Show Posts
|
|
Pages: 1 [2] 3
|
|
18
|
Using Arduino / Programming Questions / Re: Optimization of code for maximum speed, very specific project.
|
on: April 03, 2013, 10:27:08 pm
|
If the ISR / digital I/O code is a bottleneck (I highly doubt it is) using "port manipulation" should allow you to speed it up. You would be able to manipulate eight bits / eight I/O pins with a few machine instructions.
So I know you don't have time to go totally in depth but: With the little bit you have been able to look, do you think the code I have in the ISRs is a bad (slow) way to structure it? Sounds like you think that should be fast enough the way it is. I guess my next move is to truly hook this up and see what happens, 
|
|
|
|
|
20
|
Using Arduino / Programming Questions / Re: Optimization of code for maximum speed, very specific project.
|
on: April 03, 2013, 10:11:39 pm
|
Thanks again. I've been reading this link about the time ISRs take, found a reference to it in another post here. Seems I completely under estimated the cycles it takes just to get into and out of an ISR. Maybe it won't be a problem though. I'd like to do 255 levels of dimming but I suppose if I find I can't make that happen I can change that to something smaller like 32 or 64. Vixen lets you define the lower and upper bounds of the channel values.
|
|
|
|
|
23
|
Using Arduino / Programming Questions / Optimization of code for maximum speed, very specific project.
|
on: April 03, 2013, 09:28:52 pm
|
A while back I built a Christmas lights controller that used Vixen to create the light sequences. That project used mechanical relays and, while it worked fine, it didn't provide any real dimming capabilities. I've since moved on to version 2 of the controller using random-cross SSRs instead of the mechanical relays, the hardware is done, now and I'm working on the software. I'm trying to do full dimming of 32 channels of lights all controlled via the Vixen sequencing software. I've already done most of what I can think of to speed it up, even before bothering to do real testing on it. (I've already tested the hardware side) My normal rule would be make it work then make it work fast. Unfortunately in this case if it isn't fast it just won't work.  I've put comments in the code explaining why I thought doing certain things would speed it up. I've also put in TODO: comments every place I'm curious about the method I used or think there is a better, faster way to do something. What I would like is a little help or pointers in the right direction for squeezing every extra cycle possible out of the sketch. I've put the old (version 1) and new (version 2) code up here: https://code.google.com/p/arduino-christmas-lights-control-system-for-vixen/The new code is the XmasLightControllerForVixenSSRs.ino download. I'm using 1.0.1 version of the Arduino IDE right now. The basics of the sketch are: 1> reads 32 channels of data from Vixen via an FT232R breakout board on Serial1, Vixen sends me 32 channels (bytes) every 50ms but this is adjustable. I want to be able to handle the data at the fastest possible speed 2> uses an AC zero-cross detection circuit to trigger an interrupt so I can calculate when in the AC cycle to turn the digital pins on/off (this is the dimming, turn on later in the cycle makes the lights dimmer) 3> uses portions of the Faster Digital Write library to do port manipulations 4> has a random lights mode (you can ignore all the code related to this as it doesn't need to be fast) 5> uses Timer/Counter 1 in CTC mode to keep track of number of ticks (cycles) via an interrupt 6> The methods that have to execute as fast as possible are: loop(), readFromVixen(), ZeroCrossDetected(), ISR(TIMER1_COMPA_vect) - everything else can run slower. 7> uses an ArdunioMega 2560 Any insights you can give would be greatly appreciated. Thanks. 
|
|
|
|
|
27
|
Development / Other Hardware Development / Re: Christmas Lights Control System -Arduino Mega - 16 Channel Relay Board
|
on: December 09, 2012, 04:27:30 pm
|
I've had a few questions from some folks about the project wiring so a made a little video which I'll be uploading to youtube shortly to try to explain it. Here is a little textual explanation that covers the most important points. I don't do very well trying to explain things verbally sometimes, which you will notice if you watch the new video.  Basically the key to the project is this: There are 3 common power bus lines. Ground, Positive and Negative. The electrical sockets all have their positive terminals connected together on the common positive bus. The electrical sockets all have their ground terminals connected on the common ground bus. Each electrical socket has its negative terminal connected to one of the relays with the center screw terminal of the relay. The third screw terminal (common open of the relay) of every relay is connected to the common negative bus. When a relay closes it connects the electrical socket's negative terminal to the common negative bus thus allowing power to flow through the circuit for that individual electrical socket, causing the lights plugged into that socket to light up. There are two power sources for the project. The power source supplying power to the electrical sockets (the orange plug in the project) and the power supply that is powering the relay board and the Arduino board (that little HP power supply in the project).
|
|
|
|
|
28
|
Development / Other Hardware Development / Re: Christmas Lights Control System -Arduino Mega - 16 Channel Relay Board
|
on: December 08, 2012, 06:42:56 pm
|
Sorry for constantly updating this thread but I keep making code changes. // which pins control which channels #define CHANNEL01 2 #define CHANNEL02 3 #define CHANNEL03 4 #define CHANNEL04 5 #define CHANNEL05 6 #define CHANNEL06 7 #define CHANNEL07 8 #define CHANNEL08 9 #define CHANNEL09 10 #define CHANNEL10 11 #define CHANNEL11 12 #define CHANNEL12 13 #define CHANNEL13 44 #define CHANNEL14 45 #define CHANNEL15 46 #define CHANNEL16 47
// Which pins is the random/Vixen mode switch using #define RANDOM_MODE_PININ 52 #define RANDOM_MODE_PINOUT 53 #define RANDOM_MODE_SPEED 5000
int channels[] = {CHANNEL01,CHANNEL02,CHANNEL03,CHANNEL04,CHANNEL05,CHANNEL06,CHANNEL07,CHANNEL08,CHANNEL09, CHANNEL10,CHANNEL11,CHANNEL12,CHANNEL13,CHANNEL14,CHANNEL15,CHANNEL16};
// how many channel will vixen be sending #define CHANNEL_COUNT 16
// speed for the com port for talking with vixen #define VIXEN_COM_SPEED 57600
// speed for talking with the serial monitor in the IDE #define PC_COM_SPEED 57600
// setup your choice of dimming values or just on/off values // the relays don't seem to be able to dim the lights so it looks // like I will have to build dimmer circuits for next year. The // doesn't change, just have to remove the relay bord and replace // it with a dimmer circuit for each relay. #define MODE_DIMMING 0 #define MODE_FULL 1 #define MODE MODE_FULL
boolean startingVixen = true;
void setup() { Serial.begin(PC_COM_SPEED); Serial1.begin(VIXEN_COM_SPEED); // set the channel pins to output mode for(int channelIndex=0;channelIndex<CHANNEL_COUNT;channelIndex++){ pinMode(channels[channelIndex],OUTPUT); } // set up the switch for Vixen or Random mode pinMode(RANDOM_MODE_PININ, INPUT); digitalWrite(RANDOM_MODE_PININ,HIGH); // turn on the internal pull-up resistor pinMode(RANDOM_MODE_PINOUT, OUTPUT); turnLightsOff(); powerOnSelfTest(); }
// !!!! note the PWM values that need to be sent to the relay board are reversed from the // values comming in from Vixen. Vixen 0-255 (off-on), Relays 255-0 (off-on) void loop() { if(digitalRead(RANDOM_MODE_PININ)==LOW){ // blink at random mode startingVixen=true; doRandomLights(); }else{ // play from Vixen mode if(startingVixen==true) turnLightsOff(); readFromVixen(); } }
void powerOnSelfTest() { Serial.println("Power on self test running."); for(int channelIndex=0;channelIndex<CHANNEL_COUNT;channelIndex++){ Serial.print("Channel: "); Serial.println(channelIndex+1,DEC); analogWrite(channels[channelIndex], 0); // turn on one channel at a time delay(500); // wait .5 seconds analogWrite(channels[channelIndex], 255); } turnLightsOff(); }
void turnLightsOff() { //turn them all off for(int channelIndex=0;channelIndex<16;channelIndex++){ analogWrite(channels[channelIndex], 255); } }
void doRandomLights() { randomSeed(analogRead(0)); Serial.println("Writting random values."); for(int channelIndex=0;channelIndex<CHANNEL_COUNT;channelIndex++){ if(MODE == MODE_DIMMING) { int randNumber = random(255); randNumber = map(randNumber, 0, 255, 255, 0); analogWrite(channels[channelIndex], randNumber); Serial.print(randNumber, DEC); Serial.print(","); } else // not dimming, just on or off { int randNumber = random(0, 255); randNumber = map(randNumber, 0, 255, 255, 0); if(randNumber<=128) analogWrite(channels[channelIndex], 0); else analogWrite(channels[channelIndex], 255); Serial.print(randNumber, DEC); Serial.print(","); } } Serial.println(""); delay(random(100,RANDOM_MODE_SPEED)); }
void outputToLights(unsigned char* buffer) { for(int channelIndex=0;channelIndex<CHANNEL_COUNT;channelIndex++){ analogWrite(channels[channelIndex], buffer[channelIndex]); Serial.print(buffer[channelIndex], DEC); Serial.print(","); } Serial.println(""); }
void readFromVixen() { Serial.println("Waiting for data from Vixen."); startingVixen = false; char *footer="VIXEN_END"; unsigned char buffer[CHANNEL_COUNT]; char buffer2[CHANNEL_COUNT]; int index=0; unsigned long time = millis();
waitForVixenHeader(); while (true) { int inByte = Serial1.read(); if(inByte==-1){ if(index==0 && millis()-time>1000) // we haven't read anything in a second return; continue; } time = millis(); int lightByte = map(inByte, 0, 255, 255, 0); buffer[index] = lightByte; buffer2[index] = inByte; buffer[index+1] = 0; buffer2[index+1] = 0; index++; if(index==9 && strcmp(footer,buffer2)==0){ Serial.println(footer); return; } else if(index==CHANNEL_COUNT){ outputToLights(buffer); index=0; } } Serial.println(""); }
void waitForVixenHeader() { char *header="VIXEN_START"; char buffer[12]; int index = 0; unsigned long time = millis();
while (true) { int inByte = Serial1.read(); if(inByte==-1){ if(index==0 && millis()-time>1000) // we haven't read anything in a second return; continue; } time = millis(); buffer[index] = inByte; if(buffer[index]!=header[index]) {// not the right sequence restart index=-1; } buffer[index+1] = 0; // add null index++; if(index==11 && strcmp(header,buffer)==0){ Serial.println(header); return; } } }
|
|
|
|
|