Project for PWM synchronized by GPS
Dependencies: GPS MODSERIAL PowerControl mbed
Revision 0:bc3d86a76707, committed 2014-03-10
- Comitter:
- Deurklink
- Date:
- Mon Mar 10 15:09:21 2014 +0000
- Commit message:
- x
Changed in this revision
diff -r 000000000000 -r bc3d86a76707 GPS.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GPS.lib Mon Mar 10 15:09:21 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/Deurklink/code/GPS/#85068b8c3f50
diff -r 000000000000 -r bc3d86a76707 MODSERIAL.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MODSERIAL.lib Mon Mar 10 15:09:21 2014 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/AjK/code/MODSERIAL/#ae0408ebdd68
diff -r 000000000000 -r bc3d86a76707 PowerControl.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PowerControl.lib Mon Mar 10 15:09:21 2014 +0000 @@ -0,0 +1,1 @@ +https://mbed.org/users/JST2011/code/PowerControl/#d0fa2aeb02a4
diff -r 000000000000 -r bc3d86a76707 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Mar 10 15:09:21 2014 +0000 @@ -0,0 +1,313 @@ +#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(); + + } +} \ No newline at end of file
diff -r 000000000000 -r bc3d86a76707 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Mar 10 15:09:21 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/824293ae5e43 \ No newline at end of file