Created
December 9, 2014 16:01
-
-
Save Scott216/673f24079b22f3b147e1 to your computer and use it in GitHub Desktop.
Debugging panStamp lockup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Hardware: | |
Wiznet Ethernet module | |
PanStamp V2 | |
Forum thread regarding compile problems: http://www.panstamp.org/forum/showthread.php?tid=3073&page=6 | |
Compiled with Arduino IDE v1.5.8 | |
Since both panstamp and Ethernet libary use pin D10 for slave select, some of the Ethernet libraries need to be modified to use a different pin. | |
SurferTim modified library files so Ethernet.select() would work: | |
Got new library from SurferTim here: http://forum.arduino.cc/index.php?topic=217423.msg1962182#msg1962182 | |
Files changed are: | |
C:\Program Files (x86)\arduino_158\libraries\Ethernet\src\Ethernet.h & .cpp | |
C:\Program Files (x86)\arduino_158\libraries\Ethernet\src\utility\w5100.h & .cpp | |
Difference between stock Arduino v1.5.8 original and SurferTim's are: | |
w5100.h - https://www.diffchecker.com/2zzxtslg | |
w5100.cpp - https://www.diffchecker.com/hl0s1zmd | |
Ethernet.h - https://www.diffchecker.com/hwg0wq0p | |
Ethernet.cpp - https://www.diffchecker.com/6jdpzevk | |
To Do: | |
Xively Streams ( http://xively.com/feeds/103470 ) | |
0 Inches of rain. Take pulses and divide by 10 | |
1 Heater On/Off | |
2 Heating Pad 1 temp | |
3 Heating Pad 2 temp | |
4 Heating Pad 3 temp - future use | |
5 Temp inside rain collector | |
6 Outside temp | |
7 Spare | |
8 Xively upload successes | |
9 Xively upload failures | |
10 panStamp TxRx successes | |
History | |
v2.00 09/13/14 - combined panStamp Rx and Base code together so panStamp can control Ethernet shield | |
v2.01 10/04/14 - renamed a few things, some minor cleanup | |
v2.02 10/17/14 - Changed networks address (syncword)to two byte array | |
v2.03 12/02/14 - compiled with IDE 1.5.8 and SurferTim modified libraries - doesn't work, hangs on Serial.println(Ethernet.localIP()); | |
v2.04 12/09/14 - added debugging code to find lockup problem. Commented out Ethernet code and found it's hanging on radio.init(). Using stock Ethernet libraries | |
*/ | |
#define VERSION "v2.04" | |
#define PRINT_DEBUG | |
// #define ENABLE_ETHERNET // use for debugging problems between panStamp and ethernet | |
// #define WDT | |
#include <SPI.h> // Put this after cc1101.h Communicate with SPI devices http://arduino.cc/en/Reference/SPI | |
#include "HardwareSerial.h" // Required by IDE 1.5.x | |
#include <ERxPachube.h> // Library to upload to Xively http://code.google.com/p/pachubelibrary/ | |
#include <Ethernet.h> // LIbrary for Arduino ethernet shield http://arduino.cc/en/Reference/Ethernet | |
#include <avr/wdt.h> // Watchdog timer, Example code: http://code.google.com/p/arduwind/source/browse/trunk/ArduWind.ino | |
//#include <Tokens.h> // Xively API Key | |
#define XIVELY_API_KEY "TESTING" // temporary - use for sharing publicly | |
#define UPDATE_INTERVAL 20000 // Xively upload interval (mS) | |
#define UPDATE_TIMEOUT 600000 // 10 minute timeout - if there are no successful updates in 10 minutes, reboot | |
uint32_t g_uploadTimout_timer = UPDATE_TIMEOUT; // Timer to reboot if no successful uploads in 10 minutes | |
// Xively Feed IDs | |
#define FEED_ID_TEST 4663 // Test feed http://xively.com/feeds/4663 | |
#define FEED_ID_RAIN 103470 // Rain Collector http://xively.com/feeds/103470 | |
ERxPachubeDataOut dataout_Rain(XIVELY_API_KEY, FEED_ID_RAIN); | |
const byte XIVELY_STREAMS = 11; | |
// I/O | |
const byte ETH_SS_PIN = 9; // Slave Select pin | |
const byte TX_OK_LED_PIN = 4; // LED to flash when Xively upload succeeds | |
const byte RX_OK_LED_PIN = 5; // LED to flash when panStamp packet is received | |
byte g_ip[] = { 192, 168, 46, 83 }; // Suntec | |
// byte g_ip[] = { 192, 168, 216, 40 }; // Crestview | |
byte g_mac[] = { 0xCC, 0xAC, 0xBE, 0x46, 0xFE, 0x99 }; | |
byte g_psNetworkAddress[] = {10, 0}; // panStamp network address, aka SyncWord | |
byte g_psReceiverAddress = 40; // panStamp Rx address | |
// The connection to the panStamp hardware chip CC1101 the RF Chip. http://code.google.com/p/panstamp/wiki/CC1101class | |
CC1101 radio; | |
// flag indicates a wireless panStamp packet has been received | |
volatile boolean g_psPacketAvail = false; | |
// Variables to hold data coming from rain collector | |
int g_tempIn; // Temp inside rain collector | |
int g_tempOut; // Outdoor teamp | |
int g_tempHeatPad1; // Heating pad temp | |
int g_tempHeatPad2; // Heating pad temp | |
int g_rainPulseCount; // Rain gauges pulses, 1 pulse = 0.01" rain | |
bool g_isHeaterOn; // True if heater on | |
bool g_TxOK; // True if rain collector is transmitting | |
uint8_t g_xively_successes = 0; // Successful Xively uploads | |
uint8_t g_xively_failures = 0; // Xively Network failures | |
uint8_t g_panStampSuccesses = 0; // panStamp RxTx successes | |
// Declare function prototypes | |
void radioSignalsInterrupt(void); | |
int uploadRainCollector(); | |
void checkXivelyStatus(int statusXively); | |
void BlinkLed(byte ledPin); | |
void PrintDataStream(const ERxPachube& pachube); | |
void printpanStampDeviceInfo(); | |
void software_Reset(); | |
#ifdef WDT | |
void WatchdogSetup(void); | |
void WDT_ForceTimeout(); | |
#endif | |
// Handle interrupt from CC1101 (INT 0) | |
void radioSignalsInterrupt(void) | |
{ | |
// set the flag that a package is available | |
g_psPacketAvail = true; | |
} // end radioSignalsInterrupt() | |
void setup() | |
{ | |
#ifdef WDT | |
// We always need to make sure the WDT is disabled immediately after a | |
//reset, otherwise it will continue to operate with default values. | |
wdt_disable(); | |
#endif | |
Serial.begin(9600); | |
pinMode(RX_OK_LED_PIN, OUTPUT); | |
pinMode(TX_OK_LED_PIN, OUTPUT); | |
// Wait for seial connection to be established - Leonardo needs this | |
delay(2000); | |
Serial.print(F("Rain Collector ")); | |
Serial.println(VERSION); | |
#ifdef ENABLE_ETHERNET | |
Ethernet.select(ETH_SS_PIN); // Set slave select pin - requires modified Ethernet.h library | |
Ethernet.begin(g_mac, g_ip); // Initialize Ethernet | |
Serial.println(Ethernet.localIP()); | |
#endif | |
// setup upload feeds | |
for (int i=0; i < XIVELY_STREAMS; i++) | |
{ dataout_Rain.addData(i); } | |
// initialize the panStamp radio | |
Serial.println("debug A"); delay(100); | |
radio.init(); | |
Serial.println("debug B"); delay(100); | |
radio.setSyncWord(g_psNetworkAddress); // Set network address, pointer to address | |
// this panStamp Rx device address needs to match the target address in the Tx | |
Serial.println("debug C"); delay(100); | |
radio.setDevAddress(g_psReceiverAddress); // 2nd parameter (false) determines is value is set in EEPROM | |
Serial.println("debug D"); delay(100); | |
radio.enableAddressCheck(); // you can skip this line, because the default is to have the address check enabled | |
// Set this panStamp to be a receiver | |
Serial.println("debug E"); delay(100); | |
radio.setRxState(); | |
Serial.println("debug F"); delay(100); | |
attachInterrupt(0, radioSignalsInterrupt, FALLING); // Enable panStamp wireless reception interrupt | |
Serial.println("debug G"); delay(100); | |
printpanStampDeviceInfo(); | |
#ifdef WDT | |
WatchdogSetup();// setup Watch Dog Timer to 8 sec | |
wdt_reset(); | |
Serial.println(F("Initialize Watchdog Timer")); | |
#endif | |
BlinkLed(RX_OK_LED_PIN); | |
BlinkLed(RX_OK_LED_PIN); | |
BlinkLed(TX_OK_LED_PIN); | |
BlinkLed(TX_OK_LED_PIN); | |
Serial.println(F("setup complete")); | |
} // end setup() | |
void loop() | |
{ | |
static uint32_t upload_timer; // Timer for uploading to Xively | |
static uint32_t gotpsPacketTime; // Keeps track of time since last successful packet from rain collector | |
#ifdef PRINT_DEBUG | |
static int printHdr; // prints heading every 20 rows | |
#endif | |
#ifdef WDT | |
wdt_reset(); // Reset watchdog time | |
#endif | |
if(g_psPacketAvail) | |
{ | |
g_psPacketAvail = false; // Reset panStamp paccket avail flag | |
CCPACKET psPacket; // http://code.google.com/p/panstamp/source/browse/trunk/arduino/libraries/panstamp/ccpacket.h | |
// Disable wireless reception interrupt so this code finishes executing without inturruption | |
detachInterrupt(0); | |
if( radio.receiveData(&psPacket) > 0 ) | |
{ | |
if( psPacket.crc_ok && psPacket.length > 1 ) | |
{ | |
gotpsPacketTime = millis(); // keep track of time since last good packet | |
// Get data from panStamp packet and put in global variables | |
g_isHeaterOn = psPacket.data[2]; | |
g_rainPulseCount = psPacket.data[3] << 8; | |
g_rainPulseCount |= psPacket.data[4]; | |
g_tempOut = psPacket.data[5] << 8; | |
g_tempOut |= psPacket.data[6]; | |
g_tempIn = psPacket.data[7] << 8; | |
g_tempIn |= psPacket.data[8]; | |
g_tempHeatPad1 = psPacket.data[9] << 8; | |
g_tempHeatPad1 |= psPacket.data[10]; | |
g_tempHeatPad2 = psPacket.data[11] << 8; | |
g_tempHeatPad2 |= psPacket.data[12]; | |
BlinkLed(RX_OK_LED_PIN); | |
} // packet is okay | |
} // got packet | |
// Re-enable wireless reception interrupt | |
attachInterrupt(0, radioSignalsInterrupt, FALLING); | |
} // end packet is avail | |
// If we haven't gotten any panStamp packets in 15 seconds, set TxOK flag to false and clear variables, otherwise to true | |
if (long(millis() - gotpsPacketTime) > 15000L) | |
{ | |
g_TxOK = false; | |
// clear data | |
g_isHeaterOn = false; | |
g_rainPulseCount = 0; | |
g_tempOut = 0; | |
g_tempIn = 0; | |
g_tempHeatPad1 = 0; | |
g_tempHeatPad2 = 0; | |
} | |
else | |
{ g_TxOK = true; } | |
// Upload to Xively | |
if ((long)(millis() - upload_timer) > 0 ) | |
{ | |
#ifdef ENABLE_ETHERNET | |
uploadRainCollector(g_TxOK); | |
#endif | |
upload_timer = millis() + UPDATE_INTERVAL; | |
} | |
#ifdef WDT | |
wdt_reset(); // Reset watchdog timer | |
#endif | |
// Reboot if too many failures | |
if(g_xively_failures > 10) | |
{ | |
#ifdef PRINT_DEBUG | |
Serial.println(F("Reboot: failures > 10 \n\r")); | |
delay(500); // time to print before reboot | |
#endif | |
#ifdef WDT | |
WDT_ForceTimeout(); | |
#else | |
software_Reset(); | |
#endif | |
} | |
// Reboot if no successful updates in 10 minutes | |
if((long) (millis() - g_uploadTimout_timer) >= 0) | |
{ | |
#ifdef PRINT_DEBUG | |
Serial.println(F("Reboot: No successful uploads in 10 minutes \n\r")); | |
g_uploadTimout_timer = millis() + UPDATE_TIMEOUT; | |
delay(500); // time to print before reboot | |
#endif | |
#ifdef WDT | |
WDT_ForceTimeout(); | |
#else | |
software_Reset(); | |
#endif | |
} | |
} // end loop() | |
// Upload rain collector data to Xively | |
int uploadRainCollector(bool gotRainData) | |
{ | |
// If we got the rain data from outside rain collector, then send it to Xively | |
if( gotRainData ) | |
{ g_panStampSuccesses++; } | |
else | |
{ | |
#ifdef PRINT_DEBUG | |
Serial.println(F("Not receiving data from ouside")); | |
#endif | |
} | |
dataout_Rain.updateData(0, (float) (g_rainPulseCount / 100.0)); // Rain - convert to inches | |
dataout_Rain.updateData(1, g_isHeaterOn); // Heater on/off status | |
dataout_Rain.updateData(2, g_tempHeatPad1); // Heating pad 1 temp | |
dataout_Rain.updateData(3, g_tempHeatPad2); // Heating pad 2 temp | |
//dataout_Rain.updateData(4, tempH3); // Heating pad 3 temp - future | |
dataout_Rain.updateData(5, g_tempIn); // Temp inside rain collector | |
dataout_Rain.updateData(6, (int) g_tempOut); // Outside temp | |
//dataout_Rain.updateData(7, rainData[]); // Spare | |
dataout_Rain.updateData(8, g_xively_successes); // Xively upload successes | |
dataout_Rain.updateData(9, g_xively_failures); // Xively upload failures | |
dataout_Rain.updateData(10, g_panStampSuccesses); // panStamp TxRx successes | |
int xively_upload_status = dataout_Rain.updatePachube(); // send data to Xively | |
#ifdef PRINT_DEBUG | |
if (xively_upload_status == 200) | |
{ PrintDataStream(dataout_Rain); } | |
#endif | |
checkXivelyStatus(xively_upload_status); // prints errors, updates success/failure counters | |
return xively_upload_status; | |
} // end uploadRainCollector() | |
void checkXivelyStatus(int statusXively) | |
{ | |
switch (statusXively) | |
{ | |
case 0: | |
Serial.println(F("Unknown Error")); | |
g_xively_failures++; | |
Serial.print(F("Failures = ")); | |
Serial.println(g_xively_failures); | |
break; | |
case 1: | |
Serial.println(F("Can't connect to server")); | |
g_xively_failures++; | |
Serial.print(F("Failures = ")); | |
Serial.println(g_xively_failures); | |
break; | |
case 3: | |
Serial.println(F("Data stream is empty")); | |
g_xively_failures++; | |
Serial.print(F("Failures = ")); | |
Serial.println(g_xively_failures); | |
break; | |
case 200: // success! | |
// Serial.println(F("Upload succeeded")); | |
g_uploadTimout_timer = millis() + UPDATE_TIMEOUT; // Reset upload timout timer | |
g_xively_successes++; | |
g_xively_failures = 0; | |
BlinkLed(TX_OK_LED_PIN); | |
#ifdef WDT | |
wdt_reset(); | |
#endif | |
break; | |
default: | |
Serial.print(F("Unknown status: ")); | |
Serial.println(statusXively); | |
g_xively_failures++; | |
Serial.print(F("Failures = ")); | |
Serial.println(g_xively_failures); | |
break; | |
} | |
} // end checkXivelyStatus | |
void BlinkLed(byte ledPin) | |
{ | |
digitalWrite(ledPin, HIGH); | |
delay(200); | |
digitalWrite(ledPin, LOW); | |
} // end BlinkLed() | |
// Print data uploaded to Xively | |
void PrintDataStream(const ERxPachube& pachube) | |
{ | |
unsigned int count = pachube.countDatastreams(); | |
Serial.println(); | |
Serial.print(F("ID:\t")); | |
for(unsigned int i = 0; i < count; i++) | |
{ | |
Serial.print(pachube.getIdByIndex(i)); | |
Serial.print(F("\t")); | |
if (i == 0 ) | |
{ Serial.print(F("\t")); } | |
} | |
Serial.println(); | |
Serial.print(F("Val:\t")); | |
for(unsigned int i = 0; i < count; i++) | |
{ | |
Serial.print(pachube.getValueByIndex(i)); | |
Serial.print(F("\t")); | |
} | |
Serial.println(); | |
} // end PrintDataStream() | |
void printpanStampDeviceInfo() | |
{ | |
// Print device setup info | |
Serial.print(F("Radio Frequency = ")); | |
if(radio.carrierFreq == CFREQ_868) | |
{ Serial.println(F("868 Mhz")); } | |
else | |
{ Serial.println(F("915 Mhz")); } | |
Serial.print(F("Channel = ")); | |
Serial.println(radio.channel); | |
Serial.print(F("Network address = ")); | |
Serial.println(radio.syncWord[0]); | |
Serial.print(F("Device address = ")); | |
Serial.println(radio.devAddress); | |
} // end printpanStampDeviceInfo() | |
// Restarts program from beginning but does not reset the peripherals and registers | |
// Reference: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1241733710 | |
void software_Reset() | |
{ | |
asm volatile (" jmp 0"); | |
} // end software_Reset() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment