//----------------------------------------------------------------------------- // updateDisplay - updates one digit per execution, runs every 1ms // executed from main() void updateDisplay(void) { switch(displayState) { case 0: SEG_4_GND_OFF; CLEAR_DIGIT; if(theDisplay.thousands != 0) { SEG_1_GND_ON; showDigit(theDisplay.thousands); } break; case 1: SEG_1_GND_OFF; CLEAR_DIGIT; SEG_2_GND_ON; showDigit(theDisplay.hundreds); break; case 2: SEG_2_GND_OFF; CLEAR_DIGIT; SEG_3_GND_ON; showDigit(theDisplay.tens); break; case 3: SEG_3_GND_OFF; CLEAR_DIGIT; SEG_4_GND_ON; showDigit(theDisplay.ones); break; default: break; } if(displayState<3) displayState++; else displayState = 0; return; }
void numbers99(){ uint8_t i = 0; while(1) { //just some silly temporisation for (uint32_t j = 0; j < 1500; j++){ showDigit(i); } i= (i + 1) % 100; } }
void voltmeter(){ //------------START ADC INIT -------------------------- ADCSRA |= (1 << ADEN) // Analog-Digital enable bit | (1 << ADPS1) // set prescaler to 8 (clock / 8) | (1 << ADPS0) // set prescaler to 8 (clock / 8) // | (1 << REFS1) //1.1v internal ref // | (1 << REFS2) | (1 << REFS1) //2.56v internal ref, without AREF | (1 << REFS1) | (0 << REFS0) //2.56v internal ref, without AREF ; ADCSRB |= (1 << REFS2) //2.56v internal ref, without AREF | (0 << GSEL) //no gain | (0 << MUX5) //adc9 = 001001 ; ADMUX |= // (1 << ADLAR) //just read ADH (0 << ADLAR) //read ADL then ADH | (1 << MUX3) | (1 << MUX0) //adc9 = 001001 ; //------------END ADC INIT -------------------------- uint16_t i = 0; while(1) { // i = ReadADCx();//i in [0;255] i = ReadADCx16();//i in [0;1024] //adjustement : my readings are a little to high (+10%) //also readings [0:1024]->[0:2.56v] and since voltage is measured through a divider scale, adjust i = i * VOLTAGE_SCALE_FACTOR - VOLTAGE_SCALE_FACTOR * i /10; //uint16_t i50 = (uint16_t)i * (uint16_t)50 / (uint16_t)255; // uint16_t i50 = (uint16_t)i * (uint16_t)50; i50 = i50 >> 8; //same as /255 uint16_t i50 = (uint16_t)i * (uint16_t)50; i50 = i50 >> 10; //same as /1024 //just some silly temporisation for (uint32_t j = 0; j < 1500; j++){ showDigit(i50); } } }
//Main body in fact, an inifinite loop void ReadTemp(){ set_sleep_mode(SLEEP_MODE_PWR_SAVE); while(1) { uint32_t v = ReadADCx16(); //convert to centigrad and *10 (because we are working with INT and want to display 1 decimal) //v = (v * 5 * 100 * 10) / 1024; <=> v * 5 * 1000 / 1024 <=> v *5 but we loose a bit of precision //v = v * 5; v = (v * 5 * 100 * 10) >> 10; //>> 10 <=> /1024 //ad'hoc calibration //apparently my system reads a bit too high temp, about 5% too high //I don't have the will to make extensive test, calculate formula etc... //v = v - v/20; //finally readings are ok like that after comparison, just keep the code for memory //average the temp with latest readings mTempBufferAverage[mTempBufferHead] = v; mTempBufferHead = (mTempBufferHead +1) % AVGBUFFER_LEN; //calculate an average with a circle buffer v= 0; for (uint16_t j = 0; j < AVGBUFFER_LEN; j++){ v += mTempBufferAverage[j]; } v = v / AVGBUFFER_LEN; //just some silly temporisation for (uint16_t j = 0; j < 10000; j++){ showDigit(v); //_delay_us(1000); //_delay_ms(1); // save about 0.5mA per ms of sleep. 1 does not change the brightness, after it does but saves more power... depends if you want to read the temperature by daylight too. } //and now the sleep n time 8 sec for (int i =0; i < 2; i++){ wdt_reset(); myWatchdogEnable(); sleep_mode(); } } }
int main (void){ int cbtns = 1; int cins = 1; setup(); for(;;){ if(taskBtn == 0){ cbtns = digitalRead(BUTTON); if(cbtns != lbtns){ if(cbtns == 0){ HOLD = !HOLD; } } lbtns = cbtns; taskBtn = 500; } if(task1 == 0){ if(HOLD){ t1s = !t1s; digitalWrite(LED1,t1s); }else{ digitalWrite(LED1,LOW); } task1 = 2500; } if(task2 == 0){ t2s = !t2s; digitalWrite(LED2,t2s); task2 = 5000; } if(task3 == 0){ if(!HOLD){ t3s = !t3s; digitalWrite(LED3,t3s); }else{ digitalWrite(LED3,LOW); } task3 = 1250; } if(!HOLD){ cins = digitalRead(SIGNAL); if(cins != lins){ counter++; } } if(displayUpdate == 0){ if(!HOLD){ if(counter <= 9999){ displaysValue[3] = counter/1000; int h = counter%1000; displaysValue[2] = h/100; h = h % 100; displaysValue[1] = h/10; h = h % 10; displaysValue[0] = h; }else{ displaysValue[3] = 1; displaysValue[2] = 10; displaysValue[1] = 10; displaysValue[0] = 10; } } if(display == 4){ display = 0; } showDigit(displays[display],displaysValue[display]); display ++; displayUpdate = 20; } lins = cins; task1--; task2--; task3--; taskBtn--; displayUpdate--; delayMicroseconds(100); } return 0; }