The program is part of the assignment of CE713 Internet of Things. It provides a simple solution to activate an Escalator only when it really needs to be done by using a Sonar Sensor.
Dependencies: EthernetNetIf HTTPServer TextLCD mbed
main.cpp@0:e0539419df78, 2018-01-13 (annotated)
- Committer:
- Elleppi
- Date:
- Sat Jan 13 13:11:20 2018 +0000
- Revision:
- 0:e0539419df78
The Escalator Smart Switch
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Elleppi | 0:e0539419df78 | 1 | #include "mbed.h" |
Elleppi | 0:e0539419df78 | 2 | #include "TextLCD.h" |
Elleppi | 0:e0539419df78 | 3 | #include "EthernetNetIf.h" |
Elleppi | 0:e0539419df78 | 4 | #include "HTTPServer.h" |
Elleppi | 0:e0539419df78 | 5 | |
Elleppi | 0:e0539419df78 | 6 | TextLCD lcd(p15, p16, p17, p18, p19, p20); // LCD: RS, E, D4-D7 |
Elleppi | 0:e0539419df78 | 7 | SPI spi(p5, p6, p7); // SPI: MOSI, MISO, SCLK (MISO not used with LCD) |
Elleppi | 0:e0539419df78 | 8 | DigitalOut lat(p8); // data latch for LED driver TLC59281 |
Elleppi | 0:e0539419df78 | 9 | DigitalOut Sel0(p26); // input select bits: |
Elleppi | 0:e0539419df78 | 10 | DigitalOut Sel1(p25); // " |
Elleppi | 0:e0539419df78 | 11 | DigitalOut Sel2(p24); // " |
Elleppi | 0:e0539419df78 | 12 | DigitalIn In0(p14); // input from switches, keypad etc |
Elleppi | 0:e0539419df78 | 13 | DigitalIn In1(p13); // " |
Elleppi | 0:e0539419df78 | 14 | DigitalIn In2(p12); // " |
Elleppi | 0:e0539419df78 | 15 | DigitalIn In3(p11); // " |
Elleppi | 0:e0539419df78 | 16 | I2C i2c(p9, p10); // I2C: SDA, SCL pins |
Elleppi | 0:e0539419df78 | 17 | DigitalOut Trigger(p28); // Ultrasonic rangefinder trigger pin |
Elleppi | 0:e0539419df78 | 18 | DigitalIn Echo(p27); // Ultrasonic rangefinder echo pin |
Elleppi | 0:e0539419df78 | 19 | Timer Sonar; // Ultrasonic timer |
Elleppi | 0:e0539419df78 | 20 | DigitalOut led1(LED1); |
Elleppi | 0:e0539419df78 | 21 | Serial out(USBTX, USBRX); |
Elleppi | 0:e0539419df78 | 22 | short LEDbits = 0; // global led status used for readback |
Elleppi | 0:e0539419df78 | 23 | |
Elleppi | 0:e0539419df78 | 24 | /*Functions used to initialize the Internet connection*/ |
Elleppi | 0:e0539419df78 | 25 | /*LocalFileSystem fs("webfs"); |
Elleppi | 0:e0539419df78 | 26 | EthernetNetIf eth; |
Elleppi | 0:e0539419df78 | 27 | HTTPServer svr; |
Elleppi | 0:e0539419df78 | 28 | Ticker WebUpdate; // Interrupt timer to update web page // |
Elleppi | 0:e0539419df78 | 29 | |
Elleppi | 0:e0539419df78 | 30 | extern "C" void mbed_mac_address(char *mac); |
Elleppi | 0:e0539419df78 | 31 | |
Elleppi | 0:e0539419df78 | 32 | void WebServerPoll () { |
Elleppi | 0:e0539419df78 | 33 | Net::poll(); |
Elleppi | 0:e0539419df78 | 34 | led1=!led1; //Show that we are alive |
Elleppi | 0:e0539419df78 | 35 | } |
Elleppi | 0:e0539419df78 | 36 | |
Elleppi | 0:e0539419df78 | 37 | int InitWebServer() { |
Elleppi | 0:e0539419df78 | 38 | EthernetErr ethErr = eth.setup(); |
Elleppi | 0:e0539419df78 | 39 | if(ethErr) { |
Elleppi | 0:e0539419df78 | 40 | return -1; |
Elleppi | 0:e0539419df78 | 41 | } |
Elleppi | 0:e0539419df78 | 42 | |
Elleppi | 0:e0539419df78 | 43 | FILE *fp = fopen("/webfs/index.htm", "w"); // Open "out.txt" on the local file system for writing |
Elleppi | 0:e0539419df78 | 44 | fprintf(fp, "<html><head><title>Hello World online</title></head><body><h1>Hello World from Mbed NXP LPC1768!</h1></body></html>"); |
Elleppi | 0:e0539419df78 | 45 | fclose(fp); // Close file |
Elleppi | 0:e0539419df78 | 46 | FSHandler::mount("/webfs", "/files"); // Mount /webfs path on /files web path |
Elleppi | 0:e0539419df78 | 47 | FSHandler::mount("/webfs", "/"); // Mount /webfs path on web root path |
Elleppi | 0:e0539419df78 | 48 | svr.addHandler<SimpleHandler>("/hello"); |
Elleppi | 0:e0539419df78 | 49 | svr.addHandler<RPCHandler>("/rpc"); |
Elleppi | 0:e0539419df78 | 50 | svr.addHandler<FSHandler>("/files"); |
Elleppi | 0:e0539419df78 | 51 | svr.addHandler<FSHandler>("/"); // Default handler |
Elleppi | 0:e0539419df78 | 52 | svr.bind(80); // Example : http://155.245.21.144 |
Elleppi | 0:e0539419df78 | 53 | WebUpdate.attach(&WebServerPoll, 0.1); // update webserver every 100ms |
Elleppi | 0:e0539419df78 | 54 | return 0; // return without error |
Elleppi | 0:e0539419df78 | 55 | } |
Elleppi | 0:e0539419df78 | 56 | |
Elleppi | 0:e0539419df78 | 57 | void HTTPText(char t[4000]) { |
Elleppi | 0:e0539419df78 | 58 | FILE *fp = fopen("/webfs/index.htm", "w"); // Open "out.txt" on the local file system for writing |
Elleppi | 0:e0539419df78 | 59 | fprintf(fp, t); |
Elleppi | 0:e0539419df78 | 60 | fclose(fp); |
Elleppi | 0:e0539419df78 | 61 | }*/ |
Elleppi | 0:e0539419df78 | 62 | |
Elleppi | 0:e0539419df78 | 63 | /*Function used to initialize the board sensors and actuators*/ |
Elleppi | 0:e0539419df78 | 64 | int ReadSonar() { |
Elleppi | 0:e0539419df78 | 65 | Trigger = 1; // set sonar trigger pulse high |
Elleppi | 0:e0539419df78 | 66 | Sonar.reset(); // reset sonar timer |
Elleppi | 0:e0539419df78 | 67 | wait_us(10.0); // 10 us pulse |
Elleppi | 0:e0539419df78 | 68 | Trigger = 0; // set sonar trigger pulse low |
Elleppi | 0:e0539419df78 | 69 | while (Echo == 0) {}; // wait for echo high (8 cycles have been transmitted) |
Elleppi | 0:e0539419df78 | 70 | Sonar.start(); // echo high so start timer |
Elleppi | 0:e0539419df78 | 71 | while (Echo == 1) {}; // wait for echo low |
Elleppi | 0:e0539419df78 | 72 | Sonar.stop(); // echo low so stop timer |
Elleppi | 0:e0539419df78 | 73 | return (Sonar.read_us()*10)/58; // read timer and scale to mm |
Elleppi | 0:e0539419df78 | 74 | } |
Elleppi | 0:e0539419df78 | 75 | |
Elleppi | 0:e0539419df78 | 76 | void InitLEDs() { |
Elleppi | 0:e0539419df78 | 77 | lat = 0; // latch must start low |
Elleppi | 0:e0539419df78 | 78 | spi.format(16,0); // SPI 16 bit data, low state, high going clock |
Elleppi | 0:e0539419df78 | 79 | spi.frequency(1000000); // 1MHz clock rate |
Elleppi | 0:e0539419df78 | 80 | } |
Elleppi | 0:e0539419df78 | 81 | |
Elleppi | 0:e0539419df78 | 82 | void SetLEDs(short ledall) { |
Elleppi | 0:e0539419df78 | 83 | LEDbits = ledall; // update global led status |
Elleppi | 0:e0539419df78 | 84 | spi.write((LEDbits & 0x03ff) | ((LEDbits & 0xa800) >> 1) | ((LEDbits & 0x5400) << 1)); |
Elleppi | 0:e0539419df78 | 85 | lat = 1; // latch pulse start |
Elleppi | 0:e0539419df78 | 86 | lat = 0; // latch pulse end |
Elleppi | 0:e0539419df78 | 87 | } |
Elleppi | 0:e0539419df78 | 88 | |
Elleppi | 0:e0539419df78 | 89 | void SetLED(short LEDNo, short LEDState) { |
Elleppi | 0:e0539419df78 | 90 | LEDNo = ((LEDNo - 1) & 0x0007) + 1; // limit led number |
Elleppi | 0:e0539419df78 | 91 | LEDState = LEDState & 0x0003; // limit led state |
Elleppi | 0:e0539419df78 | 92 | LEDNo = (8 - LEDNo) * 2; // offset of led state in 'LEDbits' |
Elleppi | 0:e0539419df78 | 93 | LEDState = LEDState << LEDNo; |
Elleppi | 0:e0539419df78 | 94 | short statemask = ((0x0003 << LEDNo) ^ 0xffff); // mask used to clear led state |
Elleppi | 0:e0539419df78 | 95 | LEDbits = ((LEDbits & statemask) | LEDState); // clear and set led state |
Elleppi | 0:e0539419df78 | 96 | SetLEDs(LEDbits); |
Elleppi | 0:e0539419df78 | 97 | } |
Elleppi | 0:e0539419df78 | 98 | |
Elleppi | 0:e0539419df78 | 99 | void SelInput(short Input) { |
Elleppi | 0:e0539419df78 | 100 | Sel0 = Input & 0x0001; // set sel[0:2] pins |
Elleppi | 0:e0539419df78 | 101 | Sel1 = (Input >> 1) & 0x0001; // |
Elleppi | 0:e0539419df78 | 102 | Sel2 = (Input >> 2) & 0x0001; // |
Elleppi | 0:e0539419df78 | 103 | } |
Elleppi | 0:e0539419df78 | 104 | |
Elleppi | 0:e0539419df78 | 105 | short ReadSwitches() { |
Elleppi | 0:e0539419df78 | 106 | SelInput(5); // select least significant 4 switches in[3:0] |
Elleppi | 0:e0539419df78 | 107 | short Switches = In0 + (In1 << 1) + (In2 << 2) + (In3 << 3); |
Elleppi | 0:e0539419df78 | 108 | SelInput(4); // select most significant 4 switches in[3:0] |
Elleppi | 0:e0539419df78 | 109 | return (Switches + (In0 << 4) + (In1 << 5) + (In2 << 6) + (In3 << 7)); |
Elleppi | 0:e0539419df78 | 110 | } |
Elleppi | 0:e0539419df78 | 111 | |
Elleppi | 0:e0539419df78 | 112 | short ReadSwitch(short SwitchNo) { |
Elleppi | 0:e0539419df78 | 113 | SwitchNo = ((SwitchNo - 1) & 0x0007) + 1; // limit switch number |
Elleppi | 0:e0539419df78 | 114 | SwitchNo = 8 - SwitchNo; // offset of switch state in ReadSwitches() |
Elleppi | 0:e0539419df78 | 115 | short SwitchState = ReadSwitches(); // read switch states |
Elleppi | 0:e0539419df78 | 116 | SwitchState = SwitchState >> SwitchNo; // shift selected switch state into ls bit |
Elleppi | 0:e0539419df78 | 117 | return (SwitchState & 0x0001); // mask out and return switch state |
Elleppi | 0:e0539419df78 | 118 | } |
Elleppi | 0:e0539419df78 | 119 | |
Elleppi | 0:e0539419df78 | 120 | /*Set reference distance: |
Elleppi | 0:e0539419df78 | 121 | if the distance sensed by the sonar is the same for 9 seconds, |
Elleppi | 0:e0539419df78 | 122 | it will be the reference distance, otherwise restart the cycle*/ |
Elleppi | 0:e0539419df78 | 123 | int setDistance() { |
Elleppi | 0:e0539419df78 | 124 | int D_temp = ReadSonar(); |
Elleppi | 0:e0539419df78 | 125 | int D; |
Elleppi | 0:e0539419df78 | 126 | |
Elleppi | 0:e0539419df78 | 127 | lcd.cls(); |
Elleppi | 0:e0539419df78 | 128 | lcd.printf("setting distance"); |
Elleppi | 0:e0539419df78 | 129 | |
Elleppi | 0:e0539419df78 | 130 | SetLEDs(0); |
Elleppi | 0:e0539419df78 | 131 | |
Elleppi | 0:e0539419df78 | 132 | for(int i=0; i<9; i++) { |
Elleppi | 0:e0539419df78 | 133 | D = ReadSonar(); |
Elleppi | 0:e0539419df78 | 134 | |
Elleppi | 0:e0539419df78 | 135 | /*Allow an extra range of 10 mm for setting the distance*/ |
Elleppi | 0:e0539419df78 | 136 | if(D_temp - 10 < D && D_temp + 10 > D) { |
Elleppi | 0:e0539419df78 | 137 | D_temp = D; //reset D_temp |
Elleppi | 0:e0539419df78 | 138 | i = 0; //restart setting the distance |
Elleppi | 0:e0539419df78 | 139 | SetLEDs(0); |
Elleppi | 0:e0539419df78 | 140 | } |
Elleppi | 0:e0539419df78 | 141 | else { |
Elleppi | 0:e0539419df78 | 142 | wait(1); |
Elleppi | 0:e0539419df78 | 143 | SetLED(i%9, 1); |
Elleppi | 0:e0539419df78 | 144 | } |
Elleppi | 0:e0539419df78 | 145 | } |
Elleppi | 0:e0539419df78 | 146 | |
Elleppi | 0:e0539419df78 | 147 | lcd.cls(); |
Elleppi | 0:e0539419df78 | 148 | lcd.printf("distance set at\n%d", D); |
Elleppi | 0:e0539419df78 | 149 | wait(2); |
Elleppi | 0:e0539419df78 | 150 | |
Elleppi | 0:e0539419df78 | 151 | return D; |
Elleppi | 0:e0539419df78 | 152 | } |
Elleppi | 0:e0539419df78 | 153 | |
Elleppi | 0:e0539419df78 | 154 | int main() { |
Elleppi | 0:e0539419df78 | 155 | InitLEDs(); |
Elleppi | 0:e0539419df78 | 156 | //InitWebServer(); |
Elleppi | 0:e0539419df78 | 157 | int D = setDistance(); |
Elleppi | 0:e0539419df78 | 158 | int D1; |
Elleppi | 0:e0539419df78 | 159 | int T_ON = 0; //Time (seconds) the escalator is ON |
Elleppi | 0:e0539419df78 | 160 | int T_tot = 0; //Time (seconds) since the system started working |
Elleppi | 0:e0539419df78 | 161 | int timeSaved; //Time saved (seconds) |
Elleppi | 0:e0539419df78 | 162 | int energySaved = 0; //Percentage of energy saved |
Elleppi | 0:e0539419df78 | 163 | char ON = 0; |
Elleppi | 0:e0539419df78 | 164 | |
Elleppi | 0:e0539419df78 | 165 | //char Buffer[4000]; |
Elleppi | 0:e0539419df78 | 166 | |
Elleppi | 0:e0539419df78 | 167 | while(1) { |
Elleppi | 0:e0539419df78 | 168 | D1 = ReadSonar(); |
Elleppi | 0:e0539419df78 | 169 | |
Elleppi | 0:e0539419df78 | 170 | /*ESCALATOR_POWER_ON*/ |
Elleppi | 0:e0539419df78 | 171 | if(D1 < D - 10) { //Allow an extra range of 10 mm when sensing the distance |
Elleppi | 0:e0539419df78 | 172 | T_ON++; |
Elleppi | 0:e0539419df78 | 173 | ON = 1; |
Elleppi | 0:e0539419df78 | 174 | } |
Elleppi | 0:e0539419df78 | 175 | |
Elleppi | 0:e0539419df78 | 176 | /*ESCALATOR_POWER_OFF*/ |
Elleppi | 0:e0539419df78 | 177 | else |
Elleppi | 0:e0539419df78 | 178 | ON = 0; |
Elleppi | 0:e0539419df78 | 179 | |
Elleppi | 0:e0539419df78 | 180 | T_tot++; |
Elleppi | 0:e0539419df78 | 181 | energySaved = 100 - ((100*T_ON)/T_tot); //(previously the escalator was always ON) |
Elleppi | 0:e0539419df78 | 182 | timeSaved = T_tot - T_ON; |
Elleppi | 0:e0539419df78 | 183 | |
Elleppi | 0:e0539419df78 | 184 | int firstOnSwitch = 0; //used to identify the switch |
Elleppi | 0:e0539419df78 | 185 | |
Elleppi | 0:e0539419df78 | 186 | for (int a= 1; a < 9; a++ ) { // map Switch states to led's |
Elleppi | 0:e0539419df78 | 187 | SetLED (a,(ReadSwitch(a) + 1)); |
Elleppi | 0:e0539419df78 | 188 | |
Elleppi | 0:e0539419df78 | 189 | if(ReadSwitch(a) == 1) { |
Elleppi | 0:e0539419df78 | 190 | firstOnSwitch = a; |
Elleppi | 0:e0539419df78 | 191 | } |
Elleppi | 0:e0539419df78 | 192 | } |
Elleppi | 0:e0539419df78 | 193 | |
Elleppi | 0:e0539419df78 | 194 | /*Display the data collected on the LCD of the board*/ |
Elleppi | 0:e0539419df78 | 195 | switch(firstOnSwitch) |
Elleppi | 0:e0539419df78 | 196 | { |
Elleppi | 0:e0539419df78 | 197 | /*Switch 1: percentage of energy saved*/ |
Elleppi | 0:e0539419df78 | 198 | case 1: |
Elleppi | 0:e0539419df78 | 199 | lcd.cls(); |
Elleppi | 0:e0539419df78 | 200 | lcd.printf("Energy Saved =\n%d%c", energySaved, '%'); |
Elleppi | 0:e0539419df78 | 201 | break; |
Elleppi | 0:e0539419df78 | 202 | |
Elleppi | 0:e0539419df78 | 203 | /*Switch 2: total elapsed time since the system started working*/ |
Elleppi | 0:e0539419df78 | 204 | case 2: |
Elleppi | 0:e0539419df78 | 205 | lcd.cls(); |
Elleppi | 0:e0539419df78 | 206 | lcd.printf("T_tot:\n%d", T_tot); |
Elleppi | 0:e0539419df78 | 207 | break; |
Elleppi | 0:e0539419df78 | 208 | |
Elleppi | 0:e0539419df78 | 209 | /*Switch 3: amount of time the escalator has been ON*/ |
Elleppi | 0:e0539419df78 | 210 | case 3: |
Elleppi | 0:e0539419df78 | 211 | lcd.cls(); |
Elleppi | 0:e0539419df78 | 212 | lcd.printf("T_ON =\n%d", T_ON); |
Elleppi | 0:e0539419df78 | 213 | break; |
Elleppi | 0:e0539419df78 | 214 | |
Elleppi | 0:e0539419df78 | 215 | /*Switch 4: amount of time saved (time the escalator has been OFF)*/ |
Elleppi | 0:e0539419df78 | 216 | case 4: |
Elleppi | 0:e0539419df78 | 217 | lcd.cls(); |
Elleppi | 0:e0539419df78 | 218 | lcd.printf("Time saved =\n%d", timeSaved); |
Elleppi | 0:e0539419df78 | 219 | break; |
Elleppi | 0:e0539419df78 | 220 | |
Elleppi | 0:e0539419df78 | 221 | /*No Switch: current state of the escalator (ON/OFF)*/ |
Elleppi | 0:e0539419df78 | 222 | default: |
Elleppi | 0:e0539419df78 | 223 | if(ON == 1) { |
Elleppi | 0:e0539419df78 | 224 | lcd.cls(); |
Elleppi | 0:e0539419df78 | 225 | lcd.printf("Escalator\nON"); |
Elleppi | 0:e0539419df78 | 226 | } |
Elleppi | 0:e0539419df78 | 227 | else { |
Elleppi | 0:e0539419df78 | 228 | lcd.cls(); |
Elleppi | 0:e0539419df78 | 229 | lcd.printf("Escalator\nOFF"); |
Elleppi | 0:e0539419df78 | 230 | } |
Elleppi | 0:e0539419df78 | 231 | } |
Elleppi | 0:e0539419df78 | 232 | |
Elleppi | 0:e0539419df78 | 233 | /*HTML and CSS code to be sent to the dedicated Web Page (MAC Address)*/ |
Elleppi | 0:e0539419df78 | 234 | /*sprintf(Buffer, "<!DOCTYPE html><html><head><title>Escalator Smart Switch</title></head><body><style type=\"text/css\">.tg {border-collapse:collapse;border-spacing:0;border-color:#aabcfe;margin:0px auto;}.tg td{font-family:Arial, sans-serif;font-size:14px;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#aabcfe;color:#669;background-color:#e8edff;}.tg th{font-family:Arial, sans-serif;font-size:14px;font-weight:normal;padding:10px 5px;border-style:solid;border-width:1px;overflow:hidden;word-break:normal;border-color:#aabcfe;color:#039;background-color:#b9c9fe;}.tg .tg-wfog{font-weight:bold;font-size:22px;color:#f56b00;text-align:center;vertical-align:top}.tg .tg-3v14{background-color:#D2E4FC;font-weight:bold;font-size:18px;text-align:center;vertical-align:top}.tg .tg-5frq{font-style:italic;text-align:center;vertical-align:top}.tg .tg-xqmu{background-color:#D2E4FC;font-style:italic;text-align:center;vertical-align:top}</style>"); |
Elleppi | 0:e0539419df78 | 235 | sprintf(Buffer + strlen(Buffer), "<table class=\"tg\"><tr><th class=\"tg-wfog\" colspan=\"3\">Escalator MAC ADDRESS</th></tr><tr><td class=\"tg-3v14\">Value</td><td class=\"tg-3v14\">Currently</td><td class=\"tg-3v14\">Previously</td></tr>"); |
Elleppi | 0:e0539419df78 | 236 | sprintf(Buffer + strlen(Buffer), "<tr><td class=\"tg-5frq\">Working Time</td><td class=\"tg-5frq\">%d seconds</td><td class=\"tg-5frq\">%d seconds</td></tr>", T_ON, T_tot); |
Elleppi | 0:e0539419df78 | 237 | sprintf(Buffer + strlen(Buffer), "<tr><td class=\"tg-xqmu\">Working Time Saved</td><td class=\"tg-xqmu\" colspan=\"2\">%d seconds</td></tr>", timeSaved); |
Elleppi | 0:e0539419df78 | 238 | sprintf(Buffer + strlen(Buffer), "<tr><td class=\"tg-5frq\">Energy Saved</td><td class=\"tg-5frq\" colspan=\"2\">%f</td></tr></table></body></html>", energySaved); |
Elleppi | 0:e0539419df78 | 239 | HTTPText(Buffer);*/ // write to index.htm |
Elleppi | 0:e0539419df78 | 240 | |
Elleppi | 0:e0539419df78 | 241 | wait(1); |
Elleppi | 0:e0539419df78 | 242 | } |
Elleppi | 0:e0539419df78 | 243 | } |