Show Posts
|
|
Pages: 1 ... 3 4 [5] 6
|
|
61
|
Using Arduino / Programming Questions / Re: Sketch resets unexpectedly
|
on: April 29, 2012, 02:25:12 pm
|
|
I attached a schematic of the Arduino setup i am using. Everything is SMT so removing components is difficult but not impossible. From the arduino I have a Sparkfun USB to serial board. I believe that I have the appropriate decoupling caps along with a 2.8V regulator.
The issue only occurs when the ATMega is awake and it only happens when it is in the while loop waiting for new serial data. I have other simpler code with no serial communications which acts as a timer which also seems to reset but I have never captured it. It will run perfectly happy for weeks or months before it resets. Now that I have added complexity and serial communications it resets frequently and I can easily replicate the problem.
|
|
|
|
|
62
|
Using Arduino / Programming Questions / Re: Sketch resets unexpectedly
|
on: April 29, 2012, 01:13:40 pm
|
|
I did not know that and I appreciate the information. I did try opening and closing my session on my terminal program while the sketch was running and I did not see it reboot. In my case the serial was open the entire time so I don't think that is what causes it to reset. Sometimes it will make it through a full cycle but not others.
|
|
|
|
|
63
|
Using Arduino / Programming Questions / Re: Sketch resets unexpectedly
|
on: April 29, 2012, 12:51:20 pm
|
In case it is helpful here is my code. #include <avr/sleep.h>
//10801 = 24 hours, 7.5 = 1 minute int time0 = 10; int time1 = 0; int time2 = 0; int time3 = 0; int time4 = 0; int time5 = 0; int time6 = 0; int time7 = 0; int time8 = 0; int time9 = 0; int time10 = 0; int time11 = 0; int reset = 10802;
char delimiters[30] = ","; char* valPosition;
int interval[150] = {0, 0, 0};
int midnight = 1;
int gpsdata = 0; int hours; int minutes; int update; int gsmdata = 0; int strend = 0; int i = 0;
volatile int seconds = 10800; volatile int timer = 0;
SIGNAL(TIMER2_OVF_vect){ seconds++; timer++; }
char inputString[100]; int inByte = 0;
boolean stringComplete = false;
void setup() {
for(int x = 1 ; x < 18 ; x++){ pinMode(x, INPUT); digitalWrite(x, HIGH); }
set_sleep_mode(SLEEP_MODE_PWR_SAVE); sleep_enable();
Serial.begin(9600);
//Power down various bits of hardware to lower power usage ADCSRA &= ~(1<<ADEN); //Disable ADC ACSR = (1<<ACD); //Disable the analog comparator DIDR0 = 0x3F; //Disable digital input buffers on all ADC0-ADC5 pins DIDR1 = (1<<AIN1D)|(1<<AIN0D); //Disable digital input buffer on AIN1/0
//Setup TIMER2 TCCR2A = 0x00; TCCR2B = (1<<CS22)|(1<<CS21)|(1<<CS20); / ASSR = (1<<AS2); TIMSK2 = (1<<TOIE2);
sei(); //Enable global interrupts
}
void loop() {
sleep_mode(); sleep_disable();
ADCSRA &= ~(1<<ADEN); ACSR = (1<<ACD); DIDR0 = 0x3F; DIDR1 = (1<<AIN1D)|(1<<AIN0D);
if (seconds == time0){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time1){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time2){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time3){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time4){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time5){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time6){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time7){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time8){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time9){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time10){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == time11){ reset_5s(); initialize(); Serial.println("type text now"); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); }
if (seconds == reset){ Serial.print("this is millis "); Serial.println( millis()); seconds = 1; if (midnight > 0){ reset_5s(); Serial.println("type text now"); Serial.print("this is seconds "); Serial.println(seconds); Serial.print("this is timer before initialize "); Serial.println(timer); initialize(); serialEvent(); //looks for serial data for a fixed period of time Serial.println("going to sleep now"); Serial.print("this is millis "); Serial.println( millis()); } } } // // collect the serial data //
void initialize(){ gpsdata = 0; gsmdata = 0; strend = 0; minutes = 0; hours = 0; timer = 0; i = 0; }
void serialEvent(){ Serial.flush(); while (timer < 5){s Serial.print("this is timer "); Serial.println(timer); if (Serial.available() > 0) { inByte = Serial.read(); inputString[i] = inByte; Serial.println(inputString[i], BYTE); i++; if (inByte == '!'){ i = 0; Serial.println("gpsdata is now 1"); gpsdata = 1; // set the gpsdata bit to 1 to force the update to GPS }
if (inByte == '*'){ i = 0; gsmdata= 1; // set the gsmdata bit to 1 to force the update to GSM Serial.println("gsmdata is now 1"); }
if (inByte == '#') { if (gpsdata == 1){ Serial.println("went to GPSdata"); verifygps(); } if (gsmdata == 1){ Serial.println("went to GSMdata"); verifygsm(); } } } } } void verifygps(){ Serial.println("went to verify GPS"); valPosition = strtok(inputString, delimiters); for(int i = 0; i < 6; i++){ Serial.print("this is i "); Serial.println(i); interval[i] = atoi(valPosition); Serial.println(interval[i]); valPosition = strtok(NULL, delimiters); Serial.println("this is interval 0"); Serial.println(interval[0]); //do the math to create the seconds variable hours = interval[0]; minutes = interval[1]; hours = hours * 450; minutes = minutes * 7.5; update = minutes + hours + 5; // 5 added since seconds isnt recognized and it takes time to parse and update Serial.println("this is update"); Serial.println(update); // if update is between the variables then it updates the seconds if (update > 0 && update < 10801){ Serial.print("this is seconds before update "); Serial.println(seconds); seconds = update; Serial.print("this is seconds after the update "); Serial.println(seconds); //timer = 40; // forces it to go to sleep //dont do this so overlap cant happen with GPS times }
else{ Serial.println("GPS data was not verified and seconds was not updated"); } }
}
void verifygsm(){ valPosition = strtok(inputString, delimiters); for(int i = 0; i < 6; i++){ Serial.print("this is i "); Serial.println(i); interval[i] = atoi(valPosition); Serial.println(interval[i]); valPosition = strtok(NULL, delimiters);
} if(interval[1] > 0 && interval[1] < 10802){ midnight = interval[0]; Serial.print("this is midnight update "); Serial.println(interval[0]); time0 = interval[1]; Serial.print("this is time0 "); Serial.println(time0); time1 = interval[2]; Serial.print("this is time1 "); Serial.println(time1); time2 = interval[3]; Serial.print("this is time2 "); Serial.println(time2); time3 = interval[4]; Serial.print("this is time3 "); Serial.println(time3); time4 = interval[5]; Serial.print("this is time4 "); Serial.println(time4); time5 = interval[6]; Serial.print("this is time5 "); Serial.println(time5); timer = 40; //forces the serial to stop and go to sleep } else{ Serial.println("string did not match or time was outside of range"); } } //turns the Telit on by holding the pin low for 5 seconds. //uses fake_msdelay to create the delay so no interupt is generated. It is not very accurate. void reset_5s(){ pinMode(A0, OUTPUT); digitalWrite(A0, LOW); // needs to be LOW fake_msdelay(2000); digitalWrite(A0, HIGH); // needs to be HIGH pinMode(A0, INPUT); }
void fake_msdelay(int x){ for( ; x > 0 ; x--) fake_usdelay(1000); }
void fake_usdelay(int x){ for( ; x > 0 ; x--) { __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t"); } }
|
|
|
|
|
64
|
Using Arduino / Programming Questions / Sketch resets unexpectedly
|
on: April 29, 2012, 12:47:54 pm
|
|
My project involves putting the Arduino to sleep and then waking it up at pre-determined times. While it is awake it waits for a brief time looking for incoming serial data. The serial data is meant to update the time intervals that it should wake up for. Once it completes this cycle it goes back to sleep and then wakes at the next predetermined time. I am working with a 328P on a breadboard running a 32khz external crystal. I set the seconds variable to run async with the external crystal and this is what keeps my time during sleep and creates the interupt to wake from. I use the 8mhz internal clock boot loader and the 0023 IDE. I don't use V1 IDE because it has issues with the 8mhz internal clock bootloader which I did not find a solution for yet.
The problem I run into is that about 60% of the time while the sketch is running and waiting for serial data it reboots. If I send serial data before the error it accepts the data and then goes to sleep just fine. The Arduino has a tendencay to reset when I just let it time out and no serial data is sent. I started to print millis() which verified that it is indeed rebooting mid-cycle. My reading on the forum suggests that I am likely running out of SRAM. My issue is that I don't understand things well enough to know how to figure out what is causing the memory issue. I have seen the MemoryFree library which I tried and it consistently shows 820 right up until it resets. Any suggestions on how I can trouble shoot a memory issue?
|
|
|
|
|
66
|
Using Arduino / Programming Questions / learning how to use arrays
|
on: February 08, 2012, 05:05:32 pm
|
I am learning how to use arrays and I have read the Arduino tutorial on the subject. I am doing a basic project to learn how they work and just when I thought I was starting to understand them I got stuck. My goal is to send serial data such as SCH*,123,456,789# which is populated into an array and then split it into arrays based on the comma. I took the basic structure of the GPS sketch in the playground since it takes serial data, verifies the starting characters, uses a terminating character and then splits it into arrays based on a comma. In my sketch I am able to send serial data and verify the starting characters just fine. I use SCH* as starting characters to verify the data is valid and I use # as a terminating character which seems to work. This array works well, where I run into trouble is when I try to split the data into arrays based on the comma. My goal is to end up with an array such as SCH* is array 0, 123 is array 1, 456 is array 2, etc. My sketch does not seem read the initial array and find the comma in order to split it up. I put print statement all over the place to help me debug and understand better but I still cant seem to get past this. Any suggestions on where I went wrong or how I could use the array feature better? int incoming = -1 ; int count = 0; int conta=0; char linea[30] = ""; char verify[6] = "SCH*"; int check = 0; int indicies[5]; int cont = 0;
void setup() // run once, when the sketch starts { Serial.begin(9600); // set up Serial library at 9600 bps }
void loop() {
incoming = Serial.read(); // Read a byte of the serial port if (incoming == -1) { // See if the port is empty yet delay(100); //delay if nothing is on the serial yet } else { linea[conta] = incoming; // If there is serial port data, it is put in the buffer conta++; //moves the array up one } //checks for an # if (incoming == '#'){ Serial.println("linea got an #"); Serial.println(linea); Serial.println("This is first array in verify"); Serial.println(verify[0]); Serial.println("This is first array in linea"); Serial.println(linea[0]); conta = 0; // resets the array once it gets an # check = 0; //if ==3 then the start of the string is correct and should proceed to process data for (int i=0;i<3;i++){ // Verifies if the received command starts with SCH* if (linea[i]==verify[i]){ Serial.println("this is i"); Serial.println(linea[i]); check++; } if(check ==3){ Serial.println("the initial string matches"); //incoming = -1; for (int i=0; i< 30;i++){ //Serial.println("looping 30 times looking for ,"); //Serial.println("this is i"); Serial.print(linea[i]); // // Sketch gets stuck here and the section below does not work to separate based on the comma // if (linea[i]==','){ indicies[cont] = i; //used to seperate based on comma but does not read linea properly cont++; Serial.println("this is indices 0"); Serial.println(indicies[0]); } for (int i =0 ;i< 30;i++){ linea[i] = ' '; } } } else{ Serial.println("SCHED check does not match"); }
} } }
|
|
|
|
|
68
|
Using Arduino / General Electronics / Re: Solar powered Arduino charging issue
|
on: January 24, 2012, 10:54:24 am
|
|
I just gave a 6V wall wart a try. The input voltage was steady at 6.24V with or without a load on the battery and the charge rate was about 80Mah with and without a load on the battery. So by all accounts the charger worked properly with a wall wart.
|
|
|
|
|
69
|
Using Arduino / General Electronics / Re: Solar powered Arduino charging issue
|
on: January 24, 2012, 08:24:53 am
|
|
agreed, that is a good article and thanks for posting it!
I am not using a regulator since the GPS and Arduino work well at the li-po voltage. I did more testing and have some observations though. When I put a fully charged battery on the charger I read 5.5V on the solar input line. When the battery requires charging it appears to draws on the solar as hard as it can and brings the voltage down to 4.2V on the input side. As the battery gets close to being charged it ramps down the charge and the solar voltage works its way from 4.2V up to the 5.5V when the battery is charged and it stops. When I connect a discharged battery and put it under load (even small loads) I see the solar input voltage go up from 4.2 to 4.6-4.9V which suggests that the charger is not sensing that the battery needs to be charged. It seems to think that the battery is mostly charged and it is starting to taper off the charge. It is not clear to me why a load on the battery would impact the voltage the charger see's but somehow it seems to.
|
|
|
|
|
70
|
Using Arduino / General Electronics / Re: Solar powered Arduino charging issue
|
on: January 23, 2012, 07:16:37 pm
|
I don't know how to check for all of those specs and none are given by the manufacture. The solar cell is designed to be 5V and I have measured 6V in good sun with no load. A close approximation to what I have is this unit from solarbotics http://solarbotics.com/products/scc2433b-mse/. When I measure the input side of the max1555 with no load I see 4.2V with about 17mah which seems correct since this is what it is trying to charging to. When I add a small load (about 200uA) I see the solar input voltage rise to 4.9V and the current is about 10mah. When I put a heavier load on the battery (about 35mah) the input voltage is about 4.6V and the current from the solar cell remains about 10mah. i am not sure exactly what the results mean but they seem odd to me.
|
|
|
|
|
71
|
Using Arduino / General Electronics / Solar powered Arduino charging issue
|
on: January 23, 2012, 02:29:04 pm
|
|
I have stand alone Arduino with a GPS that is powered by a 3.7V li-po battery. To save the battery I put both the Arduino and the GPS to sleep which works very well. To keep things going I have a solar cell to recharge the battery. I am using a Max1555 1 cell li-po charger which I have seen a bunch of other people in this forum use for a similiar purpose. When I populate ONLY the Max1555 charger and decoupling caps on the PCB the charging works great. In this configuration I am measuring about 17mah which I am very happy with. To clarify I am measuring in series on the solar cell going to the charger. However, as soon as I add a load to the battery the charge current drops dramatically. I am seeing the charge rate drop to about 10mah which is not really enough for my application. My components in sleep mode draw about 200uA which should be low enough to have limited impact on charging. Has anyone else had problems using a Max1555 to charge a battery while it is still under load? I read the datasheet and did not find anything that says it can or cant charge a battery while under load.
Thanks in advance for the advice!
|
|
|
|
|
73
|
Using Arduino / Programming Questions / Re: Sleep and wake intervals
|
on: January 04, 2012, 05:18:56 pm
|
|
I made the change to the interrupt as suggested by Udo and the clock is now running reliably. Thank you very much!
@Nick, I am thinking I will continue to use the 32.768khz crystal which seems to be fairly accurate. I require the Arduino to wake up only a few times per day so the sleep intervals are fairly long so I think I will stick with my existing method of incrementing a variable. I have a GPS connected so I am thinking I can use the time from the NMEA data to update the seconds variable and keep everything running accurately. That is my plan anyway, we will see how it works out....
|
|
|
|
|
74
|
Using Arduino / Programming Questions / Re: Sleep and wake intervals
|
on: January 04, 2012, 09:31:01 am
|
|
Some excellent suggestions here!
@Nick, I disabled the BOD and in sleep mode I measure 1.5uA. I didn't use the watchdog timer because it only last 8 seconds and I need as much as 24 hours. Maybe this can be looped but I didn't know how to do it so I used a variable that increments from timer2. I looked over your example sketch and I did not see anything that would make the WDT timer increment more than 8 seconds. Is it possible to get hours out of it and do you think it would be a better solution than what I have now? Accuracy is a concern and I do need this to maintain a fairly precise clock over a period of years. @Jack, I read all of the millis() articles and spent some hours last night working with it. I tried to implement it but had difficulty since timer0 gets shut off. Since I wont have any other interrupts to worry about is delay() a bad option? I have never heard of atomic.h and have no idea what it does but I will read up on that.
@Udo, I will give that a try and let you know my results. During my testing at this moment you are correct in your assumption that they are floating.
Thanks again everyone, this forum is really amazing!!
|
|
|
|
|
75
|
Using Arduino / Programming Questions / Sleep and wake intervals
|
on: January 03, 2012, 10:30:33 am
|
I am working with a bread boarded 328P running the 8mhz internal clock boot loader and I have a 32.768khz external crystal. I am trying to put it to sleep and then wake up at predetermined times based on timer2. I have variable "seconds" and use timer2 to increment this variable. So if seconds is greater than variable A then it wake sup and takes pin A0 low and reset seconds to zero and start the cycle over. I am successfully putting it to sleep and waking it up but the cycles are not even and I cant understand why. For example with the posted code it will go to sleep and then wake up every 2 minutes and 14 seconds. It is running very reliably at that interval for the first 3-4 cycles and then the next 3-4 cycles will be all over the place. For example sometimes is it 3 minutes, sometimes 4+ minutes and each cycle is vastly different. Then it will settle down and run reliably at the 2 minutes and 14 seconds for a few cycles. Although it is set for a short duration for testing my goal is to set it for several hours delay. Any suggestions are greatly appreciated! #include <avr/sleep.h> //Needed for sleep_mode #include <avr/power.h> //Needed for powering down perihperals such as the ADC/TWI and Timers
volatile long seconds = 0;
int A = 28;
//The very important 32.686kHz interrupt handler SIGNAL(TIMER2_OVF_vect){ seconds++; }
void setup() { //To reduce power, setup all pins as inputs with no pullups for(int x = 1 ; x < 18 ; x++){ pinMode(x, INPUT); digitalWrite(x, HIGH); //changed from low to high which was 400ua change }
//Power down various bits of hardware to lower power usage set_sleep_mode(SLEEP_MODE_PWR_SAVE); sleep_enable();
//Shut off ADC, TWI, SPI, Timer0, Timer1
ADCSRA &= ~(1<<ADEN); //Disable ADC ACSR = (1<<ACD); //Disable the analog comparator DIDR0 = 0x3F; //Disable digital input buffers on all ADC0-ADC5 pins DIDR1 = (1<<AIN1D)|(1<<AIN0D); //Disable digital input buffer on AIN1/0 power_twi_disable(); power_spi_disable(); // power_usart0_disable(); power_timer0_disable(); power_timer1_disable(); //power_timer2_disable(); //Needed for asynchronous 32kHz operation
//Setup TIMER2 TCCR2A = 0x00; TCCR2B = (1<<CS22)|(1<<CS21)|(1<<CS20); //Set CLK/1024 or overflow interrupt every 8s ASSR = (1<<AS2); //Enable asynchronous operation, 32kHz xtal needed TIMSK2 = (1<<TOIE2); //Enable the timer 2 interrupt
//Setup external INT1 (pin3) interrupt EICRA = (1<<ISC11)|(1<<ISC01)|(1<<ISC10)|(1<<ISC00); //Interrupt on rising edge EIMSK = (1<<INT0)|(1<<INT1); //Enable INT interrupts //need pull downs if active high, active low can enable internal pulllups digitalWrite(3, LOW); digitalWrite(2, LOW);
sei(); //Enable global interrupts }
void loop() { sleep_mode(); //Stop everything and go to sleep. Wake up if the Timer2 buffer overflows or if you hit the button ADCSRA &= ~(1<<ADEN); //Disable ADC ACSR = (1<<ACD); //Disable the analog comparator DIDR0 = 0x3F; //Disable digital input buffers on all ADC0-ADC5 pins DIDR1 = (1<<AIN1D)|(1<<AIN0D); //Disable digital input buffer on AIN1/0 //variable 1 if(seconds > A){ reset_5s(); }
}
void reset_5s(){ pinMode(A0, OUTPUT); digitalWrite(A0, LOW); // needs to be LOW fake_msdelay(2000); digitalWrite(A0, HIGH); // needs to be HIGH pinMode(A0, INPUT); seconds = 0; }
//This is a not-so-accurate delay routine //Calling fake_msdelay(100) will delay for about 100ms //Assumes 8MHz clock void fake_msdelay(int x){ for( ; x > 0 ; x--) fake_usdelay(1000); }
//This is a not-so-accurate delay routine //Calling fake_usdelay(100) will delay for about 100us //Assumes 8MHz clock void fake_usdelay(int x){ for( ; x > 0 ; x--) { __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t"); __asm__("nop\n\t"); } }
|
|
|
|
|