Project for PWM synchronized by GPS
Dependencies: GPS MODSERIAL PowerControl mbed
main.cpp
- Committer:
- Deurklink
- Date:
- 2014-03-10
- Revision:
- 0:bc3d86a76707
File content as of revision 0:bc3d86a76707:
#include <mbed.h> #include "GPS.h" #include <string> #include "EthernetPowerControl.h" #include "MODSERIAL.h" #define XBEETIMEOUT 5 //MODSERIAL pc(USBTX,USBRX); MODSERIAL XBee(p13,p14); char RxBuffer[256]; bool PWMon = false; bool RxTO = false; GPS gps(p9,p10); int TimingOffset; int BeaconNumber; // Digital pins for setting the Timing offset DigitalIn T1(p11); DigitalIn T2(p12); DigitalIn T3(p15); DigitalIn T4(p16); DigitalIn T5(p17); DigitalIn T6(p18); DigitalIn T7(p19); DigitalIn T8(p20); // Digital pins for setting the beacon number DigitalIn B1(p24); DigitalIn B2(p23); DigitalIn B3(p22); DigitalIn B4(p21); // mBed LED 1 DigitalOut L1(LED1); int PulseFrequency = 25; //Hz int Pulselength = 1000; //usec int PWMclock; int Period; InterruptIn PPS(p5); // PPS pin interrupt void ppsSync(){ // Toggle LED1 L1 = !L1; if (PWMon == true){ // Reset PWM timer value so that new cycle immediately starts LPC_PWM1->TC = Period; } } Timeout _RxTimeOut; // XBee Receive Timeout void rxTimeOut(){ RxTO = true; } //------------------------------------DIP-SWITCHES--------------------------- void 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 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); } //--------------------------------------------------------------------------- //------------------------------------PWM------------------------------------ void startPWM(){ // enable PWM mode and counting LPC_PWM1->TCR = (1 << 3) | 1; PWMon = true; } void stopPWM(){ // Reset PWM-counter; this also stops it LPC_PWM1->TCR = 2; PWMon = false; } void 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------------------------------------ void printStatus(){ // Print the status of a Beacon XBee.printf("\r\n\nBeacon no.: %d; TimingOffset: %d",BeaconNumber, TimingOffset); 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 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(&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 %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 %d rx buffer overflow",BeaconNumber); return; } // Timeout if no '#' is received within XBEETIMEOUT seconds if (RxTO == true){ wait(BeaconNumber); XBee.printf("\r\nBeacon %d rx time out",BeaconNumber); XBee.printf("\r\nReceived: %s",RxBuffer); return; } } } void parseXBee(){ // This function collects data from RxBuffer[] and reads it // put data into RxBuffer[] getXBeeData(); // $STATUS# if (strncmp(RxBuffer, "STATUS",6) == 0){ wait(BeaconNumber); printStatus(); } // $STARTPULSE# else if (strncmp(RxBuffer, "STARTPULSE",10) == 0){ // Only start PWM if GPS module has a fix if (gps.fixtype > 0){ startPWM(); wait(BeaconNumber); XBee.printf("\r\nBeacon %d pulses started",BeaconNumber); } else{ wait(BeaconNumber); XBee.printf("\r\nBeacon %d has no GPS fix",BeaconNumber); } } // $STOPPULSE# else if (strncmp(RxBuffer, "STOPPULSE",10) == 0){ if (PWMon == true){ stopPWM(); wait(BeaconNumber); XBee.printf("\r\nBeacon %d pulses stopped",BeaconNumber); } else{ wait(BeaconNumber); XBee.printf("\r\nBeacon %d has not been started yet. No action",BeaconNumber); } } // $CHANGEPULSE,freq(hz),pulselength(us)# 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 %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 %d pulselength or frequency not received correctly, please try again (CHANGEPULSE,freq,pulselength)",BeaconNumber); } } else{ wait(BeaconNumber); XBee.printf("\r\nBeacon %d did not understand message",BeaconNumber); XBee.printf("\r\nReceived: %s",RxBuffer); } // Flush buffer for (int i=0;i<255;i++){ RxBuffer[i] = '0'; } } //-----------------------------------/XBee------------------------------------ int main(void){ // Power down ethernet module PHY_PowerDown(); // Initialize dipswitches initDipSwitch(); // Read beacon number and timing offset readDipSwitch(); // Set baud rate XBee.baud(9600); XBee.printf("\r\n.. Beacon %d Initializing ..\n",BeaconNumber); // Initialize GPS unit gps.Init(); //Attach interrupt to rising edge of GPS PPS pin PPS.rise(&ppsSync); // Initialize PWM resetPWM(PulseFrequency, Pulselength); //pc.printf("\r\n.. Beacon %d Initialization finished ..\n",BeaconNumber); XBee.printf("\r\n.. Beacon %d Initialization finished ..\n",BeaconNumber); while(1){ // Parse GPS data until data is received on XBee serial port if (XBee.readable()){ parseXBee(); } gps.parseData(); readDipSwitch(); } }