[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