Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 // Device Drivers for Labmbed Board 00002 00003 #include "mbed.h" 00004 #include "TextLCD.h" 00005 00006 TextLCD lcd(p15, p16, p17, p18, p19, p20); // LCD: RS, E, D4-D7 00007 SPI spi(p5, p6, p7); // SPI: MOSI, MISO, SCLK (MISO not used with LCD) 00008 DigitalOut lat(p8); // data latch for LED driver TLC59281 00009 DigitalOut Sel0(p26); // input select bits: 00010 DigitalOut Sel1(p25); // " 00011 DigitalOut Sel2(p24); // " 00012 DigitalIn In0(p14); // input from switches, keypad etc 00013 DigitalIn In1(p13); // " 00014 DigitalIn In2(p12); // " 00015 DigitalIn In3(p11); // " 00016 I2C i2c(p9, p10); // I2C: SDA, SCL pins 00017 PwmOut servo1(p21); // Servo 1 PWM pin 00018 PwmOut servo2(p22); // Servo 2 PWM pin 00019 DigitalOut Trigger(p28); // Ultrasonic rangefinder trigger pin 00020 DigitalIn Echo(p27); // Ultrasonic rangefinder echo pin 00021 Timer Sonar; // Ultrasonic timer 00022 00023 // global variables 00024 short LEDbits = 0; // global led status used for readback 00025 const int TMP102Addr = 0x92; // TMP102 temperature I2C address 00026 const int MPU6050Addr = 0xd0; // MPU-6050 accelerometer and Gyro I2C address 00027 float Acceleration[3]; // MPU-6050 x,y,z acceleration values in 1G floating point 00028 float GyroRate[3]; // MPU-6050 x,y,z gyrorates in degrees per second 00029 float GyroOffset[3]; // MPU-6050 x,y,z gyrorates compensation 00030 char AReg[] = { 0x3b, 0x3d, 0x3f }; // MPU-6050 I2C x,y,z accelerometer data registers 00031 char GReg[] = { 0x43, 0x45, 0x47 }; // MPU-6050 I2C x,y,z gyro data registers 00032 00033 void Servo1(float s) { // range +-1 00034 s=s+1; 00035 if (s>=0 && s<=2) { 00036 servo1.pulsewidth(s/2000+0.001); 00037 } 00038 } 00039 00040 void Servo2(float s) { // range +-1 00041 s=s+1; 00042 if (s>=0 && s<=2) { 00043 servo2.pulsewidth(s/2000+0.001); 00044 } 00045 } 00046 00047 void InitServos() { 00048 servo1.period(0.02); 00049 servo2.period(0.02); 00050 Servo1(0); // initiate servo 1 to centre position 00051 Servo2(0); // initiate servo 1 to centre position 00052 } 00053 00054 int ReadSonar() { 00055 Trigger = 1; // set sonar trigger pulse high 00056 Sonar.reset(); // reset sonar timer 00057 wait_us(10.0); // 10 us pulse 00058 Trigger = 0; // set sonar trigger pulse low 00059 while (Echo == 0) {}; // wait for echo high (8 cycles have been transmitted) 00060 Sonar.start(); // echo high so start timer 00061 while (Echo == 1) {}; // wait for echo low 00062 Sonar.stop(); // echo low so stop timer 00063 return (Sonar.read_us()*10)/58; // read timer and scale to mm 00064 } 00065 00066 void InitLEDs() { 00067 lat = 0; // latch must start low 00068 spi.format(16,0); // SPI 16 bit data, low state, high going clock 00069 spi.frequency(1000000); // 1MHz clock rate 00070 } 00071 00072 void SetLEDs(short ledall) { 00073 LEDbits = ledall; // update global led status 00074 spi.write((LEDbits & 0x03ff) | ((LEDbits & 0xa800) >> 1) | ((LEDbits & 0x5400) << 1)); 00075 lat = 1; // latch pulse start 00076 lat = 0; // latch pulse end 00077 } 00078 00079 void SetLED(short LEDNo, short LEDState) { 00080 LEDNo = ((LEDNo - 1) & 0x0007) + 1; // limit led number 00081 LEDState = LEDState & 0x0003; // limit led state 00082 LEDNo = (8 - LEDNo) * 2; // offset of led state in 'LEDbits' 00083 LEDState = LEDState << LEDNo; 00084 short statemask = ((0x0003 << LEDNo) ^ 0xffff); // mask used to clear led state 00085 LEDbits = ((LEDbits & statemask) | LEDState); // clear and set led state 00086 SetLEDs(LEDbits); 00087 } 00088 00089 short ReadLED(short LEDNo) { 00090 LEDNo = ((LEDNo - 1) & 0x0007) + 1; // limit led number 00091 LEDNo = (8 - LEDNo) * 2; // offset of led state in 'LEDbits' 00092 short LEDState = (LEDbits >> LEDNo) & 0x0003; // shift selected led state into ls 2 bits 00093 return LEDState; // return led state 00094 } 00095 00096 short ReadLEDs() { 00097 return LEDbits; // return led status 00098 } 00099 00100 void SelInput(short Input) { 00101 Sel0 = Input & 0x0001; // set sel[0:2] pins 00102 Sel1 = (Input >> 1) & 0x0001; // 00103 Sel2 = (Input >> 2) & 0x0001; // 00104 } 00105 00106 short ReadSwitches() { 00107 SelInput(5); // select least significant 4 switches in[3:0] 00108 short Switches = In0 + (In1 << 1) + (In2 << 2) + (In3 << 3); 00109 SelInput(4); // select most significant 4 switches in[3:0] 00110 return (Switches + (In0 << 4) + (In1 << 5) + (In2 << 6) + (In3 << 7)); 00111 } 00112 00113 short ReadSwitch(short SwitchNo) { 00114 SwitchNo = ((SwitchNo - 1) & 0x0007) + 1; // limit switch number 00115 SwitchNo = 8 - SwitchNo; // offset of switch state in ReadSwitches() 00116 short SwitchState = ReadSwitches(); // read switch states 00117 SwitchState = SwitchState >> SwitchNo; // shift selected switch state into ls bit 00118 return (SwitchState & 0x0001); // mask out and return switch state 00119 } 00120 00121 short ReadKeys() { 00122 SelInput(0); // select Keypad top row 00123 short Keys = (In0 << 15) + (In1 << 14) + (In2 << 13) + (In3 << 12); 00124 SelInput(1); // select Keypad second row 00125 Keys += (In0 << 3) + (In1 << 6) + (In2 << 9) + (In3 << 11); 00126 SelInput(2); // select Keypad third row 00127 Keys += (In0 << 2) + (In1 << 5) + (In2 << 8) + In3; 00128 SelInput(3); // select Keypad forth row 00129 Keys += (In0 << 1) + (In1 << 4) + (In2 << 7) + (In3 << 10); 00130 return (Keys ^ 0xffff); // return inverted (Key press active high) 00131 } 00132 00133 short ReadKey(short KeyNo) { 00134 KeyNo = KeyNo & 0x000f; // limit key number 0 to 15 (0 to F) 00135 short KeyState = ReadKeys(); // read key states 00136 KeyState = KeyState >> KeyNo; // shift selected key state into ls bit 00137 return (KeyState & 0x0001); // mask out and return key state 00138 } 00139 00140 int FindKeyNo() { 00141 short KeyNo; 00142 short KeyPressed = -1; // set KeyPressed to -1 (no key pressed) 00143 short KeyState = ReadKeys(); // read key states 00144 for (KeyNo= 0; KeyNo < 16; KeyNo++ ) { // check all 16 Keys 00145 if (KeyState & 0x0001) { // check key state 00146 if (KeyPressed == -1) { // check if key already found 00147 KeyPressed = KeyNo; // update KeyPressed 00148 } 00149 else { 00150 return -1; // 2 or more keys pressed 00151 } 00152 } 00153 KeyState = KeyState >> 1; // shift to check next key 00154 } 00155 return KeyPressed; // return KeyPressed 00156 } 00157 00158 char FindKeyChar() { 00159 short KeyNo; 00160 char KeyChar = ' '; // set KeyChar to ' ' (no key pressed) 00161 KeyNo = FindKeyNo(); // find key pressed 00162 if (KeyNo < 10 && KeyNo >= 0) { 00163 KeyChar = (char) KeyNo + 0x30; // convert char 0-9 to ascii string '0'-'9' 00164 } 00165 if (KeyNo > 9 && KeyNo < 16) { 00166 KeyChar = (char) KeyNo + 0x37; // convert char 10-15 to ascii string 'A'-'F' 00167 } 00168 return KeyChar; // return key pressed 00169 } 00170 00171 float ReadTemp() { 00172 char Cmd[3]; 00173 Cmd[0] = 0x01; // pointer register value 00174 Cmd[1] = 0x60; // byte 1 of the configuration register 00175 Cmd[2] = 0xa0; // byte 2 of the configuration register 00176 i2c.write(TMP102Addr, Cmd, 3); // select configuration register and write 0x60a0 to it 00177 wait(0.5); // ensure conversion time 00178 Cmd[0] = 0x00; // pointer register value 00179 i2c.write(TMP102Addr, Cmd, 1); // select temperature register 00180 i2c.read(TMP102Addr, Cmd, 2); // read 16-bit temperature register 00181 return (float((Cmd[0] << 8) | Cmd[1]) / 256); // divide by 256 and return temperature 00182 } 00183 00184 signed short ReadMPU6050(int RegAddr) { 00185 char Cmd[3]; 00186 Cmd[0] = RegAddr; // register address 00187 i2c.write(MPU6050Addr, Cmd, 1); // select register to read 00188 i2c.read(MPU6050Addr, Cmd, 2); // read 2 bytes from register 00189 return ((Cmd[0] << 8) | Cmd[1]); // return signed 16 bit value 00190 } 00191 00192 void CalibrateGyros() { 00193 short a,b; 00194 for(a=0; a<3; a++) { 00195 GyroOffset[a] = 0; // clear gyro calibration offsets 00196 for(b=0; b<1000; b++) { 00197 GyroOffset[a] = GyroOffset[a] + (float)ReadMPU6050(GReg[a]); 00198 wait_ms(1); // wait for next sample 00199 } 00200 GyroOffset[a] = GyroOffset[a]/1000; // find average over 1000 samples 00201 } 00202 } 00203 00204 void InitMotion() { 00205 char Cmd[3]; 00206 Cmd[0] = 0xa1; // config register address 00207 Cmd[1] = 0x06; // accelerometer and gyro bandwidth = 5Hz 00208 i2c.write(MPU6050Addr, Cmd, 2); // write data to config register 00209 Cmd[0] = 0x6b; // power management register address 00210 Cmd[1] = 0x00; // data 00211 i2c.write(MPU6050Addr, Cmd, 2); // write data to power management register 00212 Cmd[0] = 0x1b; // gyro configuration register address 00213 Cmd[1] = 0x08; // no gyro self test, +-500 full scale 00214 i2c.write(MPU6050Addr, Cmd, 2); // write data to gyro configuration register 00215 Cmd[0] = 0x19; // sample rate register address 00216 Cmd[1] = 0x07; // sample rate = gyro output rate / 8 00217 i2c.write(MPU6050Addr, Cmd, 2); // write data to sample rate register 00218 CalibrateGyros(); 00219 } 00220 00221 void ReadMotion() { 00222 short a; // Acceleration is in G where 1G = 9.81 ms/s 00223 for(a=0; a<3; a++) { // GyroRate is in degrees per second 00224 Acceleration[a] = (float)ReadMPU6050(AReg[a]) / 16384; 00225 GyroRate[a] = ((float)ReadMPU6050(GReg[a]) - GyroOffset[a]) / 66.5; 00226 } 00227 } 00228 00229 int main() { 00230 00231 float spos = 0; // Test servo position 00232 InitLEDs(); 00233 InitMotion(); 00234 InitServos(); 00235 00236 while(1) { 00237 int a,b; 00238 for (b = 0; b < 4; b++ ) { // select all 4 led states 00239 for (a = 1; a < 9; a++ ) { // set all 8 leds to selected state 00240 SetLED (a,b); // set led 'a' to state 'b' 00241 wait(.05); // wait 0.05 second 00242 } 00243 } 00244 for (a= 1; a < 9; a++ ) { // map Switch states to led's 00245 SetLED (a,(ReadSwitch(a) + 1)); // 00246 wait(.05); // wait 0.05 second 00247 } 00248 float temp = ReadTemp(); // get temperature 00249 lcd.cls(); // clear lcd 00250 lcd.printf("Temp = %f\n", temp); // print temperature 00251 wait(1); // wait 1 second 00252 lcd.cls(); // clear lcd 00253 int swch = ReadSwitches(); // look at Switch states 00254 lcd.printf("Switches = %d\n", swch); // print result 00255 char Key = FindKeyChar(); // look for Key pressed 00256 lcd.printf("Key = %c\n", Key); // print result 00257 wait(1); // wait 1 second 00258 lcd.cls(); // clear lcd 00259 int dist = ReadSonar(); // get distance 00260 lcd.printf("Distance = %d\n", dist); // print result 00261 lcd.printf("Servo = %f\n", spos); // print servo pos 00262 wait(1); // wait 1 second 00263 ReadMotion(); // read new data in from the MPU-6050 00264 lcd.cls(); // clear lcd 00265 lcd.locate(0,0); // print at start of first line 00266 lcd.printf("x%.1f y%.1f z%.1f", Acceleration[0], Acceleration[1], Acceleration[2]); 00267 lcd.locate(0,1); // print at start of second line 00268 lcd.printf("x%.1f y%.1f z%.1f", GyroRate[0], GyroRate[1], GyroRate[2]); 00269 wait(.4); // wait 0.4 second 00270 if (spos < 1) { // is servo at upper limit of 1 00271 spos += .1; // increment servo position 00272 } // 00273 else { // was at upper limit so 00274 spos = -1; // reset servo position 00275 } // 00276 Servo1(spos); // update servo 00277 } 00278 }
Generated on Mon Aug 22 2022 08:44:22 by
1.7.2