This code is part of a project Ive been working on; its a datalogger that logs data to a I2C EEprom over time. Right now I have it set to log data once every minute. I have a bunch of debug lines in that just spit out data via UART so I can watch whats going on. So far, everything works as intended
But here is what I want to do: Obviously in field I do not need UART communication. The processor will sleep, and then wake up, turn on external power, take data and go back to sleep. This much works. But I need a way to retrieve the data once the datalogger is finished doing its job in field. So I will depoly the datalogger, let it do its own thing, bring it back in, and connect it to a computer. If I send a "R" or an "E" it will either retreive data or erase data.
Hence this part:
HSerReceive(Rec)HSerPrint"Interrupt Seen"HSerReceive(Rec)IfRec="R"thenEEpromDataAddress=0HSerPrint"EEprom Read"ForEEpromDataAddress=0toMaxAddresseeprom_rd_byte(eepDev, EEpromDataAddress, TempData)HSerPrintTempDataHSerSend13HSerSend10nextEEpromDataAddress=0MaxAddress=0BAUDCON.WUE=1endifIfRec="E"thenForEEpromDataAddress=0to65535eeprom_wr_byte(eepDev, EEpromDataAddress, 0)HSerPrintEEpromDataAddressHSerPrint"% Done"HSerSend13HSerSend10HSerReceive(Rec)ifRec="S"thenEXITFor'Stops the loop from happeningwait5msnextHSerPrint"Device Erased"BAUDCON.WUE=1endif
Ive gotten it to work in a stand alone Read/Write Program to an EEprom project, so the problem is integrating it here when I already have an interrupt happening. I want to wake the processor up when it sees a byte on the UART recieve channel, respond back and take the data out of the EEprom and display it via UART.
I think my problem may be due to having two interrupts. The first is Timer 1, which is crucial for obvious reasons. I dont know if I am setting the WUE bit correctly where it needs to be, so you may see it in various places. Any help here or suggestions would be appreciated :). Ive included one solution down below already, but I am wondering if there is a different or better way that will save power.
Possible Working solution: I could have it just check the UART receive register once per second to see if there is anything waiting but I am worried about power usage in this case. I am using the LF version of the PIC to save more power as well. It is powered via solar during the day and two 6F super Caps during the night. Looking through the datasheet, there is no power usage given for the UART module. I wonder why that is. Does the UART module not take any current? It is just a shift register after all.
For those interested: I do have a Github link+ schematics for this project. I just dont have it with me as of this writing. I have included the code in this post as its kind of long. I am also open to criticism on how to be better at coding or rather how I organize things.
Have you thought of using the serial buffer ring? You can load the buffer when the interrupt happens or handle the interrupt flag to load the buffer, and then in either cases consume the buffer when you need to.
The Help has the serial buffer and there are few demos, but, this is way I would go.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I had a similar solar datalogger project. Now I cheated and just used a "wait 10 s" to start the next logging of variables to eeprom. Here is the code I used to start/stop the data logging by pressing a button.
'*****IOC Begin/Stop Log Interrupt*****subInterruptIfIOCAF7=1ThensetIOCAF7OffDoWhileswitchOffSetLEDONLoopcount+=1SetLEDOffIfBegin=TrueThen'second button pressStopLog=TrueexitsubEndIf'first button pressBegin=TrueEndIf'test for UART RX, send any character from terminal' If RCIF = 1 Then' RCIF = 0' Pulseout LED, 3 s'' StartUartFile = True' End Ifendsub
After the second press of the button, you could use a flag to shutdown the timer interrupt (PIE bit?) so there would be no conflict with the UsartRX1Ready interrupt? So, sub Interrupt for the switch, and timer1Overflow, UsartRX1Ready GCB interrupts in initialization.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello. I meant to get back to the both of you, but I currently have a working solution, so I thank you for your suggestions. I kind of did do what kent suggested in a way. One cavet with my current solution: sometimes it will say Interrupt seen for no reason. Could be noise or something. Maybe the RX pin should be grounded with a resistor. The code works though. I am currently putting it through its final paces :D. Ive commented as much as I can..and Im sure I could remove some of the "WUE" bits all over the place..but it works. But I wanted people to have a copy of this. Once I confirm this works, I will post my github link.
Alternative Suggestion. I dont know why I didnt see this before. It honestly came to in a dream last night: Use PGD/Int0 to just trigger a mem dump and erase. Use a toggle switch that requires the user to hold it down for 5 seconds so the system doesnt reset itself. Its not like PGD is going to be needed all the time. But this is incase my burn in test fails.
Oh and I still have to verify that this micro is actually sleeping since its powered via 2 super capacitors.
Hello All :)
This code is part of a project Ive been working on; its a datalogger that logs data to a I2C EEprom over time. Right now I have it set to log data once every minute. I have a bunch of debug lines in that just spit out data via UART so I can watch whats going on. So far, everything works as intended
But here is what I want to do: Obviously in field I do not need UART communication. The processor will sleep, and then wake up, turn on external power, take data and go back to sleep. This much works. But I need a way to retrieve the data once the datalogger is finished doing its job in field. So I will depoly the datalogger, let it do its own thing, bring it back in, and connect it to a computer. If I send a "R" or an "E" it will either retreive data or erase data.
Hence this part:
Ive gotten it to work in a stand alone Read/Write Program to an EEprom project, so the problem is integrating it here when I already have an interrupt happening. I want to wake the processor up when it sees a byte on the UART recieve channel, respond back and take the data out of the EEprom and display it via UART.
I think my problem may be due to having two interrupts. The first is Timer 1, which is crucial for obvious reasons. I dont know if I am setting the WUE bit correctly where it needs to be, so you may see it in various places. Any help here or suggestions would be appreciated :). Ive included one solution down below already, but I am wondering if there is a different or better way that will save power.
Possible Working solution: I could have it just check the UART receive register once per second to see if there is anything waiting but I am worried about power usage in this case. I am using the LF version of the PIC to save more power as well. It is powered via solar during the day and two 6F super Caps during the night. Looking through the datasheet, there is no power usage given for the UART module. I wonder why that is. Does the UART module not take any current? It is just a shift register after all.
For those interested: I do have a Github link+ schematics for this project. I just dont have it with me as of this writing. I have included the code in this post as its kind of long. I am also open to criticism on how to be better at coding or rather how I organize things.
Chris.
Have you thought of using the serial buffer ring? You can load the buffer when the interrupt happens or handle the interrupt flag to load the buffer, and then in either cases consume the buffer when you need to.
The Help has the serial buffer and there are few demos, but, this is way I would go.
I had a similar solar datalogger project. Now I cheated and just used a "wait 10 s" to start the next logging of variables to eeprom. Here is the code I used to start/stop the data logging by pressing a button.
After the second press of the button, you could use a flag to shutdown the timer interrupt (PIE bit?) so there would be no conflict with the UsartRX1Ready interrupt? So, sub Interrupt for the switch, and timer1Overflow, UsartRX1Ready GCB interrupts in initialization.
Hello. I meant to get back to the both of you, but I currently have a working solution, so I thank you for your suggestions. I kind of did do what kent suggested in a way. One cavet with my current solution: sometimes it will say Interrupt seen for no reason. Could be noise or something. Maybe the RX pin should be grounded with a resistor. The code works though. I am currently putting it through its final paces :D. Ive commented as much as I can..and Im sure I could remove some of the "WUE" bits all over the place..but it works. But I wanted people to have a copy of this. Once I confirm this works, I will post my github link.
Alternative Suggestion. I dont know why I didnt see this before. It honestly came to in a dream last night: Use PGD/Int0 to just trigger a mem dump and erase. Use a toggle switch that requires the user to hold it down for 5 seconds so the system doesnt reset itself. Its not like PGD is going to be needed all the time. But this is incase my burn in test fails.
Oh and I still have to verify that this micro is actually sleeping since its powered via 2 super capacitors.
Git Hub Link:
https://github.com/chrissavage2300/EEprom-Datalogger
I will be editing that page as needed to add photos and what not.