Programming difference between Arduino Freeduino MaxSerial and Arduino Mega1280

Hi Everyone,

I’ve been making this project by Jon Bennett: Wifi Robot - JBProjects.net

It is a spy car that uses a router that is connected to an arduino and an rc car. The information that my router send to the arduino mega1280 is accurate - I used a sketch to read the information coming in (rx) and it is what it should be. The sketch for the spy robot is supposed to convert the information coming in into digitalHigh for various pins. However, it does not work. A signal from the router does not activate any pins.

The only reason I can think of why it does not work is because he was using an arduino freeduino maxserial and I am using a Arduino Mega1280. Would one sketch work for a freeduino, but not for a mega1280?

I would really appreciate if someone could give me some advice on what the problem with this sketch is or adjust the sketch so it will work on my mega1280.

Thanks!!!

Here is the sketch:

/*******************************************************************
; Function: Wifi Robot Arduino Firmware
; Filename: car_arduino.c
; Author: Jon Bennett
; Website: www.jbprojects.net/projects/wifirobot
;*******************************************************************/

#define DEBUG 0
#define WAIT_FOR_START 1

unsigned char incomingByte = 0;
unsigned long loop_count = 0;
unsigned char horn = 32;
unsigned char redLED = 64;
unsigned char greenLED = 128;

unsigned char forward = 1;
unsigned char backward = 2;
unsigned char left = 4;
unsigned char right = 8;

unsigned char PORTB_val;
unsigned char PORTD_val;

unsigned char in_char = 0;

void setup()
{
//PORTD = digital IO 0-7
//horn, redLED, greenLED

pinMode(5, OUTPUT); // sets the digital pin as output
pinMode(6, OUTPUT); // sets the digital pin as output
pinMode(7, OUTPUT); // sets the digital pin as output

//PORTB = digital IO 8 - 13
//right, left, backwards, forward

pinMode(8, OUTPUT); // sets the digital pin as output
pinMode(9, OUTPUT); // sets the digital pin as output
pinMode(10, OUTPUT); // sets the digital pin as output
pinMode(11, OUTPUT); // sets the digital pin as output

Serial.begin(9600); // set up Serial library at 9600 bps

PORTD = redLED; // turn on the red LED

#if DEBUG
flash_led(3,500);
#endif

wait_for_start(); //Waits for startup message from router serial port
//continues after receiving it.
}

void flash_led(unsigned int count, unsigned int rate)
{
// debug routine that flashes an LED

int n_count = 0;

while (n_count < count)
{
n_count++;
digitalWrite(13, HIGH); // sets the LED on
delay(rate); // waits for a bit
digitalWrite(13, LOW); // sets the LED off
delay(rate); // waits for a bit
}
}

char get_char()
{
//Function that waits for a character from the serial port
//If none are received, it returns 0.
//The timeout is so that if the router stops sending data to the microcontroller,
//the micrcontroller will stop driving the car, rather than just going forever with
//the last command. Timeout is around 250mS.

while (loop_count < 30000)
{
loop_count++;

if (Serial.available() > 0)
{
incomingByte = Serial.read();
loop_count = 0;
return incomingByte;
}
}

loop_count = 0;

#if DEBUG
Serial.print(‘X’, BYTE);
#endif

return 0;
}

unsigned char wait_for_start()
{
//Waits for startup message from router serial port
#if WAIT_FOR_START

#if DEBUG
Serial.println(“Waiting…”);
#endif

while(1)
{
if (get_char() == ‘j’ && get_char() == ‘b’ && get_char() == ‘p’ && get_char() == ‘r’ && get_char() == ‘o’)
{

#if DEBUG
Serial.print(“Passcode Accepted”);
#endif

return 0;
}
}
#endif
}

void loop()
{
//Function that processes input from serial port and drives the car based
//on that input.

in_char = get_char();

//Split byte received in to upper and lower halves.
PORTB_val = in_char & 0x0F;
PORTD_val = in_char & 0xF0;

//Make sure the greenLED is turned on now.
if ((PORTD_val & greenLED) == 0)
{
PORTD_val = PORTD_val + greenLED;
}

//The following IF statements are sanity checks to make sure that FORWARD and BACKWARD cannot be on at the same time
//and that LEFT and RIGHT can’t be on at the same time.
if ((PORTB_val & (left + right)) == (left + right))
{
PORTB_val = PORTB_val - right;
}

if ((PORTB_val & (forward + backward)) == (forward + backward))
{
PORTB_val = PORTB_val - backward;
}

//Write the processed values to the ports.
PORTD = PORTD_val;
PORTB = PORTB_val;

#if DEBUG
Serial.print(PORTD, HEX);
Serial.print(PORTB, HEX);
#endif

}

Thanks so much!

Yes. The problem is that the sketch uses direct port manipulation, and the port-to-pin mappings for the mega and regular arduino/clones (like the freeduino) are different. For example, this sketch accesses the PORTD register in a few places, which on the Atmega328, maps to arduino pins 1-4. On the mega, however, it maps to some pins in the 20s. You can either modify the program or modify what is plugged into where. It really is whatever is easier for you. This spreadsheet shows which arduino mega and standard pins are wired to which Atmega pins: http://spreadsheets.google.com/pub?key=rtHw_R6eVL140KS9_G8GPkA&gid=0

Good luck! Looks like a really cool project

Hi bilbo,

Thanks heaps for that. However, I have tried plugging in the output to all the different pins and it still doesn't work. I'll have a look at the code and see if I can change it and see what is going on (It will probably take me a few days as I am a beginner with programming).

If you have any further thoughts, or know which parts of the sketch to change, please let me know.

Thanks

Here is what you need to do: Replace every PORTD in the sketch with PORTA and plug what is supposed to be plugged in to pins 5,6 and 7 into Mega digital pins 27, 28, and 29 respectively. Leave the PORTB's the way they are, but plug what is supposed to be plugged into digital pins 8,9,10 and 11 into Mega digital pins 53, 52, 51, and 50 in that order.

That should make everything work the way it should

Good luck!

Hi Bilbo,

Thanks for that, but unfortunately it did not work. I am aware that playing with PORTD etc is very tricky and hard to pick up where the problems are. However, I found an example that I’m pretty sure will do me fine. All I need to do is change this code so that instead of the input being a,b,c,d I want it to be 1,2,4,8,32. If I change the ‘a’ to 1, it does not work. Any idea how I can change this to make it work? Thanks heaps.

void setup() {
// initialize serial communication:
Serial.begin(9600);
// initialize the LED pins:
for (int thisPin = 2; thisPin < 7; thisPin++) {
pinMode(thisPin, OUTPUT);
}
}

void loop() {
// read the sensor:
if (Serial.available() > 0) {
int inByte = Serial.read();
// do something different depending on the character received.
// The switch statement expects single number values for each case;
// in this exmaple, though, you’re using single quotes to tell
// the controller to get the ASCII value for the character. For
// example ‘a’ = 97, ‘b’ = 98, and so forth:

switch (inByte) {
case ‘a’:
digitalWrite(2, HIGH);
break;
case ‘b’:
digitalWrite(3, HIGH);
break;
case ‘c’:
digitalWrite(4, HIGH);
break;
case ‘d’:
digitalWrite(5, HIGH);
break;
case ‘e’:
digitalWrite(6, HIGH);
break;
default:
// turn all the LEDs off:
for (int thisPin = 2; thisPin < 7; thisPin++) {
digitalWrite(thisPin, LOW);
}
}
}
}