Show Posts
|
|
Pages: [1]
|
|
2
|
Using Arduino / Programming Questions / Re: Button triggered Macro, problems with interrupt and delay
|
on: December 30, 2012, 08:51:02 am
|
int pin_B = 0; int pin_X = 1; These are the serial pins, you know. If you are doing Serial I/O (and you are), you can't expect to use them with LEDs, too. I'm not using them to drive LEDs they're integrated with a USB game controller the game controller simply needs a logic high or logic low. I know when the Arduino is "pushing" a button because I have the controller plugged into my computer with a simple test program that shows when a button is being pushed. when I run my new function instead, which loops through an array and should be doing the exact same thing as "doStuff" the pin for pin_B, and pin_X don't work... Well, I'm not surprised. I still don't understand, maybe you could explain to me why these outputs work as desired when I call "digitalWrite(pin_B, LOW);" in the "doStuff" function but not when I call "digitalWrite(pin_B, LOW);" in the "runSeq" function.
|
|
|
|
|
3
|
Using Arduino / Programming Questions / Re: Button triggered Macro, problems with interrupt and delay
|
on: December 30, 2012, 01:29:24 am
|
this is what I'm getting output to the serial monitor... which is exactly what I'd expect: seq 0: 10000000000000000000001111101000 seq 1: 1000000000000000000001111101000 seq 2: 100000000000000000001111101000 seq 3: 10000000000000000001111101000 seq 4: 1000000000000000001111101000 seq 5: 100000000000000001111101000 seq 6: 10000000000000001111101000 seq 7: 1000000000000001111101000 seq 8: 100000000000001111101000 seq 9: 10000000000001111101000 seq 10: 1000000000001111101000
|
|
|
|
|
6
|
Using Arduino / Programming Questions / Re: Button triggered Macro, problems with interrupt and delay
|
on: December 29, 2012, 03:40:08 pm
|
so I found another project that used an external file to separate the logic from the macro and it seems to work very well but now I'm having a weird bug.... So when I run my old "doStuff" function everything works great, I get a low signal on each output one at a time each for 1 second. when I run my new function instead, which loops through an array and should be doing the exact same thing as "doStuff" the pin for pin_B, and pin_X don't work... I also sometimes get pin_X flashing low along at the same time I loop to the next step (just a quick low back to high, rather than staying low for the full 1 second). I'm sure it's not the hardware since this doesn't happen on doStuff, Also I'm outputting the raw data that I'm processing to serial and everything seem to be correct.... I'm at a loss as to why this is happening /* runs through an automated sequence when the button is pushed */ #include <avr/pgmspace.h> //this is so we can use flash memory instead of SRAM
//set the binary button settings 4 bytes #define A 0x80000000 //B10000000000000000000000000000000 #define B 0x40000000 //B01000000000000000000000000000000 #define X 0x20000000 //B00100000000000000000000000000000 #define Y 0x10000000 //B00010000000000000000000000000000 #define LB 0x08000000 //B00001000000000000000000000000000 #define RB 0x04000000 //B00000100000000000000000000000000 #define Select 0x02000000 //B00000010000000000000000000000000 #define Up 0x01000000 //B00000001000000000000000000000000 #define Down 0x00800000 //B00000000100000000000000000000000 #define Left 0x00400000 //B00000000010000000000000000000000 #define Right 0x00200000 //B00000000001000000000000000000000
PROGMEM prog_uint32_t steps[] = { A+1000, B+1000, X+1000, Y+1000, LB+1000, RB+1000, Back+1000, Up+1000, Down+1000, Left+1000, Right+1000, };
long sizeOfSeq = (sizeof(steps) / sizeof(steps[0])); //determine the length of the sequence
//set names for the output pins int pin_A = 4; int pin_B = 0; int pin_X = 1; int pin_Y = 2;
int pin_RB = 12; int pin_LB = 7;
int pin_Select = 13;
int pin_Up = 11; int pin_Down = 10; int pin_Left = 9; int pin_Right = 8;
int pin_Go = 3;
byte state = HIGH; // The macro state 0=running 1=stopped byte lastButtonState = HIGH; // The go button state toggle 0=depressed unsigned long lastPushTime = 0; //the millis since the last time the button was pushed unsigned long currentMillis = 0; //get the start time unsigned long previousMillis = 0; //get the current time
// the setup routine runs once when you press reset: void setup() { // initialize the digital pins as an output. pinMode(pin_A, OUTPUT); pinMode(pin_B, OUTPUT); pinMode(pin_X, OUTPUT); pinMode(pin_Y, OUTPUT); pinMode(pin_LB, OUTPUT); pinMode(pin_RB, OUTPUT); pinMode(pin_Select, OUTPUT); pinMode(pin_Up, OUTPUT); pinMode(pin_Down, OUTPUT); pinMode(pin_Left, OUTPUT); pinMode(pin_Right, OUTPUT); //setup interrupt pinMode(pin_Go, INPUT);
//make sure everything is in the starting state that we want digitalWrite(pin_Select, LOW); //try to get it set off allClear(); }
//sets all outputs to off (high) void allClear(){ digitalWrite(pin_Up, HIGH); digitalWrite(pin_Down, HIGH); digitalWrite(pin_Left, HIGH); digitalWrite(pin_Right, HIGH); digitalWrite(pin_A, HIGH); digitalWrite(pin_B, HIGH); digitalWrite(pin_X, HIGH); digitalWrite(pin_Y, HIGH); digitalWrite(pin_LB, HIGH); digitalWrite(pin_RB, HIGH); digitalWrite(pin_Select, HIGH); }
// the loop routine runs over and over again forever: void loop() { checkPushed(); //check if the button was pushed if (state == LOW){ //doStuff(); runSeq(); allClear(); state = HIGH; } }
// the interrput routine run with the go button is pushed void checkPushed(){ byte buttonState = digitalRead(pin_Go); if (lastButtonState == HIGH && buttonState == LOW){ unsigned long pushTime = millis(); //check the time // If pushed again within 60ms, assume it's a bounce and ignore if (pushTime - lastPushTime > 60){ state = !state; //change state lastPushTime = pushTime; //set the last check time } } lastButtonState = buttonState; }
// check for the button push void myDelay(unsigned long interval){ currentMillis = millis(); //get the current time previousMillis = currentMillis; //get the start time while (currentMillis - previousMillis < interval){ //loop until the start time plus the desired delay is reached currentMillis = millis(); //get the current time checkPushed(); if (state){ return; } } }
void runSeq(){ unsigned long seq = 0; Serial.begin(9600); for(int i=0; i<sizeOfSeq; i++){ //loop through each step in the sequence seq = pgm_read_dword(&(steps[i])); //reads the steps from the included file
Serial.print("seq "); Serial.print(i, DEC); Serial.print(": "); Serial.println(seq, BIN);
if ((seq&A ) == A ) {digitalWrite(pin_A , LOW);} else {digitalWrite(pin_A , HIGH);} if ((seq&B ) == B ) {digitalWrite(pin_B , LOW);} else {digitalWrite(pin_B , HIGH);} if ((seq&X ) == X ) {digitalWrite(pin_X , LOW);} else {digitalWrite(pin_X , HIGH);} if ((seq&Y ) == Y ) {digitalWrite(pin_Y , LOW);} else {digitalWrite(pin_Y , HIGH);} if ((seq&LB ) == LB ) {digitalWrite(pin_LB , LOW);} else {digitalWrite(pin_LB , HIGH);} if ((seq&RB ) == RB ) {digitalWrite(pin_RB , LOW);} else {digitalWrite(pin_RB , HIGH);} if ((seq&Select) == Select) {digitalWrite(pin_Select , LOW);} else {digitalWrite(pin_Select , HIGH);} if ((seq&Up ) == Up ) {digitalWrite(pin_Up , LOW);} else {digitalWrite(pin_Up , HIGH);} if ((seq&Down ) == Down ) {digitalWrite(pin_Down , LOW);} else {digitalWrite(pin_Down , HIGH);} if ((seq&Left ) == Left ) {digitalWrite(pin_Left , LOW);} else {digitalWrite(pin_Left , HIGH);} if ((seq&Right) == Right) {digitalWrite(pin_Right, LOW);} else {digitalWrite(pin_Right, HIGH);} myDelay(seq&0x000fffff); if (state){ return; } } }
// the output sequence routine void doStuff(){ digitalWrite(pin_A, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_A, HIGH); digitalWrite(pin_B, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_B, HIGH); digitalWrite(pin_X, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_X, HIGH); digitalWrite(pin_Y, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_Y, HIGH); digitalWrite(pin_LB, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_LB, HIGH); digitalWrite(pin_RB, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_RB, HIGH); digitalWrite(pin_Select, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_Select, HIGH); digitalWrite(pin_Up, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_Up, HIGH); digitalWrite(pin_Down, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_Down, HIGH); digitalWrite(pin_Left, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_Left, HIGH); digitalWrite(pin_Right, LOW); myDelay(1000); if (state){ return; } digitalWrite(pin_Right, HIGH); }
|
|
|
|
|
7
|
Using Arduino / Programming Questions / Re: Button triggered Macro, problems with interrupt and delay
|
on: December 28, 2012, 11:24:39 pm
|
ok so I've re-written my sketch per everyone's suggestions... it works! My only questions now are: Is there a more elegant way to do what I'm doing between each step in the doStuff function? I'm interested in loading in the sequence from a separate file and ideally programming the state of all 12 outputs plus the delay time in a single line for ease of reading... I have some ideas but I don't like any of them any suggestions on the best way to go about this? /* SNES Controller Test presses each of the buttons on the controller when the go button is pushed should also stop the sequence if the go button is pushed a second time */ //set names for the output pins int A = 4; int B = 0; int X = 1; int Y = 2;
int R = 12; int L = 7;
int Select = 13;
int Up = 11; int Down = 10; int Left = 9; int Right = 8;
int Go = 3;
byte state = HIGH; // The macro state 0=running 1=stopped byte lastButtonState = HIGH; // The go button state toggle 0=depressed unsigned long lastPushTime = 0; //the milliseconds since the last time the button was pushed unsigned long currentMillis = 0; //get the delay start time in milliseconds unsigned long previousMillis = 0; //get the current time in milliseconds
// the setup routine runs once when you press reset: void setup() { // initialize the digital pins as an output. pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(X, OUTPUT); pinMode(Y, OUTPUT); pinMode(L, OUTPUT); pinMode(R, OUTPUT); pinMode(Select, OUTPUT); pinMode(Up, OUTPUT); pinMode(Down, OUTPUT); pinMode(Left, OUTPUT); pinMode(Right, OUTPUT); // initialize the digital pins as an input. pinMode(Go, INPUT); //make sure everything is in the starting state that we want allClear(); }
//sets all outputs to off (high) void allClear(){ digitalWrite(Up, HIGH); digitalWrite(Down, HIGH); digitalWrite(Left, HIGH); digitalWrite(Right, HIGH); digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(X, HIGH); digitalWrite(Y, HIGH); digitalWrite(L, HIGH); digitalWrite(R, HIGH); digitalWrite(Select, HIGH); }
// the loop routine runs over and over again forever: void loop() { checkPushed(); //check if the button was pushed if (!state){ //if the state is set to run doStuff(); //run the sequence state = HIGH; //reset the state so we don't run again } allClear(); //set all the outputs to the starting position }
// the interrput routine run with the go button is pushed void checkPushed(){ byte buttonState = digitalRead(Go); if (lastButtonState && !buttonState){ unsigned long pushTime = millis(); //check the time // If pushed again within 60ms, assume it's a bounce and ignore if (pushTime - lastPushTime > 60){ state = !state; //change state lastPushTime = pushTime; //set the last check time } } lastButtonState = buttonState; }
// check for the button push void myDelay(unsigned long interval){ currentMillis = millis(); //get the current time previousMillis = currentMillis; //get the start time while (currentMillis - previousMillis < interval){ //loop until the desired delay is reached currentMillis = millis(); //get the current time checkPushed(); //check if the button has been pushed if (state){ //if the button push triggered a state change return; //exit the delay function } } }
// the output sequence routine void doStuff(){ digitalWrite(Up, LOW); //start of first step in the sequence myDelay(1000); //continue running step while checking for a state change if (state){ //if there was a state change return; //quit the sequence } digitalWrite(Up, HIGH); //end of first step in the sequence digitalWrite(Down, LOW); myDelay(1000); if (state){ return; } digitalWrite(Down, HIGH); digitalWrite(Left, LOW); myDelay(1000); if (state){ return; } digitalWrite(Left, HIGH); digitalWrite(Right, LOW); myDelay(1000); if (state){ return; } digitalWrite(Right, HIGH); digitalWrite(A, LOW); myDelay(1000); if (state){ return; } digitalWrite(A, HIGH); digitalWrite(B, LOW); myDelay(1000); if (state){ return; } digitalWrite(B, HIGH); digitalWrite(X, LOW); myDelay(1000); if (state){ return; } digitalWrite(X, HIGH); digitalWrite(Y, LOW); myDelay(1000); if (state){ return; } digitalWrite(Y, HIGH); digitalWrite(L, LOW); myDelay(1000); if (state){ return; } digitalWrite(L, HIGH); digitalWrite(R, LOW); myDelay(1000); if (state){ return; } digitalWrite(R, HIGH); digitalWrite(Select, LOW); myDelay(1000); if (state){ return; } digitalWrite(Select, HIGH); }
|
|
|
|
|
10
|
Using Arduino / Programming Questions / Button triggered Macro, problems with interrupt and delay
|
on: December 28, 2012, 10:45:16 am
|
So I'm building a macro game controller, my intent is that I push a button and the Arduino will run through a macro sequence, ideally I'd like to be able to push the button a 2nd time to immediately stop the macro even if it hasn't completed. pushing it a 3rd time would start the macro sequence back at the beginning again. I've got the hardware side complete and confirmed working. I wrote a small program that turns an LED on and off via an interrupt and then I wrote another one that runs through my sequence as part of the main loop, both of those worked great (and confirmed that my hardware is setup properly) but I'm having problems now that I'm trying to combine them. Initially when I tried running my macro sequence via an interrupt it would just skip over the calls to "delay" so I swapped that out for a manual calculation of delay using millis() but I can't seem to get that working and I don't know why. I would appreciate any help or advice. Here is my sketch: /* SNES Controller Test presses each of the buttons on the controller when the go button is pushed should also stop the sequence if the go button is pushed a second time */ //set names for the output pins int A = 4; int B = 0; int X = 1; int Y = 2;
int R = 12; int L = 7;
int Select = 13;
int Up = 11; int Down = 10; int Left = 9; int Right = 8;
int Go = 1; //interrupt 1 pin #3
volatile int state = HIGH; // The go button state toggle unsigned long lastInterruptTime = 0; //set the interrupt counter
// the setup routine runs once when you press reset: void setup() { // initialize the digital pins as an output. pinMode(A, OUTPUT); pinMode(B, OUTPUT); pinMode(X, OUTPUT); pinMode(Y, OUTPUT); pinMode(L, OUTPUT); pinMode(R, OUTPUT); pinMode(Select, OUTPUT); pinMode(Up, OUTPUT); pinMode(Down, OUTPUT); pinMode(Left, OUTPUT); pinMode(Right, OUTPUT); //setup interrupt attachInterrupt(Go, buttonPushed, LOW); //make sure everything is in the starting state that we want allClear(); }
//sets all outputs to off (high) void allClear(){ digitalWrite(Up, HIGH); digitalWrite(Down, HIGH); digitalWrite(Left, HIGH); digitalWrite(Right, HIGH); digitalWrite(A, HIGH); digitalWrite(B, HIGH); digitalWrite(X, HIGH); digitalWrite(Y, HIGH); digitalWrite(L, HIGH); digitalWrite(R, HIGH); digitalWrite(Select, HIGH); }
// the loop routine runs over and over again forever: void loop() { wait(); }
// the interrupt routine run with the go button is pushed void buttonPushed(){ unsigned long interruptTime = millis(); //check the interrupt time // If interrupts come faster than 50ms, assume it's a bounce and ignore if (interruptTime - lastInterruptTime > 50){ state = !state; //change state if (state){ doStuff(); //run the sequence } else { allClear(); //clear the outputs } lastInterruptTime = interruptTime; //set the last interrupt time } }
// my non "delay" delay routine void myDelay(int interval){ unsigned long previousMillis = millis(); //get the start time unsigned long currentMillis = millis(); //get the current time while (previousMillis + interval < currentMillis){ //loop until the start time plus the desired delay is reached currentMillis = millis(); //get the current time } }
void wait(){ myDelay(1000); // wait for 1 second }
// the output sequence routine void doStuff(){ digitalWrite(Up, LOW); myDelay(1000); digitalWrite(Up, HIGH); digitalWrite(Down, LOW); myDelay(1000); digitalWrite(Down, HIGH); digitalWrite(Left, LOW); myDelay(1000); digitalWrite(Left, HIGH); digitalWrite(Right, LOW); myDelay(1000); digitalWrite(Right, HIGH); digitalWrite(A, LOW); myDelay(1000); digitalWrite(A, HIGH); digitalWrite(B, LOW); myDelay(1000); digitalWrite(B, HIGH); digitalWrite(X, LOW); myDelay(1000); digitalWrite(X, HIGH); digitalWrite(Y, LOW); myDelay(1000); digitalWrite(Y, HIGH); digitalWrite(L, LOW); myDelay(1000); digitalWrite(L, HIGH); digitalWrite(R, LOW); myDelay(1000); digitalWrite(R, HIGH); digitalWrite(Select, LOW); myDelay(1000); digitalWrite(Select, HIGH); }
|
|
|
|
|
11
|
Using Arduino / Programming Questions / Re: Help Can't get Inturrupt to work..
|
on: July 11, 2011, 02:16:17 pm
|
A CHANGE interrupt handler will fire when the switch is pressed, and again when it is released. Is that what you really want?
not in the final sketch, no, however I wrote this as a simplified sketch to simply get the interrupt functionality figured out and I simply wanted to see ANY signs of life from the interrupt handler, for that "CHANGE" is perfect. 1) PIN 1 is the serial port, it is not recommended to use this for IO other than serial, however no real problem in your sketch. 2) The IRQ lines are line 2 and 3 and identified as 0 and 1
Connect the switch to pin 2 to run this minimal IRQ example ...
I didn't realize that IRQ couldn't only be used on certain lines, I'll try moving the pin later tonight, Thanks!
|
|
|
|
|
12
|
Using Arduino / Programming Questions / Help Can't get Inturrupt to work..
|
on: July 10, 2011, 12:29:14 pm
|
I have a project where I'm trying to get the Arduino to perform a series of tasks when I push a button, part of the functionality is that I want it to stop what it's doing and wait for the input again if I push the button again while it's running through it's tasks. For the life of me I can't get interrupts to work, it's as if I don't have them set at all. this is the bare bones code, I have a button on 1 with a pull up resistor to 5V, and an LED on pin 13 when I push the button the first time, the LED lights, up.... if I push it again it just ignores my input and stays lit. I feel like I must be missing something really simple. Any help would be appreciated. this is 100% of the code. int pbIn = 1; int ledOut = 13;
void setup(){ pinMode(pbIn, INPUT); pinMode(ledOut, OUTPUT); attachInterrupt(pbIn, stateChange, CHANGE); }
void loop(){ if (digitalRead(pbIn) == HIGH) { digitalWrite(ledOut, HIGH); delay(50000); } }
void stateChange(){ digitalWrite(ledOut, LOW); }
|
|
|
|
|
14
|
Using Arduino / Project Guidance / Re: feed a program an external script, looking for advice on high level approach.
|
on: July 05, 2011, 10:00:39 pm
|
|
I'm sure I could work out a multiplexed or serialized output if 14 digital isn't enough.
I hadn't thought of using an SD card, that would probably work quite well.
I don't know that I need or want to load the whole program from the card, just my script file.
thinking about it further reading from a thumb drive might even be better, as I wouldn't have to order an SD card port, I could just hack up a cable, and it'd be a bit more versatile too.
thanks for the suggestion!
|
|
|
|
|
15
|
Using Arduino / Project Guidance / feed a program an external script, looking for advice on high level approach.
|
on: July 05, 2011, 07:55:52 pm
|
My background:I'm not new to programming, I've written several PC applications, web applications even PIC micro-controller projects in the past. I'm also not new to electronics at all with numerous projects under my belt. Am am new to the arduino though. I have an Arduino UNO that I'm using. My Project:I have a project where I'd like to feed the arduino a "script" from an external source. Basically the "Script" would be like a macro of sorts identifying the state of the various outputs and how long they will remain in that state before changing to the next state in the script. The program on the arduino would wait for a "start" button to be activated and once pushed it would run through the script. These scripts could be as short as 10 seconds or as long as 10 minutes with output state changes occurring every few milliseconds. I guess you could think of it like a Christmas light controller and the various "scripts" would correspond to patterns you could play back on the lights. I'm looking at a maximum of 20 digital outputs and 6 analog outputs though for prototyping purposes to start I'll probably only need 6 or 8 digital outputs. Where I need help:Basically I'm not really sure the best way to transfer the script from my PC to the arduino. I'd like a method where I can have my Arduino installed and able to receive modifications to the script or new scripts on the fly. I'd also like the transfer method to be ubiquitous enough that I could give less tech savvy friends similar devices and have them create their own scripts/send and trade scripts with each other. I'm sure I'm capable of finding how to program the finer points of interpreting the script and changing the outputs, but I don't really know the best method of actually getting the script quickly and easily to the arduino. Ideally I'd need to be able to run a script, and easily feed a new script to the arudino without much hassle so I can make revisions quickly. I would appreciate any suggestions as well as links to similar projects that I might use as a reference. I've done some searching but I didn't come up with anything, I'm not sure I'm even searching for the right terms, as "script" and "macro" are rather generic. Thanks for taking the time to read this 
|
|
|
|
|