7 uint16_t track_current_samples[16] = { 0 };
8 uint8_t track_current_head = 0;
9 volatile uint16_t track_current_sum = 0;
10 uint16_t overcurrent_limit = 8796;
11 uint8_t overcurrent_sent = 0;
13 uint16_t input_voltage_samples[16] = { 0 };
14 uint8_t input_voltage_head = 0;
15 volatile uint16_t input_voltage_sum = 0;
17 volatile uint8_t adc_state = 0;
18 volatile uint16_t adc_value = 0;
20 uint16_t track_current_milliamps();
21 uint16_t input_voltage_millivolts();
32 uint16_t value = adc_value;
36 uint8_t i = track_current_head;
37 track_current_sum -= track_current_samples[i];
38 track_current_samples[i] = value;
39 track_current_sum += value;
40 track_current_head = (i+1)&15;
42 if(track_current_sum>overcurrent_limit)
49 serial_write(OVERCURRENT);
57 uint8_t i = input_voltage_head;
58 input_voltage_sum -= input_voltage_samples[i];
59 input_voltage_samples[i] = value;
60 input_voltage_sum += value;
61 input_voltage_head = (i+1)&15;
64 adc_state = (adc_state+1)&3;
65 adc_read_async(adc_state>>1);
69 uint8_t monitor_command()
71 if(cmd_buf[0]==READ_TRACK_CURRENT)
77 serial_write(TRACK_CURRENT);
78 uint16_t value = track_current_milliamps();
79 serial_write(value>>8);
82 else if(cmd_buf[0]==SET_OVERCURRENT_LIMIT)
87 uint16_t value = (cmd_buf[1]<<8) | cmd_buf[2];
88 if(value>4000) // Safe maximum value
91 // Convert from milliamps: (512+v/1000*0.185/5*1024)*16
92 // multiply by 16384*0.185/5000 = 0.1001101100110b
93 uint16_t v_3 = value*3;
94 overcurrent_limit = 8192+(value>>1)+(v_3>>5)+(v_3>>8)+(v_3>>12);
96 else if(cmd_buf[0]==READ_INPUT_VOLTAGE)
102 serial_write(INPUT_VOLTAGE);
103 uint16_t value = input_voltage_millivolts();
104 serial_write(value>>8);
108 return INVALID_COMMAND;
113 uint16_t track_current_milliamps()
115 uint16_t value = track_current_sum;
117 // Convert to milliamps: (v/16*5/1024-2.5)*1000/0.185
118 if(value<8192) // Ignore negative current readings
124 // multiply by 5000/0.185/16384 = 1.1010011001001b
125 int16_t v_3 = value*3;
126 return (v_3>>1)+(value>>3)+(v_3>>7)+(value>>10)+(v_3>>13);
130 uint16_t input_voltage_millivolts()
132 uint16_t value = input_voltage_sum;
134 // Convert to millivolts: (v/16*5/1024)*1000*11
135 // multiply by 55000/16384 = 11.0101101101100b
136 uint16_t v_3 = value*3;
137 return v_3+(value>>2)+(v_3>>5)+(v_3>>8)+(v_3>>11);
140 static inline void adc_complete(uint16_t value)
146 ADC_SET_CALLBACK(adc_complete)