1 #define F_CPU 16000000L
4 #include <util/delay.h>
6 #define USART_BAUDRATE 9600
7 #define UBRR_VALUE (((F_CPU/(USART_BAUDRATE*16UL)))-1)
9 // this will output only changes on serial
10 #define SERIAL_CHANGES 0
13 // initialize USART (must call this before using it)
14 UBRR0=UBRR_VALUE; // set baud rate
15 UCSR0B|=(1<<TXEN0); //enable transmission only
16 UCSR0C|=(1<<UCSZ01)|(1<<UCSZ01); // no parity, 1 stop bit, 8-bit data
19 void serial_send(unsigned char data){
20 // send a single character via USART
21 while(!(UCSR0A&(1<<UDRE0))){}; //wait while previous byte is completed
22 UDR0 = data; // Transmit data
25 void serial_string(const char* s){
32 serial_send(10); // new line
33 // serial_send(13); // carriage return
36 serial_send(','); // comma
37 serial_send(' '); // space
40 void serial_number(uint32_t val){ // send a number as ASCII text
41 uint32_t divby=1000000000; // change by dataType
43 serial_send('0'+val/divby);
44 val-=(val/divby)*divby;
49 void serial_binary(int val){ // send a number as ASCII text
51 for(bitPos=8;bitPos;bitPos--){
52 if ((val>>(bitPos-1))&1){serial_send('1');}
53 else {serial_send('0');}
60 for(i=65;i<65+26;i++){
69 ////////////////////////////////////////////////////////////////////////
70 ////////////////////////////////////////////////////////////////////////
71 ////////////////////////////////////////////////////////////////////////
72 ////////////////////////////////////////////////////////////////////////
73 ////////////////////////////////////////////////////////////////////////
74 ////////////////////////////////////////////////////////////////////////
75 ////////////////////////////////////////////////////////////////////////
76 ////////////////////////////////////////////////////////////////////////
77 ////////////////////////////////////////////////////////////////////////
78 ////////////////////////////////////////////////////////////////////////
79 ////////////////////////////////////////////////////////////////////////
80 ////////////////////////////////////////////////////////////////////////
81 ////////////////////////////////////////////////////////////////////////
83 // these variables will hold an instant capture of all input pins
84 volatile uint8_t regB;
85 volatile uint8_t regC;
86 volatile uint8_t regD;
88 // these values will hold the current/voltage value
89 volatile char current[4] = "XXXX";
90 volatile char voltage[4] = "XXXX";
92 volatile int display_sum = 0;
93 volatile int last_display_sum = 0;
97 // load the volatile capture variables with tue current pin state
104 // returns the letter (1-8) of the segments stored in read_capture
105 // returned value will be in ASCII
106 // returns ? if no letter is selected, or if it's confusing
108 // start by creating a "letter" variable which defines pin states
110 if(regC&(1<<PC0)){letter|=(1<<7);} // letter 1 (voltage MSB)
111 if(regC&(1<<PC3)){letter|=(1<<6);} // letter 2
112 if(regC&(1<<PC4)){letter|=(1<<5);} // letter 3
113 if(regD&(1<<PD2)){letter|=(1<<4);} // letter 4
114 if(regB&(1<<PB3)){letter|=(1<<3);} // letter 5 (current MSB)
115 if(regD&(1<<PD4)){letter|=(1<<2);} // letter 6
116 if(regD&(1<<PD3)){letter|=(1<<1);} // letter 7
117 if(regD&(1<<PD5)){letter|=(1<<0);} // letter 8
119 // try to match expected pin states
120 if (letter==0b10000000) {return '1';}
121 if (letter==0b01000000) {return '2';}
122 if (letter==0b00100000) {return '3';}
123 if (letter==0b00010000) {return '4';}
124 if (letter==0b00001000) {return '5';}
125 if (letter==0b00000100) {return '6';}
126 if (letter==0b00000010) {return '7';}
127 if (letter==0b00000001) {return '8';}
131 volatile uint8_t saved_period;
133 // returns the numerical value (0-9) stored in read_capture
134 // returned value will be in ASCII
135 // returns 0 if no letter is selected, or if it's confusing
137 if(regC&(1<<PC1)){segments|=(1<<7);} // A (MSB)
138 if(regC&(1<<PC5)){segments|=(1<<6);} // B
139 if(regD&(1<<PD7)){segments|=(1<<5);} // C
140 if(regB&(1<<PB1)){segments|=(1<<4);} // D
141 if(regB&(1<<PB2)){segments|=(1<<3);} // E
142 if(regC&(1<<PC2)){segments|=(1<<2);} // F
143 if(regD&(1<<PD6)){segments|=(1<<1);} // G (LSB)
144 //if(regB&(1<<PB0)){}//H
146 if(segments==0b00001000) {return '9';}
147 if(segments==0b00000000) {return '8';}
148 if(segments==0b00011110) {return '7';}
149 if(segments==0b01000000) {return '6';}
150 if(segments==0b01001000) {return '5';}
151 if(segments==0b10011000) {return '4';}
152 if(segments==0b00001100) {return '3';}
153 if(segments==0b00100100) {return '2';}
154 if(segments==0b10011110) {return '1';}
155 if(segments==0b00000010) {return '0';}
159 uint8_t capture_letter(char letter){
160 // loops until the current letter has been captured
161 uint16_t tries=1000; // trial and error reveals this works
164 read_capture(); // take a new read
165 if (saved_letter()==letter) {
166 if (saved_number()!='?'){
167 if (letter=='1'){voltage[0]=saved_number();}
168 if (letter=='2'){voltage[1]=saved_number();}
169 if (letter=='3'){voltage[2]=saved_number();}
170 if (letter=='4'){voltage[3]=saved_number();}
171 if (letter=='5'){current[0]=saved_number();}
172 if (letter=='6'){current[1]=saved_number();}
173 if (letter=='7'){current[2]=saved_number();}
174 if (letter=='8'){current[3]=saved_number();}
183 // capture even value of every letter
186 for(i=0;i<4;i++) {voltage[i]=' ';}
187 for(i=0;i<4;i++) {current[i]=' ';}
189 for(i=0;i<8;i++){ // for each of the 8 letters
190 for (j=0;j<10;j++){ // try to capture each letter 10 times
191 if (capture_letter('1'+i)) {break;}
196 // don't send same values over serial
198 display_sum = voltage[i] + current[i];
200 if ( display_sum == last_display_sum ) {
203 last_display_sum = display_sum;
208 serial_send(voltage[i]);
209 if (i==1){serial_send('.');}
213 serial_send(current[i]);
214 if (i==2){serial_send('.');}
219 volatile uint16_t checksum;
223 //serial_send(getDigitForLetter('1'));
225 //capture_letter('4');