Hacking into the iClicker2 for adding remote access abilities. http://www.amazon.com/I-Clicker-2-I-CLICKER/dp/1429280476

Dependencies:   mbed

Committer:
jjones646
Date:
Mon Nov 24 03:10:20 2014 +0000
Revision:
0:614bf9f43501
Child:
1:7ea05d050158
initial commit;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jjones646 0:614bf9f43501 1 #include "mbed.h"
jjones646 0:614bf9f43501 2 #include <string>
jjones646 0:614bf9f43501 3 #include <vector>
jjones646 0:614bf9f43501 4
jjones646 0:614bf9f43501 5 // These are used for setting the serial buffer size and how long the mbed should wait between updates
jjones646 0:614bf9f43501 6 static const float SLEEP_TIME = 0.5; // x86 background process will only have updates every 1 second in ideal situations
jjones646 0:614bf9f43501 7 static const float PIN_DELAY = 0.05; // the time to wait for allowing the relays to fully cycle between transitions
jjones646 0:614bf9f43501 8 static const float POWER_UP_TIME = 5.0; // seconds for the device clicker to go from an OFF to ON state
jjones646 0:614bf9f43501 9 static const int NUM_CMDS = 8;
jjones646 0:614bf9f43501 10
jjones646 0:614bf9f43501 11 // Used for signaling to the main loop if new serial data has arrived by the serial rx interrupt
jjones646 0:614bf9f43501 12 bool new_data;
jjones646 0:614bf9f43501 13
jjones646 0:614bf9f43501 14 // Enumerations for the device's power state
jjones646 0:614bf9f43501 15 enum device_state_t {
jjones646 0:614bf9f43501 16 ON = 1,
jjones646 0:614bf9f43501 17 OFF = 2
jjones646 0:614bf9f43501 18 };
jjones646 0:614bf9f43501 19
jjones646 0:614bf9f43501 20 // Object for linking to a computer via serial communication
jjones646 0:614bf9f43501 21 Serial pc(USBTX, USBRX);
jjones646 0:614bf9f43501 22
jjones646 0:614bf9f43501 23 // Global string for storing the received serial data on the serial rx interrupt
jjones646 0:614bf9f43501 24 string gStr;
jjones646 0:614bf9f43501 25
jjones646 0:614bf9f43501 26
jjones646 0:614bf9f43501 27 void rx_interrupt(void)
jjones646 0:614bf9f43501 28 {
jjones646 0:614bf9f43501 29 int i = 0;
jjones646 0:614bf9f43501 30
jjones646 0:614bf9f43501 31 // update global character array
jjones646 0:614bf9f43501 32 while (pc.readable() | (i<6) ) {
jjones646 0:614bf9f43501 33 gStr += pc.getc();
jjones646 0:614bf9f43501 34 i++;
jjones646 0:614bf9f43501 35 wait(0.02);
jjones646 0:614bf9f43501 36 }
jjones646 0:614bf9f43501 37
jjones646 0:614bf9f43501 38 new_data = 1;
jjones646 0:614bf9f43501 39 }
jjones646 0:614bf9f43501 40
jjones646 0:614bf9f43501 41
jjones646 0:614bf9f43501 42 void make_edge(DigitalOut& pin)
jjones646 0:614bf9f43501 43 {
jjones646 0:614bf9f43501 44 pin = !pin;
jjones646 0:614bf9f43501 45 wait(PIN_DELAY);
jjones646 0:614bf9f43501 46 pin = !pin;
jjones646 0:614bf9f43501 47 }
jjones646 0:614bf9f43501 48
jjones646 0:614bf9f43501 49
jjones646 0:614bf9f43501 50 void confirm_on(AnalogIn& ain){
jjones646 0:614bf9f43501 51 uint16_t readings[3];
jjones646 0:614bf9f43501 52
jjones646 0:614bf9f43501 53 // get 5 initial readings
jjones646 0:614bf9f43501 54 for (int i=0; i<4; i++)
jjones646 0:614bf9f43501 55 {
jjones646 0:614bf9f43501 56 readings[i] = ain.read_u16();
jjones646 0:614bf9f43501 57 wait(0.01);
jjones646 0:614bf9f43501 58 }
jjones646 0:614bf9f43501 59
jjones646 0:614bf9f43501 60 for (int i=0; i<4; i++)
jjones646 0:614bf9f43501 61 {
jjones646 0:614bf9f43501 62 if (readings[i] < 60000)
jjones646 0:614bf9f43501 63 {
jjones646 0:614bf9f43501 64 confirm_on(ain); // break into recursion if past readings are not settled values
jjones646 0:614bf9f43501 65 }
jjones646 0:614bf9f43501 66 }
jjones646 0:614bf9f43501 67 }
jjones646 0:614bf9f43501 68
jjones646 0:614bf9f43501 69
jjones646 0:614bf9f43501 70 int main()
jjones646 0:614bf9f43501 71 {
jjones646 0:614bf9f43501 72 // Blinking LED to show that mbed is running
jjones646 0:614bf9f43501 73 DigitalOut led1(LED1);
jjones646 0:614bf9f43501 74
jjones646 0:614bf9f43501 75 // On/Off, Mode, Send
jjones646 0:614bf9f43501 76 DigitalOut controls[] = { p13, p14, p15 };
jjones646 0:614bf9f43501 77
jjones646 0:614bf9f43501 78 // A, B, C, D, E
jjones646 0:614bf9f43501 79 DigitalOut selections[] = { p16, p17, p18, p19, p21 };
jjones646 0:614bf9f43501 80
jjones646 0:614bf9f43501 81 // Used for reading the clicker's voltage regulator output for determining if clicker is on/off
jjones646 0:614bf9f43501 82 AnalogIn pwr_status(p20);
jjones646 0:614bf9f43501 83
jjones646 0:614bf9f43501 84 // Define the commands variable that holds a list of all valid serial commands
jjones646 0:614bf9f43501 85 std::vector<string> commands(NUM_CMDS);
jjones646 0:614bf9f43501 86
jjones646 0:614bf9f43501 87 // Define the valid set of serial commands
jjones646 0:614bf9f43501 88 commands[0] = "clickerPower\n";
jjones646 0:614bf9f43501 89 commands[1] = "clickerSend\n";
jjones646 0:614bf9f43501 90 commands[2] = "sayHere\n";
jjones646 0:614bf9f43501 91 commands[3] = "clickerA\n";
jjones646 0:614bf9f43501 92 commands[4] = "clickerB\n";
jjones646 0:614bf9f43501 93 commands[5] = "clickerC\n";
jjones646 0:614bf9f43501 94 commands[6] = "clickerD\n";
jjones646 0:614bf9f43501 95 commands[7] = "clickerE\n";
jjones646 0:614bf9f43501 96
jjones646 0:614bf9f43501 97 // Initialize power toggle pin so clicker stays off at mbed startup
jjones646 0:614bf9f43501 98 controls[0] = 1;
jjones646 0:614bf9f43501 99
jjones646 0:614bf9f43501 100 // get initial power readings
jjones646 0:614bf9f43501 101 uint16_t pwr_level = pwr_status.read_u16();
jjones646 0:614bf9f43501 102 uint16_t pwr_level_new = pwr_status.read_u16();
jjones646 0:614bf9f43501 103
jjones646 0:614bf9f43501 104 device_state_t dev_power = ON; // initialize to an off state
jjones646 0:614bf9f43501 105
jjones646 0:614bf9f43501 106 // variables for the main scope
jjones646 0:614bf9f43501 107 char current_selection = NULL;
jjones646 0:614bf9f43501 108 bool update_selection = false;
jjones646 0:614bf9f43501 109 int usr_cmd = 0;
jjones646 0:614bf9f43501 110
jjones646 0:614bf9f43501 111 // Holding down active low Power button will put clicker in configuration mode...we don't want that
jjones646 0:614bf9f43501 112 selections[0] = 1;
jjones646 0:614bf9f43501 113
jjones646 0:614bf9f43501 114 // Function to run at receiving serial data
jjones646 0:614bf9f43501 115 pc.attach(&rx_interrupt, Serial::RxIrq);
jjones646 0:614bf9f43501 116
jjones646 0:614bf9f43501 117 // infinite processing loop
jjones646 0:614bf9f43501 118 while(1) {
jjones646 0:614bf9f43501 119
jjones646 0:614bf9f43501 120 // pull in from globally allocated memory when interurpts are disabled
jjones646 0:614bf9f43501 121 __disable_irq();
jjones646 0:614bf9f43501 122
jjones646 0:614bf9f43501 123 pwr_level_new = pwr_status.read_u16();
jjones646 0:614bf9f43501 124
jjones646 0:614bf9f43501 125 if (new_data){
jjones646 0:614bf9f43501 126 new_data = 0;
jjones646 0:614bf9f43501 127
jjones646 0:614bf9f43501 128 // assign a valid command to variable for the switch case statement. If command is invalid, ignore
jjones646 0:614bf9f43501 129 for (int i=0; i<NUM_CMDS+1; i++){
jjones646 0:614bf9f43501 130 if ( !(strcmp(gStr.c_str(), commands[i].c_str())) ) {
jjones646 0:614bf9f43501 131 usr_cmd = i+1;
jjones646 0:614bf9f43501 132 break;
jjones646 0:614bf9f43501 133 }
jjones646 0:614bf9f43501 134 }
jjones646 0:614bf9f43501 135
jjones646 0:614bf9f43501 136 switch( usr_cmd ) {
jjones646 0:614bf9f43501 137 case 1: // clickerPower
jjones646 0:614bf9f43501 138 make_edge(controls[0]);
jjones646 0:614bf9f43501 139 break;
jjones646 0:614bf9f43501 140
jjones646 0:614bf9f43501 141 case 2: // clickerSend
jjones646 0:614bf9f43501 142 if(current_selection) {
jjones646 0:614bf9f43501 143 make_edge(controls[1]);
jjones646 0:614bf9f43501 144 pc.printf(" Answer submitted: %c\r\n", current_selection);
jjones646 0:614bf9f43501 145 current_selection = NULL;
jjones646 0:614bf9f43501 146 } else {
jjones646 0:614bf9f43501 147 pc.printf(" Must make a selection before attempting a submission\r\n");
jjones646 0:614bf9f43501 148 }
jjones646 0:614bf9f43501 149 make_edge(controls[1]); // comment line out for final version. Used for testing purposes here
jjones646 0:614bf9f43501 150 break;
jjones646 0:614bf9f43501 151
jjones646 0:614bf9f43501 152 case 3: // sayHere
jjones646 0:614bf9f43501 153 pc.printf(" Audio currently unsupported\r\n");
jjones646 0:614bf9f43501 154 break;
jjones646 0:614bf9f43501 155
jjones646 0:614bf9f43501 156 case 4: // clickerA
jjones646 0:614bf9f43501 157 current_selection = 'A';
jjones646 0:614bf9f43501 158 update_selection = true;
jjones646 0:614bf9f43501 159 break;
jjones646 0:614bf9f43501 160
jjones646 0:614bf9f43501 161 case 5: // clickerB
jjones646 0:614bf9f43501 162 current_selection = 'B';
jjones646 0:614bf9f43501 163 update_selection = true;
jjones646 0:614bf9f43501 164 break;
jjones646 0:614bf9f43501 165
jjones646 0:614bf9f43501 166 case 6: // clickerC
jjones646 0:614bf9f43501 167 current_selection = 'C';
jjones646 0:614bf9f43501 168 update_selection = true;
jjones646 0:614bf9f43501 169 break;
jjones646 0:614bf9f43501 170
jjones646 0:614bf9f43501 171 case 7: // clickerD
jjones646 0:614bf9f43501 172 current_selection = 'D';
jjones646 0:614bf9f43501 173 update_selection = true;
jjones646 0:614bf9f43501 174 break;
jjones646 0:614bf9f43501 175
jjones646 0:614bf9f43501 176 case 8: // clickerE
jjones646 0:614bf9f43501 177 current_selection = 'E';
jjones646 0:614bf9f43501 178 update_selection = true;
jjones646 0:614bf9f43501 179 break;
jjones646 0:614bf9f43501 180
jjones646 0:614bf9f43501 181 default:
jjones646 0:614bf9f43501 182 break;
jjones646 0:614bf9f43501 183 }
jjones646 0:614bf9f43501 184 }
jjones646 0:614bf9f43501 185
jjones646 0:614bf9f43501 186
jjones646 0:614bf9f43501 187 if (update_selection) {
jjones646 0:614bf9f43501 188
jjones646 0:614bf9f43501 189 update_selection = false;
jjones646 0:614bf9f43501 190
jjones646 0:614bf9f43501 191 if (dev_power == ON){
jjones646 0:614bf9f43501 192 make_edge(selections[usr_cmd - 4]);
jjones646 0:614bf9f43501 193 pc.printf(" You have selected option %c\r\n", current_selection);
jjones646 0:614bf9f43501 194
jjones646 0:614bf9f43501 195 } else {
jjones646 0:614bf9f43501 196 pc.printf(" Device is not on\r\n");
jjones646 0:614bf9f43501 197 current_selection = NULL;
jjones646 0:614bf9f43501 198 }
jjones646 0:614bf9f43501 199 }
jjones646 0:614bf9f43501 200
jjones646 0:614bf9f43501 201 // if clicker's voltage level has changed significantly...
jjones646 0:614bf9f43501 202 if ( abs(pwr_level_new - pwr_level) > 20000)
jjones646 0:614bf9f43501 203 {
jjones646 0:614bf9f43501 204
jjones646 0:614bf9f43501 205 // settling time
jjones646 0:614bf9f43501 206 while ( abs(pwr_level_new - pwr_status.read_u16()) > 32 )
jjones646 0:614bf9f43501 207 {
jjones646 0:614bf9f43501 208 // wait until the analog input settles to a steady state reading
jjones646 0:614bf9f43501 209 pwr_level_new = pwr_status.read_u16();
jjones646 0:614bf9f43501 210 wait(0.1);
jjones646 0:614bf9f43501 211 }
jjones646 0:614bf9f43501 212
jjones646 0:614bf9f43501 213 if (pwr_level_new < pwr_level) // device is shutting down
jjones646 0:614bf9f43501 214 {
jjones646 0:614bf9f43501 215 dev_power = OFF;
jjones646 0:614bf9f43501 216
jjones646 0:614bf9f43501 217 } else if (pwr_level_new > pwr_level) // device is turning on
jjones646 0:614bf9f43501 218 {
jjones646 0:614bf9f43501 219 confirm_on(pwr_status); // wait for voltage levels to settle to steady value when powering up
jjones646 0:614bf9f43501 220 wait(POWER_UP_TIME);
jjones646 0:614bf9f43501 221 dev_power = ON;
jjones646 0:614bf9f43501 222 }
jjones646 0:614bf9f43501 223
jjones646 0:614bf9f43501 224 // update the power level reading
jjones646 0:614bf9f43501 225 pwr_level = pwr_level_new;
jjones646 0:614bf9f43501 226 pc.printf(" Device power status updated. New status: %s\r\n", dev_power == ON ? "ON": "OFF");
jjones646 0:614bf9f43501 227 }
jjones646 0:614bf9f43501 228
jjones646 0:614bf9f43501 229
jjones646 0:614bf9f43501 230 // clear all command related variables
jjones646 0:614bf9f43501 231 gStr.clear();
jjones646 0:614bf9f43501 232 usr_cmd = 0;
jjones646 0:614bf9f43501 233
jjones646 0:614bf9f43501 234 // turn interrupts back on before going into a sleeping state
jjones646 0:614bf9f43501 235 __enable_irq();
jjones646 0:614bf9f43501 236
jjones646 0:614bf9f43501 237 // blink that shit then be lazy
jjones646 0:614bf9f43501 238 led1 = !led1;
jjones646 0:614bf9f43501 239 wait(SLEEP_TIME);
jjones646 0:614bf9f43501 240 }
jjones646 0:614bf9f43501 241 }