Category Archives: C++

Traffic light and pedestrian crossing implemented with an Arduino


This video shows the Traffic light and pedestrian crossing I’ve implemented with an Arduino. It’s a reproduction of the crossing near my home, timings taken from a video of it.

Pedestrian light_bb

Incidentally, I produced the diagrams for this using a product called Fritzing.  It’s a nifty piece of software that allows you to draw a breadboarded version of your circuit, lay out the circuit schematic and then automatically design the artwork for a etched circuitboard. I haven’t experienced the latter, because of an autoroute bug in version 0.8 of Fritzing.

I exported the images as SVGs from Fritzing and discovered that WordPress won’t allow them to be uploaded because of security issues; presumably the ability to include JavaScript inside a SVG for animation (etc).  So then I exported as PNG, the lossless format.  One of the two images wouldn’t upload, but was acceptable to WordPress after scaling down. I started out publishing on the web using notepad and FTP, and look where I am now.

Hardware

Circuit diagram for pedestrian lights controlled by an AVR microcontroller

I’ve been using an Arduino Mega2560 as the development environment but I’m targeting something smaller for implementation. The code compiles (on the bulky Mega instruction set) to 3.5Kb, so I’m satisfied that as things stand I’m not going to blow any memory budget.

The LED lights all share a single 220 ohm current-limiting resistor, and the call button is pulled low with a 47K ohm resistor to prevent the input pin from floating all over the shop when the button isn’t pressed.

You may notice that the video doesn’t exactly match the diagram. That’s because it’s built out of bits and bobs I had lying around. The ~200-ish Ohm resister had leads that wouldn’t insert into the breadboard. Thus, alligator clips all over the place.

Software

The light cycle is handled with a state machine; the flashing of lights is effected via state changes. The state machine is triggered by interrupts; the ISRs (Interrupt Service Routines) are lightweight, with the “heavyweight” processing for the state machine occurring in response to changes made in the ISRs. To minimise the processing load in the buttonpress ISR a test has been cached in a variable.  The timer ticks over every half second, giving the state machine a half-second resolution – which seems to match what happens in the real world.

The state machine is initialized into a safe state of having the traffic face a red light, and the pedestrians facing the flashing red man.  That means if the system restarts in the middle of a crossing cycle, no one gets killed.

Although the timer is fired via an interrupt, it won’t fire during a delay() so the delay in the main loop is very short.

Although the environment gives an opportunity to develop an OOP solution, their wasn’t any clear need for that level of abstraction, and microcontrollers tend to feel the additional cost of indirection. For example, accesses to members of the state were costly in terms of instructions and lead me to consider using multiple single dimension arrays, accessed by pointer.

#include <TimerOne.h>
//#define DEBUG
/*
Simulate a pedestrian crossing

An Australian pedestrian crossing has three traffic control lights, 
two pedestrian control lights and a light to acknowledge "call requests" 
(i.e. pressing the crossing button).
The traffic control lights cycle red -> green -> amber, solid in all.
The pedestrian control lights cycle red -> green -> flashing red.
The crossing button lights up the call request light, which stays lit
until the pedestrian control light turns green.
Once the traffic control light turns green, it stays that way for some time
before it will yield to a call request.  This is to ensure the road is not
continuously blocked servicing pedestrian crossing needs.

This code responds to two events: the passage of time and the pressing of
the call request button.  Outside of responding to these events the program
has no secondary task.  To optimize the performance of the CPU in its
secondary task, the primary tasks occur in response to interrupts.
*/
// Pin allocation:
const int CallbuttonPin = 2;        // the "I want to cross" button
const int lightCallAcknowledge = 3; // the light that says "you pressed the button"
const int lightGreenMan = 4;        // Pedestrian "walk now"
const int lightRedMan = 5;          // Pedestrian "Do not start walking"
const int lightGreen = 6;          // Traffic go
const int lightAmber = 7;          // Traffic stop if safe
const int lightRed = 8;            // Traffic stop
const int timerPin1 = 9; // lost to timing, can't be used for IO
const int timerPin2 =10; // lost to timing, can't be used for IO
const int onBoardLED = 13;      // on board, can be over-ridden or even cut

typedef struct {
public:
  byte timer_length; // How long to stay in this state (1 tick = 500ms)
  byte action;  // state to set the lights to
  char next_state_on_timer;
  char next_state_on_call_button;
} StateTransition;

const int bitClearCallButton = B00000100; // Clear call acknowledge
const int bitGreenMan =        B10001000; // "walk now"
const int bitRedMan =          B00010000; // "Do not start walking"
const int bitGreen =           B00110000; // Traffic go
const int bitAmber =           B01000000; // Traffic stop if safe
const int bitRed =             B10000000; // Traffic stop
const int maskControlLights = 
            bitGreenMan | bitRedMan | bitGreen | bitAmber | bitRed;

const char NoTransition = -1;
const StateTransition state[] = {
  {8,  bitAmber|bitRedMan,  1, NoTransition},  // Amber and Red Man (4 seconds)
  {4,  bitRed|bitRedMan,    2, NoTransition},  // Red and Red Man (2 seconds)
// Red light lasts for 28 seconds total - 56 ticks
  {21,  bitRed|bitGreenMan|bitClearCallButton,  
                            3, NoTransition},  // Red and Cross
// 7.5 Seconds of flashing red man                            
  {1,  bitRed|bitRedMan,    4, NoTransition},  // Red and Flashing Red Man
  {1,  bitRed,              5, NoTransition},  // Red and Flashing Red Man
  {1,  bitRed|bitRedMan,    6, NoTransition},
  {1,  bitRed,              7, NoTransition},  // 2s
  {1,  bitRed|bitRedMan,    8, NoTransition},
  {1,  bitRed,              9, NoTransition},  // 3s
  {1,  bitRed|bitRedMan,   10, NoTransition},
  {1,  bitRed,             11, NoTransition},  // 4s
  {1,  bitRed|bitRedMan,   12, NoTransition},
  {1,  bitRed,             13, NoTransition},  // 5s
  {1,  bitRed|bitRedMan,   14, NoTransition},
  {1,  bitRed,             15, NoTransition},  // 6s
  {1,  bitRed|bitRedMan,   16, NoTransition},
  {1,  bitRed,             17, NoTransition},  // 7s
  {1,  bitRed|bitRedMan,   18, NoTransition},
  {1,  bitRed,             19, NoTransition},  // 8s
  {9,  bitRed|bitRedMan,   20, NoTransition},  // Red and Red Man
// Allow at least 25.5 seconds of traffic through
  {51, bitGreen|bitRedMan, 21, NoTransition},  // Green and Red Man
  {99, bitGreen|bitRedMan, NoTransition,  0},  // Green and Red Man  // Loop if button pressed
  {1,  bitRed|bitRedMan,    3, 3},  // initial state
};
volatile char current_state = 16;
volatile char next_state = 3;  // Start in a safe state:
volatile byte ticks_remaining = 1;
boolean call_button_disabled = true;

void transition_to_next_state()
{
#ifdef DEBUG
  Serial.print((int)current_state);
  Serial.print(" transitions_to ");
  Serial.println((int)next_state);
#endif
  if (next_state == NoTransition) return;
  current_state = next_state;  
  next_state = NoTransition;

  // turn on the lights as per this state
  byte mask = B00001000;
  byte light=lightGreenMan;
  while (light < = lightRed)
  {
#ifdef DEBUG
    Serial.print("light pin ");
    Serial.print(light);
#endif    
    if (state[current_state].action & mask)
    {
      digitalWrite(light, HIGH);  // turn on the signal
#ifdef DEBUG
      Serial.println(" HIGH");
#endif    
    }
    else
    {
      digitalWrite(light, LOW);  // turn off the signal
#ifdef DEBUG
      Serial.println(" LOW");
#endif    
    }
    light++;
    mask = mask << 1;
  }

  // Turn off the call acknowledge light if that's something we do
  call_button_disabled = state[current_state].action & bitClearCallButton;
  if (call_button_disabled)
  {
#ifdef DEBUG
    Serial.println("CallButtonDisabled()");
#endif    
    digitalWrite(lightCallAcknowledge, LOW);  // turn off the signal
  }

  // start the timer until the next state
  ticks_remaining = state[current_state].timer_length;
}

void timer_tick()
{
  if (--ticks_remaining == 0)
  {
    next_state = state[current_state].next_state_on_timer;
  }
  // See if we can service any existing call
  else if (digitalRead(lightCallAcknowledge))
  {
    next_state = state[current_state].next_state_on_call_button;
  }
}

void call_button_pressed()
{
  // Don't acknowledge if it would be cleared
  if (!call_button_disabled)
  {
    digitalWrite(lightCallAcknowledge, HIGH);  // Acknowledge the request
  }
}

// the setup routine runs once when you press reset:
void setup() {
#ifdef DEBUG
  Serial.begin(9600);
  Serial.println("Traffic light simulation");
#endif    
  pinMode(CallbuttonPin, INPUT);     
  pinMode(lightCallAcknowledge, OUTPUT);     
  pinMode(lightGreenMan, OUTPUT);     
  pinMode(lightRedMan, OUTPUT);     
  pinMode(lightGreen, OUTPUT);     
  pinMode(lightAmber, OUTPUT);     
  pinMode(lightRed, OUTPUT);     
  Timer1.initialize(500000);         // initialize timer1, and set a 1/2 second period
  Timer1.attachInterrupt(timer_tick);  // attaches callback() as a timer overflow interrupt
  attachInterrupt(0, call_button_pressed, CHANGE);
}

// the loop routine runs over and over again forever:
void loop() {
  if (next_state!=NoTransition)
  {
    transition_to_next_state();
  }
  delay(50);
}

 

Linker problems galore

LINK : fatal error LNK1104: cannot open file ‘mfcs42d.lib’

Go to Tools | Options… | Projects and Solutions | VC++ Directories, select Show Directories for: Library files and insert the path to your existing mfcs42d.lib.

Now you get
LNK2019: unresolved external symbol “public: __thiscall AFX_MODULE_STATE::AFX_MODULE_STATE(int,long (__stdcall*)(struct HWND__ *,unsigned int,unsigned int,long),unsigned long)” (??0AFX_MODULE_STATE@@QAE@HP6GJPAUHWND__@@IIJ@ZK@Z) referenced in function “public: __thiscall _AFX_DLL_MODULE_STATE::_AFX_DLL_MODULE_STATE(void)” (??0_AFX_DLL_MODULE_STATE@@QAE@XZ)

Remove mfcs42d.lib and you get
mfcs90d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in MSVCRTD.lib(dllmain.obj)

Know what you did wrong?

I’ve got the answer.

Don’t link to mfcs42d (and, for that matter, the non-debug version mfcs42.lib) in your 2008 project. If that name’s hard-coded into your project – and it is, isn’t it? – then change the name to mfcs90d and you’ll be fine.

Visual C++ Compiler Error C2316: Make with the class definition

Visual C++ Compiler Error C2316

You know, I was getting this error when porting some exception catching code from Visual C++ 6 to version 9. The error message helpfully states that 'exception' cannot be caught as the destructor and/or copy constructor are inaccessible

Weird thing was, it was wrong. Both the copy constructor and destructor for the class and all it’s ancestors were in public scope.

Eventually there was the figuring out: the exception was being anonymously caught, like so:
try {
whatever();
}
catch (MyExceptionClass&) {}

And to keep MSVC6 happy, earlier in the codebase a preceding programmer had coded:
class MyExceptionClass;
Which did indeed keep MSVC6 happy. MSVC9 asked what I’d done with the copy constructor. Well, dear friend: it’s in the header file that wasn’t included. Delete the forward declaration, add one #include and we are cooking with gas.

If we actually give the compiler the definition of the class being caught it can generate code rather than misleading error messages. Why the error message wasn’t: “No definition for this class” is beyond me.

Incorrect <rpcproxy.h> version. Use the header that matches with the MIDL compiler

To solve this problem, check the ordering of directories searched for include files (in VC6, it’s Tools | Options | Directories | Show directories for: Include files). SDKs and Visual Studio have different versions.

Scott Meyers’ five top fives – EVER

I’ve been waiting for the full set to be published, before dumping ‘em here:

What to do when attach to process doesn’t work

When using Visual Studio, you can attach to a running process that’s chocked full of debug info (or not, but there’s not much point if it’s not) by selecting Build | Start Debug | Attach To Process…

This can handle cases where a problem doesn’t happen under the IDE, but does when running a debug executable. As happened to me recently. So, with the app running and the problem reproduced, I wanted to debug. But, when the dialog pops up it might be distressingly empty – as it was for me. What to do?

From task manager, right (context) click on the process and select Debug. That will launch your debugger and away you go.

When things become super freaky do a RebuildAll

I just solved an irritating problem. I had a program sending heartbeats to another, but with the wrong frequency.

Putting in a breakpoint at the point where that frequency is set showed the value at 2000ms, rather than the 5000ms we had in the registry. So I checked the registry reading code was pulling the right value into the appropriate variable, and indeed it was. No other lines of code referred to the member that held this value. There was no way of setting the value other than reading from the registry in this one location. Even putting a breakpoint on change to that variable failed to show what was going on – it never broke on change – although the program did run like a dog with that breakpoint on. Much pulling of hair ensued.

Then I took the opportunity to inspect this. And I noticed, browsing through the various values, that there was a value of 2000 in the preceeding variable.

I then proceeded to use the old adage, “When things become super freaky do a RebuildAll”, and the problem was solved. Seems like there was some sort of link problem. I just wish I’d tried it earlier.

C++: Pointers to member functions

Now, C++ programmers can all program C, to varying degrees of competency. And some know that in C you can store an entire function in a pointer, like so:

int DoTheThingThisWay(double count)
{
...
}

int DoTheThingThatWay(double count)
{
...
}

int (*DoTheThing)( double );  // define the variable
DoTheThing = &DoTheThingThatWay; // set the variable
result = DoTheThing( 2.0 );  // call the function, whatever it is now

Giving you a nifty kinda polymorphism. People who have programmed in C, and needed something like this (say for a state machine) have gone “neat!” and remembered it for later.

So, here we are, later. I’m working in C++ and going to do a state machine. Objects and all. I recall that you can do that polymorphic thing with function pointers, and quickly reconstruct the syntax. Now, with objects I want to point at a function on an object rather than a dumb, lying around knowing nothing about objects function. Easy, let’s just whip that up, I’ve proven how pretty the syntax for calling an arbitary function is, now just to call an arbitary member function.

Half an hour of wrestling with the compiler later, an observation is made along the lines of “everyone does this, just look it up on the web”. Top hit on a Google search for C++ “member function” pointer is http://www.goingware.com/tips/member-pointers.html – which is the right page, and you end up with the call:

result = (objectInstance.*DoTheThing)( 2.0 );

which ain’t so pretty. But you need to do that to provide the hidden this pointer, because you’re working with member functions here, not boring old functions. Add some parameters, store the pointers in an array and before you know it you’ve got

result = (objectInstance.*DoTheThing[FunctionIndex])( 2.0, InitalStringSize, HuffalumpFactor );

which is a long way from DoTheThing(2.0), and I’m not sure what you just got for all that effort. Certainly not readability. Try a pointer to a polymorphic type instead (maybe even a functiod?), and flip the pointer to different objects as you go. Much nicer:

class CThingDoer
{
public:
	virtual int operator(double count);
...
};

class CDoTheThingThisWay : public CThingDoer
{
public:
	virtual int operator(double count);
...
} DoTheThingThisWay

class CDoTheThingThatWay : public CThingDoer
{
public:
	virtual int operator(double count);
...
} DoTheThingThatWay

CThingDoer* DoTheThing;  // define the variable
DoTheThing = &DoTheThingThatWay; // set the variable
result = DoTheThing( 2.0 );  // call the function, whatever it is now

Microsoft 2005 dev tool betas

To those who watch Microsoft’s dev tools, there are betas of the 2005 versions now available. MSDN subscribers can download full products straight away; others can order CDs, or stick to the Express products, which for trying out new languages, are quite nicely featured.

It’s a cunning strategy for Microsoft, helping to counter the proliferation of free programming languages such as Java and PHP by providing free development environments for ASP, VB, C#, C++ and their own (some would say mutated) J# implementation of Java.

MSDE, which has been around for years now, providing a royalty-free cut-down SQL Server, has been renamed SQL Server Express to show its heritage. (Well, its SQL Server heritage… most people know it grew out of Sybase, but that’s ancient history). Keeping it free thus helps fight off the MySql threat and allowing people for whom Access isn’t cutting it to be encouraged up to SQL Server).

Looking back 20 years to when I was growing up, trying out BASIC on my Commodore 64 or BBC Micro, I ponder how the next generation of programmers are getting hooked into this game. I suspect a mix of freebie entry-level products like this (and their counterparts from the world of open-source) is one way they can get involved. Which probably explains MS’s “Coding 4 Fun” web site.