//board:duemilanove // Arduino serial pulser. // Pulses a PWM pin supplied over Serial for the duration that was sent. #include //#define DEBUG #define CHANNEL0 9 #define CHANNEL1 6 #define CHANNEL2 5 #define CHANNEL3 3 #define NO_CHANNELS 4 #define DECAY_TIME 8 // number of cycles to run before doing a decay loop #define UINT16_MAX (65535U) #define NODE 1 // used to define which node we're looking at. TODO move this to EEPROM and burn in byte channels[] = {CHANNEL0, CHANNEL1, CHANNEL2, CHANNEL3}; long channel_time_values[NO_CHANNELS]; // used to hold the time to stay lit uint8_t channel_light_val[NO_CHANNELS]; // used to hold the light value enum LIGHT_DIRECTION { FADE_DOWN = -1, HOLD = 0, FADE_UP = 1 } channel_light_dir[NO_CHANNELS]; // used to hold the direction uint8_t current_channel = 0; long current_value = 0; enum STATE { WAITING_DATA, WAITING_VALUE, DISCLOSE_NODE } state = WAITING_DATA; void setup() { // we're going to be talking to the serial line so best we open it. Serial.begin(9600); Serial.print("Lightnode:"); Serial.println(NODE); Serial.flush(); #ifdef DEBUG Serial.println("Serial pulser."); Serial.println("Send a channel number then a duration in msec"); Serial.println("Send CR to complete"); #endif // set up the PWM pins for use. for (uint8_t i=0; i< NO_CHANNELS; i++) { pinMode(channels[i], OUTPUT); digitalWrite(channels[i], LOW); channel_light_val[i] = 0; } } void loop() { // check to see if anything is coming in on the serial line and if there // is then process it. if(Serial.available()){ char ch = Serial.read(); if (ch >= '0' && ch<= '9') { if (state == WAITING_DATA) { current_channel = (current_channel * 10) + (ch - '0'); #ifdef DEBUG Serial.print("Got a char: "); Serial.println(ch); #endif } else if (state == WAITING_VALUE) { current_value = (current_value * 10) + (ch - '0'); } } else if (ch == 32) { // space so we split the channel stuff. if (state == WAITING_DATA) { state = WAITING_VALUE; #ifdef DEBUG Serial.println("Got a space"); #endif } } else if (ch == 'n') { //channel has asked to disclose our name state = DISCLOSE_NODE; } else if (ch == 10) { // newline so end of val. if (state == DISCLOSE_NODE) { Serial.print("Lightnode:"); Serial.println(NODE); Serial.flush(); state = WAITING_DATA; } else if (state == WAITING_VALUE) { state = WAITING_DATA; #ifdef DEBUG Serial.print("Got a new line "); Serial.print("Channel: "); Serial.print(current_channel); Serial.print("msecs: "); Serial.println(current_value); #endif pulse(current_channel, current_value); current_value = 0; current_channel = 0; } } } // decay the values on the channels appropriately. for (int i = 0; i < NO_CHANNELS; i++) { channel_time_values[i]--; if (channel_time_values[i] < 0) { channel_time_values[i] = 0; if (channel_light_val[i] > 0 && channel_light_dir[i] == HOLD) { channel_light_dir[i] = FADE_DOWN; #ifdef DEBUG Serial.print("Fading down channel: "); Serial.println(i); #endif } } if (channel_light_dir[i] == FADE_UP) { if (channel_light_val[i] < 255) { channel_light_val[i] += channel_light_dir[i]; } else { channel_light_dir[i] = HOLD; #ifdef DEBUG Serial.print("HOLDING HIGH channel: "); Serial.println(i); #endif } } else if (channel_light_dir[i] == FADE_DOWN) { if (channel_light_val[i] > 0) { channel_light_val[i] += channel_light_dir[i]; } else { channel_light_dir[i] = HOLD; #ifdef DEBUG Serial.print("HOLDING LOW channel: "); Serial.println(i); #endif } } // now we actually know what the value should be write it to the pin. analogWrite(channels[i], channel_light_val[i]); } delay(1); } void pulse(uint8_t channel, uint16_t msecs ) { // this function adds the value of a pulse onto the specified channel if ((channel_time_values[channel]+ msecs) > UINT16_MAX ) { channel_time_values[channel] = UINT16_MAX; } else { channel_time_values[channel] += msecs; #ifdef DEBUG Serial.print("Setting time value to: "); Serial.println(channel_time_values[channel]); #endif } channel_light_dir[channel] = FADE_UP; #ifdef DEBUG Serial.print("Fading up channel: "); Serial.println(channel); #endif }