Project for PWM synchronized by GPS

Dependencies:   GPS MODSERIAL PowerControl mbed

Committer:
Deurklink
Date:
Mon Mar 10 15:09:21 2014 +0000
Revision:
0:bc3d86a76707
x

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Deurklink 0:bc3d86a76707 1 #include <mbed.h>
Deurklink 0:bc3d86a76707 2 #include "GPS.h"
Deurklink 0:bc3d86a76707 3 #include <string>
Deurklink 0:bc3d86a76707 4 #include "EthernetPowerControl.h"
Deurklink 0:bc3d86a76707 5 #include "MODSERIAL.h"
Deurklink 0:bc3d86a76707 6
Deurklink 0:bc3d86a76707 7 #define XBEETIMEOUT 5
Deurklink 0:bc3d86a76707 8
Deurklink 0:bc3d86a76707 9 //MODSERIAL pc(USBTX,USBRX);
Deurklink 0:bc3d86a76707 10 MODSERIAL XBee(p13,p14);
Deurklink 0:bc3d86a76707 11 char RxBuffer[256];
Deurklink 0:bc3d86a76707 12 bool PWMon = false;
Deurklink 0:bc3d86a76707 13 bool RxTO = false;
Deurklink 0:bc3d86a76707 14
Deurklink 0:bc3d86a76707 15 GPS gps(p9,p10);
Deurklink 0:bc3d86a76707 16
Deurklink 0:bc3d86a76707 17
Deurklink 0:bc3d86a76707 18 int TimingOffset;
Deurklink 0:bc3d86a76707 19 int BeaconNumber;
Deurklink 0:bc3d86a76707 20
Deurklink 0:bc3d86a76707 21 // Digital pins for setting the Timing offset
Deurklink 0:bc3d86a76707 22 DigitalIn T1(p11);
Deurklink 0:bc3d86a76707 23 DigitalIn T2(p12);
Deurklink 0:bc3d86a76707 24 DigitalIn T3(p15);
Deurklink 0:bc3d86a76707 25 DigitalIn T4(p16);
Deurklink 0:bc3d86a76707 26 DigitalIn T5(p17);
Deurklink 0:bc3d86a76707 27 DigitalIn T6(p18);
Deurklink 0:bc3d86a76707 28 DigitalIn T7(p19);
Deurklink 0:bc3d86a76707 29 DigitalIn T8(p20);
Deurklink 0:bc3d86a76707 30
Deurklink 0:bc3d86a76707 31 // Digital pins for setting the beacon number
Deurklink 0:bc3d86a76707 32 DigitalIn B1(p24);
Deurklink 0:bc3d86a76707 33 DigitalIn B2(p23);
Deurklink 0:bc3d86a76707 34 DigitalIn B3(p22);
Deurklink 0:bc3d86a76707 35 DigitalIn B4(p21);
Deurklink 0:bc3d86a76707 36
Deurklink 0:bc3d86a76707 37 // mBed LED 1
Deurklink 0:bc3d86a76707 38 DigitalOut L1(LED1);
Deurklink 0:bc3d86a76707 39
Deurklink 0:bc3d86a76707 40 int PulseFrequency = 25; //Hz
Deurklink 0:bc3d86a76707 41 int Pulselength = 1000; //usec
Deurklink 0:bc3d86a76707 42 int PWMclock;
Deurklink 0:bc3d86a76707 43 int Period;
Deurklink 0:bc3d86a76707 44
Deurklink 0:bc3d86a76707 45 InterruptIn PPS(p5);
Deurklink 0:bc3d86a76707 46
Deurklink 0:bc3d86a76707 47 // PPS pin interrupt
Deurklink 0:bc3d86a76707 48 void ppsSync(){
Deurklink 0:bc3d86a76707 49 // Toggle LED1
Deurklink 0:bc3d86a76707 50 L1 = !L1;
Deurklink 0:bc3d86a76707 51 if (PWMon == true){
Deurklink 0:bc3d86a76707 52 // Reset PWM timer value so that new cycle immediately starts
Deurklink 0:bc3d86a76707 53 LPC_PWM1->TC = Period;
Deurklink 0:bc3d86a76707 54 }
Deurklink 0:bc3d86a76707 55 }
Deurklink 0:bc3d86a76707 56
Deurklink 0:bc3d86a76707 57 Timeout _RxTimeOut;
Deurklink 0:bc3d86a76707 58
Deurklink 0:bc3d86a76707 59 // XBee Receive Timeout
Deurklink 0:bc3d86a76707 60 void rxTimeOut(){
Deurklink 0:bc3d86a76707 61 RxTO = true;
Deurklink 0:bc3d86a76707 62 }
Deurklink 0:bc3d86a76707 63
Deurklink 0:bc3d86a76707 64
Deurklink 0:bc3d86a76707 65 //------------------------------------DIP-SWITCHES---------------------------
Deurklink 0:bc3d86a76707 66 void readDipSwitch(){
Deurklink 0:bc3d86a76707 67 // Transform the dip switch binary numbers into integers
Deurklink 0:bc3d86a76707 68 // For the timing offset, the leftmost bit is the sign bit (2's complement)
Deurklink 0:bc3d86a76707 69 TimingOffset = -128*T1 + 64*T2 + 32*T3 + 16*T4 + 8*T5 + 4*T6 + 2*T7 + T8;
Deurklink 0:bc3d86a76707 70 BeaconNumber = 8*B1 + 4*B2 + 2*B3 + B4;
Deurklink 0:bc3d86a76707 71 }
Deurklink 0:bc3d86a76707 72
Deurklink 0:bc3d86a76707 73 void initDipSwitch(){
Deurklink 0:bc3d86a76707 74 // Set pull-down resistor for dip switch inputs
Deurklink 0:bc3d86a76707 75 T1.mode(PullDown);
Deurklink 0:bc3d86a76707 76 T2.mode(PullDown);
Deurklink 0:bc3d86a76707 77 T3.mode(PullDown);
Deurklink 0:bc3d86a76707 78 T4.mode(PullDown);
Deurklink 0:bc3d86a76707 79 T5.mode(PullDown);
Deurklink 0:bc3d86a76707 80 T6.mode(PullDown);
Deurklink 0:bc3d86a76707 81 T7.mode(PullDown);
Deurklink 0:bc3d86a76707 82 T8.mode(PullDown);
Deurklink 0:bc3d86a76707 83
Deurklink 0:bc3d86a76707 84 B1.mode(PullDown);
Deurklink 0:bc3d86a76707 85 B2.mode(PullDown);
Deurklink 0:bc3d86a76707 86 B3.mode(PullDown);
Deurklink 0:bc3d86a76707 87 B4.mode(PullDown);
Deurklink 0:bc3d86a76707 88 }
Deurklink 0:bc3d86a76707 89 //---------------------------------------------------------------------------
Deurklink 0:bc3d86a76707 90
Deurklink 0:bc3d86a76707 91
Deurklink 0:bc3d86a76707 92 //------------------------------------PWM------------------------------------
Deurklink 0:bc3d86a76707 93 void startPWM(){
Deurklink 0:bc3d86a76707 94 // enable PWM mode and counting
Deurklink 0:bc3d86a76707 95 LPC_PWM1->TCR = (1 << 3) | 1;
Deurklink 0:bc3d86a76707 96 PWMon = true;
Deurklink 0:bc3d86a76707 97 }
Deurklink 0:bc3d86a76707 98
Deurklink 0:bc3d86a76707 99 void stopPWM(){
Deurklink 0:bc3d86a76707 100 // Reset PWM-counter; this also stops it
Deurklink 0:bc3d86a76707 101 LPC_PWM1->TCR = 2;
Deurklink 0:bc3d86a76707 102 PWMon = false;
Deurklink 0:bc3d86a76707 103 }
Deurklink 0:bc3d86a76707 104
Deurklink 0:bc3d86a76707 105 void resetPWM(int _PulseFrequency, int _Pulselength){
Deurklink 0:bc3d86a76707 106 // Note: wherever you read pin P2.0, it is pin 2[0] of the microcontroller.
Deurklink 0:bc3d86a76707 107 // This is wired to p26 of the mbed board.
Deurklink 0:bc3d86a76707 108 stopPWM();
Deurklink 0:bc3d86a76707 109 // First stop PWM if it is running
Deurklink 0:bc3d86a76707 110
Deurklink 0:bc3d86a76707 111 PWMclock = SystemCoreClock / 96;
Deurklink 0:bc3d86a76707 112 Period = PWMclock / _PulseFrequency;
Deurklink 0:bc3d86a76707 113
Deurklink 0:bc3d86a76707 114
Deurklink 0:bc3d86a76707 115 LPC_SC->PCONP |= 1 << 6;
Deurklink 0:bc3d86a76707 116 // Reset mode PWM timer
Deurklink 0:bc3d86a76707 117 LPC_PWM1->TCR = 2;
Deurklink 0:bc3d86a76707 118
Deurklink 0:bc3d86a76707 119 // configure P2.0 for PWM1.1 - O - Pulse Width Modulator 1, channel 1 output.
Deurklink 0:bc3d86a76707 120 LPC_PINCON->PINSEL4 = (LPC_PINCON->PINSEL4 & ~(0x3 << 0)) | (0x1 << 0);
Deurklink 0:bc3d86a76707 121
Deurklink 0:bc3d86a76707 122 // Disable pullups for P2.0
Deurklink 0:bc3d86a76707 123 LPC_PINCON->PINMODE4 = (LPC_PINCON->PINMODE4 & ~0x3) | 0x2;
Deurklink 0:bc3d86a76707 124
Deurklink 0:bc3d86a76707 125 // Set prescaler
Deurklink 0:bc3d86a76707 126 //LPC_PWM1->PR = SystemCoreClock / (4 * 1000000) - 1;
Deurklink 0:bc3d86a76707 127
Deurklink 0:bc3d86a76707 128 // Set up match registers
Deurklink 0:bc3d86a76707 129 LPC_PWM1->MR0 = Period*24+TimingOffset; // Set MR0 (Period)
Deurklink 0:bc3d86a76707 130 /*
Deurklink 0:bc3d86a76707 131 TimingOffset is there to compensate for crystal errors.
Deurklink 0:bc3d86a76707 132 It has to be calculated for every mbed, as every crystal is a little different
Deurklink 0:bc3d86a76707 133 It basically adds or detracts a few cycles from every period to keep the period equal for every module
Deurklink 0:bc3d86a76707 134 */
Deurklink 0:bc3d86a76707 135 LPC_PWM1->MR1 = _Pulselength*24; // Set MR1 (Pulse length)
Deurklink 0:bc3d86a76707 136 LPC_PWM1->LER = 0x07; // set latch-enable register
Deurklink 0:bc3d86a76707 137 LPC_PWM1->MCR |= 0x02; // Reset PWM1 on match
Deurklink 0:bc3d86a76707 138 LPC_PWM1->PCR = 1 << 9; // enable PWM1 with single-edge operation
Deurklink 0:bc3d86a76707 139 }
Deurklink 0:bc3d86a76707 140 //------------------------------------/PWM------------------------------------
Deurklink 0:bc3d86a76707 141
Deurklink 0:bc3d86a76707 142
Deurklink 0:bc3d86a76707 143
Deurklink 0:bc3d86a76707 144 //------------------------------------XBee------------------------------------
Deurklink 0:bc3d86a76707 145
Deurklink 0:bc3d86a76707 146 void printStatus(){
Deurklink 0:bc3d86a76707 147 // Print the status of a Beacon
Deurklink 0:bc3d86a76707 148 XBee.printf("\r\n\nBeacon no.: %d; TimingOffset: %d",BeaconNumber, TimingOffset);
Deurklink 0:bc3d86a76707 149 XBee.printf("\r\nLast GPS update: %d:%d:%2.2f",gps.hours, gps.minutes, gps.seconds);
Deurklink 0:bc3d86a76707 150 XBee.printf("\r\nFlash frequency: %d Hz; Pulse length: %d usec", PulseFrequency, Pulselength);
Deurklink 0:bc3d86a76707 151 XBee.printf("\r\nPulse generation: %d (0=off,1=on)",PWMon);
Deurklink 0:bc3d86a76707 152 XBee.printf("\r\nGPS location: %f,%f", gps.latitude, gps.longitude);
Deurklink 0:bc3d86a76707 153 XBee.printf("\r\nFixtype: %d (0=no fix,1=gps,2=differential)",gps.fixtype);
Deurklink 0:bc3d86a76707 154 XBee.printf("\r\nNo. of satellites: %d",gps.satellites);
Deurklink 0:bc3d86a76707 155 }
Deurklink 0:bc3d86a76707 156
Deurklink 0:bc3d86a76707 157 void getXBeeData(){
Deurklink 0:bc3d86a76707 158 // Function used by parse data function
Deurklink 0:bc3d86a76707 159 // Read data from the Xbee serial Buffer
Deurklink 0:bc3d86a76707 160 // Wait until $ is read, then put characters received after that in RxBuffer[] until # is read.
Deurklink 0:bc3d86a76707 161
Deurklink 0:bc3d86a76707 162 RxTO = false; // Reset time-out
Deurklink 0:bc3d86a76707 163 bool dollarSignRcv = false;
Deurklink 0:bc3d86a76707 164 bool dashRcv = false;
Deurklink 0:bc3d86a76707 165
Deurklink 0:bc3d86a76707 166 _RxTimeOut.attach(&rxTimeOut,XBEETIMEOUT); // timeout after XBEETIMEOUT seconds
Deurklink 0:bc3d86a76707 167
Deurklink 0:bc3d86a76707 168 while(!dollarSignRcv){
Deurklink 0:bc3d86a76707 169 // Read XBee until dollarsign received or timeout
Deurklink 0:bc3d86a76707 170 if (XBee.readable()){
Deurklink 0:bc3d86a76707 171 if (XBee.getc() == '$'){
Deurklink 0:bc3d86a76707 172 dollarSignRcv = true;
Deurklink 0:bc3d86a76707 173 //XBee.printf("$ received");
Deurklink 0:bc3d86a76707 174 }
Deurklink 0:bc3d86a76707 175 }
Deurklink 0:bc3d86a76707 176 // Timeout if no $ is received within XBEETIMEOUT seconds
Deurklink 0:bc3d86a76707 177 if (RxTO == true){
Deurklink 0:bc3d86a76707 178 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 179 XBee.printf("\r\nBeacon %d rx time out",BeaconNumber);
Deurklink 0:bc3d86a76707 180 return;
Deurklink 0:bc3d86a76707 181 }
Deurklink 0:bc3d86a76707 182 }
Deurklink 0:bc3d86a76707 183
Deurklink 0:bc3d86a76707 184 int i = 0;
Deurklink 0:bc3d86a76707 185 while(!dashRcv){
Deurklink 0:bc3d86a76707 186 // Fill buffer until dash is received, buffer is full or timeout
Deurklink 0:bc3d86a76707 187 if (XBee.readable()){
Deurklink 0:bc3d86a76707 188 RxBuffer[i] = XBee.getc();
Deurklink 0:bc3d86a76707 189 if(RxBuffer[i] == '#') {
Deurklink 0:bc3d86a76707 190 RxBuffer[i] = 0;
Deurklink 0:bc3d86a76707 191 dashRcv = true;
Deurklink 0:bc3d86a76707 192 //XBee.printf("# received");
Deurklink 0:bc3d86a76707 193 }
Deurklink 0:bc3d86a76707 194 i++;
Deurklink 0:bc3d86a76707 195 }
Deurklink 0:bc3d86a76707 196 // Return if buffer is full
Deurklink 0:bc3d86a76707 197 if (i > 255){
Deurklink 0:bc3d86a76707 198 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 199 XBee.printf("\r\nBeacon %d rx buffer overflow",BeaconNumber);
Deurklink 0:bc3d86a76707 200 return;
Deurklink 0:bc3d86a76707 201 }
Deurklink 0:bc3d86a76707 202 // Timeout if no '#' is received within XBEETIMEOUT seconds
Deurklink 0:bc3d86a76707 203 if (RxTO == true){
Deurklink 0:bc3d86a76707 204 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 205 XBee.printf("\r\nBeacon %d rx time out",BeaconNumber);
Deurklink 0:bc3d86a76707 206 XBee.printf("\r\nReceived: %s",RxBuffer);
Deurklink 0:bc3d86a76707 207 return;
Deurklink 0:bc3d86a76707 208 }
Deurklink 0:bc3d86a76707 209 }
Deurklink 0:bc3d86a76707 210 }
Deurklink 0:bc3d86a76707 211
Deurklink 0:bc3d86a76707 212 void parseXBee(){
Deurklink 0:bc3d86a76707 213 // This function collects data from RxBuffer[] and reads it
Deurklink 0:bc3d86a76707 214
Deurklink 0:bc3d86a76707 215 // put data into RxBuffer[]
Deurklink 0:bc3d86a76707 216 getXBeeData();
Deurklink 0:bc3d86a76707 217 // $STATUS#
Deurklink 0:bc3d86a76707 218 if (strncmp(RxBuffer, "STATUS",6) == 0){
Deurklink 0:bc3d86a76707 219 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 220 printStatus();
Deurklink 0:bc3d86a76707 221 }
Deurklink 0:bc3d86a76707 222
Deurklink 0:bc3d86a76707 223 // $STARTPULSE#
Deurklink 0:bc3d86a76707 224 else if (strncmp(RxBuffer, "STARTPULSE",10) == 0){
Deurklink 0:bc3d86a76707 225 // Only start PWM if GPS module has a fix
Deurklink 0:bc3d86a76707 226 if (gps.fixtype > 0){
Deurklink 0:bc3d86a76707 227 startPWM();
Deurklink 0:bc3d86a76707 228 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 229 XBee.printf("\r\nBeacon %d pulses started",BeaconNumber);
Deurklink 0:bc3d86a76707 230 }
Deurklink 0:bc3d86a76707 231 else{
Deurklink 0:bc3d86a76707 232 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 233 XBee.printf("\r\nBeacon %d has no GPS fix",BeaconNumber);
Deurklink 0:bc3d86a76707 234 }
Deurklink 0:bc3d86a76707 235 }
Deurklink 0:bc3d86a76707 236
Deurklink 0:bc3d86a76707 237 // $STOPPULSE#
Deurklink 0:bc3d86a76707 238 else if (strncmp(RxBuffer, "STOPPULSE",10) == 0){
Deurklink 0:bc3d86a76707 239 if (PWMon == true){
Deurklink 0:bc3d86a76707 240 stopPWM();
Deurklink 0:bc3d86a76707 241 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 242 XBee.printf("\r\nBeacon %d pulses stopped",BeaconNumber);
Deurklink 0:bc3d86a76707 243 }
Deurklink 0:bc3d86a76707 244 else{
Deurklink 0:bc3d86a76707 245 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 246 XBee.printf("\r\nBeacon %d has not been started yet. No action",BeaconNumber);
Deurklink 0:bc3d86a76707 247 }
Deurklink 0:bc3d86a76707 248 }
Deurklink 0:bc3d86a76707 249
Deurklink 0:bc3d86a76707 250 // $CHANGEPULSE,freq(hz),pulselength(us)#
Deurklink 0:bc3d86a76707 251 else if (strncmp(RxBuffer, "CHANGEPULSE",11) == 0){
Deurklink 0:bc3d86a76707 252 if(sscanf(RxBuffer, "%*s %d %d", &PulseFrequency, &Pulselength) ==2){
Deurklink 0:bc3d86a76707 253 resetPWM(PulseFrequency, Pulselength);
Deurklink 0:bc3d86a76707 254 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 255 XBee.printf("\r\nBeacon %d frequency set to: %d Hz. Pulselength set to %d us",BeaconNumber,PulseFrequency,Pulselength);
Deurklink 0:bc3d86a76707 256 XBee.printf("\r\nWaiting for start pulse command");
Deurklink 0:bc3d86a76707 257 }
Deurklink 0:bc3d86a76707 258 else{
Deurklink 0:bc3d86a76707 259 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 260 XBee.printf("\r\nBeacon %d pulselength or frequency not received correctly, please try again (CHANGEPULSE,freq,pulselength)",BeaconNumber);
Deurklink 0:bc3d86a76707 261 }
Deurklink 0:bc3d86a76707 262 }
Deurklink 0:bc3d86a76707 263 else{
Deurklink 0:bc3d86a76707 264 wait(BeaconNumber);
Deurklink 0:bc3d86a76707 265 XBee.printf("\r\nBeacon %d did not understand message",BeaconNumber);
Deurklink 0:bc3d86a76707 266 XBee.printf("\r\nReceived: %s",RxBuffer);
Deurklink 0:bc3d86a76707 267 }
Deurklink 0:bc3d86a76707 268 // Flush buffer
Deurklink 0:bc3d86a76707 269 for (int i=0;i<255;i++){
Deurklink 0:bc3d86a76707 270 RxBuffer[i] = '0';
Deurklink 0:bc3d86a76707 271 }
Deurklink 0:bc3d86a76707 272 }
Deurklink 0:bc3d86a76707 273 //-----------------------------------/XBee------------------------------------
Deurklink 0:bc3d86a76707 274
Deurklink 0:bc3d86a76707 275
Deurklink 0:bc3d86a76707 276 int main(void){
Deurklink 0:bc3d86a76707 277 // Power down ethernet module
Deurklink 0:bc3d86a76707 278 PHY_PowerDown();
Deurklink 0:bc3d86a76707 279
Deurklink 0:bc3d86a76707 280 // Initialize dipswitches
Deurklink 0:bc3d86a76707 281 initDipSwitch();
Deurklink 0:bc3d86a76707 282
Deurklink 0:bc3d86a76707 283 // Read beacon number and timing offset
Deurklink 0:bc3d86a76707 284 readDipSwitch();
Deurklink 0:bc3d86a76707 285
Deurklink 0:bc3d86a76707 286 // Set baud rate
Deurklink 0:bc3d86a76707 287 XBee.baud(9600);
Deurklink 0:bc3d86a76707 288
Deurklink 0:bc3d86a76707 289 XBee.printf("\r\n.. Beacon %d Initializing ..\n",BeaconNumber);
Deurklink 0:bc3d86a76707 290
Deurklink 0:bc3d86a76707 291 // Initialize GPS unit
Deurklink 0:bc3d86a76707 292 gps.Init();
Deurklink 0:bc3d86a76707 293
Deurklink 0:bc3d86a76707 294 //Attach interrupt to rising edge of GPS PPS pin
Deurklink 0:bc3d86a76707 295 PPS.rise(&ppsSync);
Deurklink 0:bc3d86a76707 296
Deurklink 0:bc3d86a76707 297 // Initialize PWM
Deurklink 0:bc3d86a76707 298 resetPWM(PulseFrequency, Pulselength);
Deurklink 0:bc3d86a76707 299
Deurklink 0:bc3d86a76707 300 //pc.printf("\r\n.. Beacon %d Initialization finished ..\n",BeaconNumber);
Deurklink 0:bc3d86a76707 301 XBee.printf("\r\n.. Beacon %d Initialization finished ..\n",BeaconNumber);
Deurklink 0:bc3d86a76707 302
Deurklink 0:bc3d86a76707 303 while(1){
Deurklink 0:bc3d86a76707 304 // Parse GPS data until data is received on XBee serial port
Deurklink 0:bc3d86a76707 305
Deurklink 0:bc3d86a76707 306 if (XBee.readable()){
Deurklink 0:bc3d86a76707 307 parseXBee();
Deurklink 0:bc3d86a76707 308 }
Deurklink 0:bc3d86a76707 309 gps.parseData();
Deurklink 0:bc3d86a76707 310 readDipSwitch();
Deurklink 0:bc3d86a76707 311
Deurklink 0:bc3d86a76707 312 }
Deurklink 0:bc3d86a76707 313 }