Project for PWM synchronized by GPS

Dependencies:   GPS MODSERIAL PowerControl mbed

Files at this revision

API Documentation at this revision

Comitter:
Deurklink
Date:
Mon Mar 10 15:09:21 2014 +0000
Commit message:
x

Changed in this revision

GPS.lib Show annotated file Show diff for this revision Revisions of this file
MODSERIAL.lib Show annotated file Show diff for this revision Revisions of this file
PowerControl.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /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
--- /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
--- /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
--- /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
--- /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