-
Dependents: GPSXbee_1_1 GPSXbee_1_0
Beacon.cpp
- Committer:
- Deurklink
- Date:
- 2014-12-16
- Revision:
- 1:d4cbfcb2be46
- Parent:
- 0:8b33ba38cc3a
File content as of revision 1:d4cbfcb2be46:
#include "Beacon.h" Beacon::Beacon(PinName gpsTx, PinName gpsRx, PinName xbTx, PinName xbRx, int freq, int len) : gps(gpsTx, gpsRx), sd(p5, p6, p7, p8, "sd"), L1(LED1), L2(LED2), L3(LED3), L4(LED4), XBee(xbTx, xbRx), PPS(p30), CD(p25), T1(p11), T2(p12), T3(p15), T4(p16), T5(p17), T6(p18), T7(p19), T8(p20), B1(p24), B2(p23), B3(p22), B4(p21), PulseFrequency(freq), Pulselength(len) { PWMon = false; RxTO = false; PulseFrequency = 25; //Hz Pulselength = 1000; //usec SDEnabled = false; } // Beacon initialisation bool Beacon::init(){ // Power down ethernet module PHY_PowerDown(); // Initialize dipswitches initDipSwitch(); // Read beacon number and timing offset readDipSwitch(); SDEnabled = initSD(); // Set baud rate XBee.baud(9600); // Initialize GPS unit gps.Init(); //Attach interrupt to rising edge of GPS PPS pin PPS.rise(this, &Beacon::ppsSync); // Initialize PWM resetPWM(PulseFrequency, Pulselength); return true; } // PPS pin interrupt void Beacon::ppsSync(){ // Toggle LED1 L1 = !L1; if (PWMon == true){ // Reset PWM timer value so that new cycle immediately starts LPC_PWM1->TC = Period*24+TimingOffset - 1; } } // XBee Receive Timeout void Beacon::rxTimeOut(){ RxTO = true; } //------------------------------------DIP-SWITCHES--------------------------- void Beacon::readDipSwitch(){ // Transform the dip switch binary numbers into integers // For the timing offset, the leftmost bit is the sign bit (2's complement) TimingOffset = -128*T1 + 64*T2 + 32*T3 + 16*T4 + 8*T5 + 4*T6 + 2*T7 + T8; BeaconNumber = 8*B1 + 4*B2 + 2*B3 + B4; } void Beacon::initDipSwitch(){ // Set pull-down resistor for dip switch inputs T1.mode(PullDown); T2.mode(PullDown); T3.mode(PullDown); T4.mode(PullDown); T5.mode(PullDown); T6.mode(PullDown); T7.mode(PullDown); T8.mode(PullDown); B1.mode(PullDown); B2.mode(PullDown); B3.mode(PullDown); B4.mode(PullDown); } //--------------------------------------------------------------------------- //------------------------------------SD------------------------------------ bool Beacon::initSD(){ CD.mode(PullUp); if (CD == 1) { L3 = 1; FILE *fp = fopen("/sd/log.txt", "a"); if(fp == NULL) { fclose(fp); return false; } else{ fprintf(fp,"\r\nSTART LOG"); fclose(fp); L4 = 1; return true; } } else{ return false; } } //--------------------------------------------------------------------------- //------------------------------------PWM------------------------------------ void Beacon::startPWM(){ // enable PWM mode and counting LPC_PWM1->TCR = (1 << 3) | 1; PWMon = true; } void Beacon::stopPWM(){ // Reset PWM-counter; this also stops it LPC_PWM1->TCR = 2; PWMon = false; } void Beacon::resetPWM(int _PulseFrequency, int _Pulselength){ // Note: wherever you read pin P2.0, it is pin 2[0] of the microcontroller. // This is wired to p26 of the mbed board. stopPWM(); // First stop PWM if it is running PWMclock = SystemCoreClock / 96; Period = PWMclock / _PulseFrequency; LPC_SC->PCONP |= 1 << 6; // Reset mode PWM timer LPC_PWM1->TCR = 2; // configure P2.0 for PWM1.1 - O - Pulse Width Modulator 1, channel 1 output. LPC_PINCON->PINSEL4 = (LPC_PINCON->PINSEL4 & ~(0x3 << 0)) | (0x1 << 0); // Disable pullups for P2.0 LPC_PINCON->PINMODE4 = (LPC_PINCON->PINMODE4 & ~0x3) | 0x2; // Set prescaler //LPC_PWM1->PR = SystemCoreClock / (4 * 1000000) - 1; // Set up match registers LPC_PWM1->MR0 = Period*24+TimingOffset; // Set MR0 (Period) /* TimingOffset is there to compensate for crystal errors. It has to be calculated for every mbed, as every crystal is a little different It basically adds or detracts a few cycles from every period to keep the period equal for every module */ LPC_PWM1->MR1 = _Pulselength*24; // Set MR1 (Pulse length) LPC_PWM1->LER = 0x07; // set latch-enable register LPC_PWM1->MCR |= 0x02; // Reset PWM1 on match LPC_PWM1->PCR = 1 << 9; // enable PWM1 with single-edge operation } //------------------------------------/PWM------------------------------------ //------------------------------------XBee------------------------------------ bool Beacon::xbeeReadable(){ return XBee.readable(); } void Beacon::printStatus(){ // Print the status of a Beacon XBee.printf("\r\n\nBeacon (ID:%d); TimingOffset: %d",BeaconNumber, TimingOffset); XBee.printf("\r\nLogging enabled: %d (0=off,1=on)",SDEnabled); XBee.printf("\r\nLast GPS update: %d:%d:%2.2f",gps.hours, gps.minutes, gps.seconds); XBee.printf("\r\nFlash frequency: %d Hz; Pulse length: %d usec", PulseFrequency, Pulselength); XBee.printf("\r\nPulse generation: %d (0=off,1=on)",PWMon); XBee.printf("\r\nGPS location: %f,%f", gps.latitude, gps.longitude); XBee.printf("\r\nFixtype: %d (0=no fix,1=gps,2=differential)",gps.fixtype); XBee.printf("\r\nNo. of satellites: %d",gps.satellites); } void Beacon::getXbeeData(){ // Function used by parse data function // Read data from the Xbee serial Buffer // Wait until $ is read, then put characters received after that in RxBuffer[] until # is read. RxTO = false; // Reset time-out bool dollarSignRcv = false; bool dashRcv = false; _RxTimeOut.attach(this,&Beacon::rxTimeOut,XBEETIMEOUT); // timeout after XBEETIMEOUT seconds while(!dollarSignRcv){ // Read XBee until dollarsign received or timeout if (XBee.readable()){ if (XBee.getc() == '$'){ dollarSignRcv = true; //XBee.printf("$ received"); } } // Timeout if no $ is received within XBEETIMEOUT seconds if (RxTO == true){ wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) rx time out",BeaconNumber); return; } } int i = 0; while(!dashRcv){ // Fill buffer until dash is received, buffer is full or timeout if (XBee.readable()){ RxBuffer[i] = XBee.getc(); if(RxBuffer[i] == '#') { RxBuffer[i] = 0; dashRcv = true; //XBee.printf("# received"); } i++; } // Return if buffer is full if (i > 255){ wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) rx buffer overflow",BeaconNumber); return; } // Timeout if no '#' is received within XBEETIMEOUT seconds if (RxTO == true){ wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) rx time out",BeaconNumber); XBee.printf("\r\nReceived: %s",RxBuffer); return; } } } void Beacon::parseXbee(){ // This function collects data from RxBuffer[] and reads it // put data into RxBuffer[] getXbeeData(); // $STATUS# // Send a status message if (strncmp(RxBuffer, "STATUS",6) == 0){ wait(BeaconNumber); printStatus(); } // $STARTPULSE# // Start pulse generation if there is a GPS fix else if (strncmp(RxBuffer, "STARTPULSE",10) == 0){ if (gps.fixtype > 0){ startPWM(); wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) pulses started",BeaconNumber); } else{ wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) has no GPS fix",BeaconNumber); } } // $FORCEPULSE# // Start pulse generation regardless of GPS fix else if (strncmp(RxBuffer, "FORCEPULSE",10) == 0){ startPWM(); if (gps.fixtype > 0){ wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) pulses started",BeaconNumber); } else{ wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) has no GPS fix; pulses started anyway",BeaconNumber); } } // $STOPPULSE# // Stop pulse generation else if (strncmp(RxBuffer, "STOPPULSE",9) == 0){ if (PWMon == true){ stopPWM(); wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) pulses stopped",BeaconNumber); } else{ wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) has not been started yet. No action",BeaconNumber); } } // $CHANGEPULSE,freq(hz),pulselength(us)# // Change frequency and pulse length else if (strncmp(RxBuffer, "CHANGEPULSE",11) == 0){ if(sscanf(RxBuffer, "%*s %d %d", &PulseFrequency, &Pulselength) ==2){ resetPWM(PulseFrequency, Pulselength); wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) frequency set to: %d Hz. Pulselength set to %d us",BeaconNumber,PulseFrequency,Pulselength); XBee.printf("\r\nWaiting for start pulse command"); } else{ wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) pulselength or frequency not received correctly, please try again (CHANGEPULSE,freq,pulselength)",BeaconNumber); } } // $CAMCHANGEPULSE,freq(hz),pulselength(us),delay(us)# // Change frequency and pulse length of camera; Ignored by beacon else if (strncmp(RxBuffer, "CAMCHANGEPULSE",14) == 0){ wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) ignored message",BeaconNumber); } // $RESETPULSE# // Read the dip switches, stop and reset PWM with new timing offset else if (strncmp(RxBuffer, "RESETPULSE",10) == 0){ readDipSwitch(); resetPWM(PulseFrequency, Pulselength); wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) PWM reset",BeaconNumber); } // Received message was not one of the above commands else{ wait(BeaconNumber); XBee.printf("\r\nBeacon (ID:%d) did not understand message",BeaconNumber); XBee.printf("\r\nReceived: %s",RxBuffer); } if (SDEnabled){ FILE *fp = fopen("/sd/log.txt", "a"); fprintf(fp,"\r\n%d:%d:%2.2f Received: %s",gps.hours, gps.minutes, gps.seconds, RxBuffer); fclose(fp); } // Flush buffer for (int i=0;i<255;i++){ RxBuffer[i] = '0'; } } //-----------------------------------/XBee------------------------------------ //------------------------------------GPS------------------------------------- bool Beacon::gpsReadable(){ return gps.readable(); } void Beacon::parseGpsData(){ gps.parseData(); } //-----------------------------------/GPS-------------------------------------