[simpits-tech] Arduino and serial comms follow-up

geneb geneb at deltasoft.com
Fri Sep 21 07:19:16 PDT 2012


On Thu, 20 Sep 2012, dabigboy at cox.net wrote:

>
> ---- geneb <geneb at deltasoft.com> wrote:
>>
>> Matt, it looks pretty simple and straightforward.  Good job!
>>
>> I'd rack the baud rate up to 250000 though. According to the rate chart I
>> have for the ATMega328, that's the highest rate you can use with a 0%
>> clocking error.
>
> Well thanks! I was expecting something like "what the heck is that?" :) 
> As you may have noticed, I did get the ordinal-to-integer codes from 
> somewhere online, with little modification.
>
I've seen much, much worse in the wild. :)

I've attached the code for my 16 channel output driver board - the 
pre-Centipede version.  This was written with the intention of having a 
bunch of ATMega328's sharing the same serial input line.  That's why 
you'll see references to the board id.  With the Centipede I can get 128 
outputs (or inputs, or a mix) for each Arduino.  Each Centipede supports 
64 channels.

g.


-- 
Proud owner of F-15C 80-0007
http://www.f15sim.com - The only one of its kind.
http://www.diy-cockpits.org/coll - Go Collimated or Go Home.
Some people collect things for a hobby.  Geeks collect hobbies.

ScarletDME - The red hot Data Management Environment
A Multi-Value database for the masses, not the classes.
http://www.scarletdme.org - Get it _today_!
-------------- next part --------------
/* Gazoutta 16 
 * 16 Channel digital output board
 * Copyright 2010 by Gene Buckle 
 * All Rights Reserved
 * This software is provided as-is and is licensed under the
 * Creative Commons Attribution Share Alike license.  
 * Please see http://creativecommons.org/about/licenses/ for details.
 *
 * I can be reached at geneb at deltasoft.com
 *
 * History:
 * -----------------
 * 18Mar10 gwb Started.
 * 21Jul10 gwb First version!
 * 30Jul10 gwb First publicly releasable version.
 *
 */

#include <EEPROM.h>

#define CHAN_1    2      /* Corresponds to pin #2 on the Arduino */
#define CHAN_2    3
#define CHAN_3    4
#define CHAN_4    5
#define CHAN_5    6
#define CHAN_6    7
#define CHAN_7    8
#define CHAN_8    9
#define CHAN_9    10
#define CHAN_10   11
#define CHAN_11   12
#define CHAN_12   13
#define CHAN_13   14
#define CHAN_14   15
#define CHAN_15   16
#define CHAN_16   17

byte channels[] = {
  2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};


#define ID_LEN 4           // length of the board ID.
#define BUF_SIZE  32


int buffer[128];
int bufIndex = 0;
int id_offset = ID_LEN;

char boardID[ID_LEN+1] = "GAZ1";

boolean havePrefix = false;
void setup() {
  int x = 0;
  byte sigValue[1];
  
  //Serial.begin(115200);  // Use this baud rate if your host can't use the faster rate below.
  Serial.begin(250000);  // The 250k baud rate gives us a 0% error rate with a 16Mhz clock.
  for(x=CHAN_1;x < CHAN_16; x++) {
    pinMode(x, OUTPUT);
    digitalWrite(x, LOW);  // Initialize all the channels to the "off" state
                           // Note that if you're using inverted outputs, you should change this
                           // for those channels that are going to be used inverted to avoid turning
                           // devices on when the board initializes.
  }
  for(x = 0;x < BUF_SIZE; x++) {
    buffer[x] = 0;
  }
  // Check to see if this is the first time we've been run 
  // Addresses 1 and 2 of the EEPROM should be "GB" if we have.
  sigValue[0] = EEPROM.read(0);
  sigValue[1] = EEPROM.read(1);
  if ((sigValue[0] != 0x47) && (sigValue[1] != 0x42)) {
    // no signature found so we should write the default board id to the EEPROM.
    for (x = 0; x < ID_LEN; x++)
      EEPROM.write(x + 2, boardID[x]);

    // Update the signature..
    EEPROM.write(0,0x47);
    EEPROM.write(1,0x42);
  } else {
    for (x = 0; x < ID_LEN; x++)
      boardID[x] = EEPROM.read(x + 2); // we pull it from the EEPROM...
  }    
}

void loop() {
  int inByte = 0;
  int test = 0;
  if (Serial.available() > 0) {
    /* append the byte to the buffer */
    inByte = Serial.read();
    buffer[bufIndex] = inByte;
    bufIndex++;
    if ((inByte == '*') || (inByte == '\n')) {
      processBuffer();
      clearBuffer();
      bufIndex = 0;
    }
  }
}

void clearBuffer() {
  int x = 0;

  for(x = 0;x < BUF_SIZE; x++) {
    buffer[x] = 0;
  }

}  

void processBuffer() {
  boolean validID = true;
  int cnt = 0;
  int chanbank1 = 0;
  int chanbank2 = 0;

  // first off, we need to find out if the command being sent is meant for us.
  // bytes 1..4 is the device ID code.  We must match before we continue.
  for(cnt = 0;cnt < ID_LEN;cnt++) {
    if (boardID[cnt] != buffer[cnt]) {
      validID = false;
      break;
    }
  }
  if (validID) {
    // Now that we know that the host is talking to US, then we can start
    // processing the commands they've sent.
    // Byte 5 is the function byte.  It tells us what we're going to do.
    // 0x00 - Set channels to follow bit state in channel bytes
    // 0x01 - Turn specific channels on
    // 0x02 - Turn specific channels off
    // 0x03 - Turn ALL channels on
    // 0x04 - Turn ALL channels off.
    // 0x05 - Write new board ID to EEPROM
    
    
    chanbank1 = buffer[ID_LEN + 1];
    chanbank2 = buffer[ID_LEN + 2];
    if (buffer[id_offset] == 0x00) {  // Follow bit state
      for (cnt = 0; cnt < 8; cnt++) {
        if (chanbank1 & (1 << cnt)) 
          digitalWrite(channels[cnt], HIGH);
        else
          digitalWrite(channels[cnt], LOW);
        if (chanbank2 & (1 << cnt)) 
          digitalWrite(channels[cnt+8], HIGH);
        else
          digitalWrite(channels[cnt+8], LOW);
      }
    }
    
    if (buffer[id_offset] == 0x01) { // Set active channels high, ignore unset bits
      // test the first control byte
      for (cnt = 0; cnt < 8; cnt++) {
        if (chanbank1 & (1 << cnt)) 
          digitalWrite(channels[cnt], HIGH);
        if (chanbank2 & (1 << cnt))
          digitalWrite(channels[cnt+8], HIGH);
      }
    }
    if (buffer[id_offset] == 0x02) { // Set active channels low, ignore unset bits
      // test the first control byte
      for (cnt = 0; cnt < 8; cnt++) {
        if (chanbank1 & (1 << cnt)) 
          digitalWrite(channels[cnt], LOW);
        if (chanbank2 & (1 << cnt))
          digitalWrite(channels[cnt+8], LOW);
      }
    }
    if (buffer[id_offset] == 0x03) {
      allChannelsOn();
    }
    if (buffer[id_offset] == 0x04) {
      allChannelsOff();
    }

    if (buffer[id_offset] == 0x05) { // Write new board ID to EEPROM
      char newID[ID_LEN+1] = {0,0,0,0,0};
      for (cnt = 0; cnt < ID_LEN; cnt++) {
        newID[cnt] = buffer[5+cnt];
      }
      for (cnt = 0; cnt < ID_LEN; cnt++) {
        EEPROM.write(cnt + 2, newID[cnt]);
        boardID[cnt] = newID[cnt];
      }
      Serial.print("ID changed to ");
      Serial.println(boardID);
    }
  } else {
    if (buffer[0] == 'i' || buffer[0] == 'I') {
      Serial.println(boardID);
    }
  }
}

void allChannelsOn() {
  int x;
  for(x=2;x<18;x++) 
    digitalWrite(x, HIGH);
}

void allChannelsOff() {
  int x;
  for(x=2;x<18;x++) 
    digitalWrite(x, LOW);
}


More information about the Simpits-tech mailing list