Aug 082015
 

I wanted to remind myself about C coding and how pointers work – never quite got my head round them at sons.

One of these was experimenting with C code so flawed it caused buffer overflows that crashed the kernel on multi user systems. That means the whole computer must be rebooted and other users would have their projects/data disrupted (it was in 1991, so a 32 bit machine was still known as a minicomputer and often used proprietary flavours of Unix and multiple users logged on using VT100 type terminals). I was already becoming disaffected with the place the profs thought I’d done it deliberately!

Todays Raspberry PI Model 2, placed in a suitable box (use a dark one as strong light can crash it due to a flaw in the chip design) is about the size of two packs of cigarettes; costs way less than they now do in the UK and is less unhealthy.

Aside: I can understand why younger people still smoke as I certainly did back then; but tobacco will knacker your insides and you become very ill as you get past your middle age. it has finished off a lot of my older friends on the electronics/radio scene. So at least try to stop with smoking when you get past age 30 if not before..

Back to the RPi – this amazing device is as powerful as the multi user computer I was using in 1991! The biggest advantage is if I screw up and hose the kernel it is only myself who gets affected by it. and I have done at least once, although most likely via accidental hard shutdowns i.e accidentally disconnecting the DC input whilst it is writing to the SD-card.

It is more tolerant of flawed code (I have made a silly mistake below; who can spot it?)

I used the console (having set the framebuffer font larger using sudo dpkg-reconfigure-console-setup as I couldn’t get the codeblocks debugger to play nicely and I find the GUI IDE more distracting when coding (probably because I am old 😉 )

Tip: To get a console from X-windows on RPI press CTRL-ALT-F2, this opens a separate virtual terminal. (you can use CTRL-ALT-Fn) up to F6CTRL-ALT-F7 returns you to the X-window and CTRL-ALT-F1 has some odd error because it is in use as part of the X-windows system.

oeps

This version is better.

WP_20150807_18_59_49_Rich

It works.

WP_20150807_19_14_07_Rich

OK the code doesn’t do much but it reminds me that in C strings are an array of char, so each string has a char * to point to it. The contents of the char* are, as you would expect, a memory address where the string starts!

I then wanted to see what was going on at lower level, so used gdb. You must compile the code with gcc -g for the debugger to work.

WP_20150808_01_37_45_Rich

back in the day (1986-1990!) I even knew a bit about Assembler, but left high school just as Acorn ARM computers were available. So I thought I’d see if I could still remember any of it today. If you compile with gcc -S you get assembler code.

WP_20150808_01_40_53_Rich

this is what the source looks like, I can see the char* array, and its contents 🙂

WP_20150808_01_43_02_Rich

This bit I do not quite understand as well yet but I can grasp the fact it is part of the main loop..

WP_20150808_01_44_09_Rich

Of course I need to learn much more about how ARM works (especially as you can only work with registers rather than put memory addresses directly in opcodes) and I am clearly no smarter than I was in my teens but at least my brain hasn’t deteriorated too much over the years 🙂

 

PS: letting random geese loose in Groningen Netherlands (the message is partly in the Gronings dialect) is not just silly but (quite rightly) illegal under their animal welfare rules.

There would no one to look after it and there are plenty of stray ones already.

However if they were going to be otherwise eaten or put down and I’d arranged with the good folk at Akka’s Ganzenparadijs that the birdies had somewhere suitable to stay it would be a good deed. Emden geese aren’t that expensive (Emden is only just the other side in Germany anyway) and are cheaper alive than dead (a friend of mine farms them).

Although the Ganzenparadijs are a Buddhist animal sanctuary and I am baptised as a Catholic (not a very good one though); sparing the lives of these creatures to atone for someone else’s sin is the sort of thing many religions encourage.

I don’t expect this would get me to Heaven on a chariot towed by geese, but it would be sufficiently silly that all the various Gods would have a good laugh about it and I might even get one of those electric trolleys used at airports and large stations to haul the various heavy items through Purgatory required for the maintenance work I am tasked with.

Apr 112014
 

this should be the code
/* Control a sony receiver via Arduino and IR
/ auto mute when door is open
/ using reed swich on door
/ 2011/2012/2013/2014
/ Alex@The Rats Nest, Ipswich, UK
/ IR code taken from http://www.arcfn.com/2009/08/multi-protocol-infrared-remote-library.html
/ and remote codes from here http://lirc.sourceforge.net/remotes/sony/RM-AAU014
/
/
/ also 4 x buttons, for vol up/down, toggle green/red led (as they can get out of sync)
/ and force mute
/ NB: This receiver uses 15 bit protocol
/ and only needs 50ms delay after each command sent twice
/ per button press
*/

// 2013-11-05 updated
// new debounce library added
// now used for door contact

// LEDS index

// 00 -(pin 13) -red
// 01 -(pin 11) - green
// 02 -(pin 10) watchdog LED (amber)
// 03 -(pin 7) trigger LED (blue)
// 04 -(pin 5) telephone LED

// 2013-11-23 - added control for relays
// 2013-12-14 - removed serial port writes
// to see if the startup is cleaner
// 2014-01-13 - corrected comments on pin layout
// reset problem was caused by hardware issue!
// 2014-02-15 - added extra output for telephone LED
// 2014-03-31 - recoded due to change in bounce library

const int buttonPins[4] = {2,4,8,9};
const int ledPins[5] = {13,11,10,7,5};
const int reedPin= 12 ; // reed switch
const int relay1Pin = 6 ;

// this ia LDR brightness if telephone strobe is on

const int strobeVal = 700 ;

const int btnDelay = 20 ; // button deley
const int reedDelay= 25 ; //

// define the constants for the remote code
// and timing delays

#define MUTE 0x140C
#define VOLUME_UP 0x240C
#define VOLUME_DOWN 0x640C

#define IR_delay1 5
#define IR_delay2 5
#define REPEATS 2
#define REED_delay 50

#define LONGBARK 500
#define YAP 50

#include

// beware this lib name is changed

#include

// global declarations & vars

IRsend irsend;

Bounce btn01 = Bounce();
Bounce btn02 = Bounce();
Bounce btn03 = Bounce();
Bounce btn04 = Bounce();
Bounce reed = Bounce();

int incomingbyte = 0;
int ledState[5] = { HIGH, LOW, HIGH, HIGH, LOW};
int btnChange[4] = { LOW, LOW, LOW, LOW };
int reedChange = LOW ;
int btnState[4] = { HIGH, HIGH, HIGH, HIGH}; // as these are pulled up (active low)
int reedState=HIGH ;
int reedTime= 0 ;
int iptChange = HIGH ;
int trigLedLatch = LOW ;
int muteState = LOW ;
int relay2State = LOW ;
int ldrValue = LOW ;
unsigned long previousMillis = 0;
unsigned long lastMuteTime = 0 ;
unsigned long trigLedTime = 0 ;
long barkInterval = LONGBARK ; // bark the watchdog LED every 500 ms
long trigInterval = 125 ; // flash command received LED

void setup()
{

pinMode(buttonPins[0], INPUT);
pinMode(buttonPins[1], INPUT);
pinMode(buttonPins[2], INPUT);
pinMode(buttonPins[3], INPUT);
pinMode(reedPin, INPUT);

btn01.attach(buttonPins[0]);
btn02.attach(buttonPins[1]);
btn03.attach(buttonPins[2]);
btn04.attach(buttonPins[3]);

btn01.interval(btnDelay);
btn02.interval(btnDelay);
btn03.interval(btnDelay);
btn04.interval(btnDelay);

reed.attach(reedPin);

pinMode(ledPins[0], OUTPUT);
pinMode(ledPins[1], OUTPUT);
pinMode(ledPins[2], OUTPUT);
pinMode(ledPins[3], OUTPUT);
pinMode(ledPins[4], OUTPUT);
pinMode(relay1Pin, OUTPUT);

getButtons();

// initialise leds

ledEmit(5);

}

void loop()
{

iptChange = LOW ;
getButtons();

// bark the watchdog LED

unsigned long currentMillis = millis();

if (currentMillis - previousMillis > barkInterval) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// if the LED is off turn it on and vice-versa:
ledState[3] = !ledState[3] ;
}

// get LDRvalue

ldrValue = analogRead (A0) ;

// green button

if ( btnChange[0] && btnState[0] ) {
// ledState[2] = !ledState[2] ;
ledState[0] = HIGH ;

ledState[1] = LOW ;
iptChange = HIGH ;
// Serial.println("btn 00 state change - green light mute off");
// Serial.println("Relay OFF");
barkInterval = LONGBARK ; // long bark
muteState = LOW ;

}

// red button

if ( btnChange[1] && btnState[1] ) {
// ledState[2] = !ledState[2] ;
ledState[0] = LOW ;
ledState[1] = HIGH ;
// Serial.println("btn 01 state change - red light mute ON");
// Serial.println("relay1 ON");
iptChange = HIGH ;
// irEmit(MUTE,REPEATS);
barkInterval = YAP ; // "yap" if redlight is on-*+
muteState = HIGH ;
}

if ( btnChange[2] && btnState[2]) {
// ledState[2] = !ledState[2] ;
// Serial.println("btn3 state change");
// Serial.println("sending VOL dOWN to IR led");
iptChange = HIGH ;
irEmit(VOLUME_DOWN,REPEATS);
}

if ( btnChange[3] && btnState[3]) {
// ledState[2] = !ledState[2] ;
// Serial.println("btn4 state change");
// Serial.println("sending VOL UP to IR led");
iptChange = HIGH ;
irEmit(VOLUME_UP,REPEATS);
}

// check reed, beware as this will be high when the door is open

if ( reedChange ) {
iptChange = HIGH ;
if ( reedState) {
ledState[0] = LOW ;
ledState[1] = HIGH ;
muteState = HIGH ;
barkInterval = YAP ;

// Serial.println("door OPEN - red/MUTE");
// Serial.println("sending MUTE to IR led");
//
// irEmit(MUTE,REPEATS);
}
if ( !reedState) {
ledState[0] = HIGH ;
ledState[1] = LOW ;
muteState = LOW ;
barkInterval = LONGBARK ;
// Serial.println("door CLOSED - red/sound through");
}
}

// check for telephone strobe

if ( ldrValue > strobeVal ) {
// ledState[2] = HIGH ;
iptChange = HIGH ;
ledState[4] = HIGH ;
// Serial.print("A0 val:");
// Serial.println(ldrValue);
}

// check for input changes and send them to serialport
// latch the trigger LED on for enough time (as the actual input change is
// only a few ms

if ( iptChange) {

trigLedLatch = HIGH ;
ledState[2] = HIGH ;
trigLedTime = millis() ;
}

currentMillis = millis();

if ( currentMillis - trigLedTime > trigInterval ) {
ledState[2] = LOW ;
trigLedLatch = LOW ;
}

ledEmit(5);
digitalWrite (relay1Pin, muteState );
}

// Functions now go here at end of sketch

void irEmit(int code, int repeats)
{
for (int i = 0 ; i < (repeats) ; i++) { irsend.sendSony(code, 15); delay(IR_delay1); irsend.sendSony(code, 15); delay(IR_delay1); irsend.sendSony(code, 15); delay(IR_delay1); irsend.sendSony(code, 15); delay(IR_delay2); } } void ledEmit(int maxLeds) { for (int i = 0 ; i < (maxLeds) ; i++) { digitalWrite(ledPins[i],ledState[i]); } } void getButtons() { btnChange[0] =btn01.update(); btnChange[1] =btn02.update(); btnChange[2] =btn03.update(); btnChange[3] =btn04.update(); reedChange =reed.update(); btnState[0] = !(btn01.read()); btnState[1] = !(btn02.read()); btnState[2] = !(btn03.read()); btnState[3] = !(btn04.read()); reedState = reed.read(); // :) // reedTime = reed.duration(); }