/* Frequenzzähler mit Key&Buttons Siebensegmentdisplay Bedieneinheit. Diese Version besitzt einen Tara Knopf ganz links. Damit kann die aktuelle Frequenz von der Anzeige abgezogen werden. Dann wird nur noch die Differenzfrequenz dargestellt. Mit dem Knopf ganz rechts stelle man auf die Default-Werte zurück. Weitere Features: - Impulse können gezählt werden - Die Periode kann in Mikrosekunden dargestellt werden ( ist aber bei niedrigen Frequenzen sehr ungenau ) Für Teile des Codes wurde diese Beispiel verwendet: https://github.com/gavinlyonsrepo/TM1638plus/blob/master/examples/TM1638plus_ADC_Model2/TM1638plus_ADC_Model2.ino#L48 21.12.2020 chris_ my code part: Free Beer Lizence ( or to be more precise: red wine ) */ #include //https://github.com/PaulStoffregen/FreqCount/archive/master.zip // Arduino UNO PIN5 Counter input #define PIN_COUNTER_INPUT 5 #include //https://github.com/gavinlyonsrepo/TM1638plus // GPIO I/O pins on the Arduino connected to strobe, clock, data, // pick on any I/O you want. #define STROBE_TM 4 // strobe = GPIO connected to strobe line of module #define CLOCK_TM 2 // clock = GPIO connected to clock line of module #define DIO_TM 3 // data = GPIO connected to data line of module bool high_freq = false; //default false,, If using a high freq CPU > ~100 MHZ set to true. //Constructor object (GPIO STB , GPIO CLOCK , GPIO DIO, use high freq MCU) TM1638plus tm(STROBE_TM, CLOCK_TM , DIO_TM, high_freq); unsigned long previousMillis_display = 0; // will store last time ADCs was updated unsigned long previousMillis_button = 0; const long interval_display = 3000; // interval at which to read ADCs (milliseconds) const long interval_button = 225; // interval to read button void ledsOff() { for (uint8_t n = 0; n < 8; n++)tm.setLED(n, 0); } /* keys 0: tara // subtract current value/reset counter 1: pwm duty cycle % 2: t on // not implemented yet 3: t off // not implemented yet 4: Period 5: count 6: freq 7: serial */ #define BUTTON_TARA 0 #define BUTTON_PWMDUTY 1 // PWM duty cycle in % #define BUTTON_THIGH 2 #define BUTTON_TLOW 3 #define BUTTON_PERIOD 4 #define BUTTON_COUNTER 5 #define BUTTON_FREQUENCY 6 #define BUTTON_SERIAL 7 #define LED_INPUT_SIGNAL 7 // we use LED 7 to indicate the state of the input uint8_t DeviceState = BUTTON_FREQUENCY; // measurement state boolean ShowTaraFlag = false; float TaraOffset = 0; float CurrentValue = 0; boolean printSerialFlag = false; uint16_t HighWordTimer1 = 0; // init Timer 1 as 16 bit counter void initCounter() { TCCR1A = 0; //wichtig um den Arduino PWM Initalisierungs Code zu überschreiben!! TCCR1B = _BV(CS12) | _BV(CS11) | _BV(CS10); } #define READ_INPUT_TIMER1 ((PIND&0b00100000)!=0) uint16_t OldValueTimer1 = 0; #define TIMEOUT_NUM 1000000 boolean measureTime(uint32_t *tLow, uint32_t *tHigh) { uint32_t timeOut; uint32_t t1, t2, t3, t4; //pinMode(READ_INPUT_TIMER1,INPUT); timeOut = TIMEOUT_NUM; // wait for rising edge //while (timeOut > 0 && digitalRead(PIN_COUNTER_INPUT) == 0) timeOut--; while ((timeOut > 0) && !READ_INPUT_TIMER1) timeOut--; t1 = micros(); timeOut = TIMEOUT_NUM; // wait for falling edge //while (timeOut > 0 && digitalRead(PIN_COUNTER_INPUT) == 1) timeOut--; while ((timeOut > 0) && READ_INPUT_TIMER1) timeOut--; t2 = micros(); timeOut = TIMEOUT_NUM; // wait for rising edge //while (timeOut > 0 && digitalRead(PIN_COUNTER_INPUT) == 0) timeOut--; while ((timeOut > 0) && !READ_INPUT_TIMER1) timeOut--; t3 = micros(); timeOut = TIMEOUT_NUM; // wait for falling edge //while (timeOut > 0 && digitalRead(PIN_COUNTER_INPUT) == 1) timeOut--; while ((timeOut > 0) && READ_INPUT_TIMER1) timeOut--; t4 = micros(); //*tHigh = t2 - t1; *tLow = t3 - t2; *tHigh = t4 - t3; // measuring tHigh here is more stable return true; } uint32_t readCounter() { uint16_t count; // attention: this should be replaced by an interrupt routine count = TCNT1;// Atmega if (count < OldValueTimer1) HighWordTimer1++; OldValueTimer1 = count; uint32_t hw = HighWordTimer1; return hw * 65536 + count; } void resetCounter() { HighWordTimer1 = 0; OldValueTimer1 = 0; TCNT1 = 0; } void setDeviceStateLed(uint8_t n) { tm.setLED(BUTTON_PWMDUTY, 0); tm.setLED(BUTTON_THIGH, 0); tm.setLED(BUTTON_TLOW, 0); tm.setLED(BUTTON_COUNTER, 0); tm.setLED(BUTTON_FREQUENCY, 0); tm.setLED(BUTTON_PERIOD, 0); tm.setLED(n, 1); } void toogleSignalLed() { static boolean ledState; tm.setLED(7, ledState); ledState = !ledState; } void setup() { Serial.begin(115200); FreqCount.begin(1000); tm.displayBegin(); setDeviceStateLed(DeviceState); pinMode(LED_BUILTIN, OUTPUT); } void loop() { unsigned long currentMillis = millis(); uint8_t buttons = 0; // use ARDUINO LED to display input pin state digitalWrite(LED_BUILTIN, digitalRead(PIN_COUNTER_INPUT)); if (currentMillis - previousMillis_display >= interval_display) { previousMillis_display = currentMillis; if (DeviceState == BUTTON_PWMDUTY) { uint32_t tLow, tHigh; measureTime(&tLow, &tHigh); float dutyPercent = 100.0 * tHigh / (tLow + tHigh); tm.displayIntNum((int32_t) dutyPercent, true); } if (DeviceState == BUTTON_TLOW) { uint32_t t1, t2; measureTime(&t1, &t2); tm.displayIntNum(t1, true); } if (DeviceState == BUTTON_THIGH) { uint32_t t1, t2; measureTime(&t1, &t2); tm.displayIntNum(t2, true); } if (DeviceState == BUTTON_PERIOD) { uint32_t t1, t2; measureTime(&t1, &t2); uint32_t period = t1 + t2; tm.displayIntNum(period, true); } } //tm.setLED(LED_INPUT_SIGNAL,digitalRead(PIN_COUNTER_INPUT)); //tm.setLED(LED_INPUT_SIGNAL,READ_INPUT_TIMER1); if (DeviceState == BUTTON_COUNTER) { tm.displayIntNum(readCounter()); } else { if (FreqCount.available()) { unsigned long count; float result; //toogleSignalLed(); count = FreqCount.read(); //tm.setLED(LED_INPUT_SIGNAL,READ_INPUT_TIMER1); if (DeviceState == BUTTON_FREQUENCY) { //float result = count / 1.000279; // correction for my Arduino, look for your own ... result = count / 1.0; // no correction /* if (DeviceState == BUTTON_PERIOD) { //float result = count / 1.000279; // correction for my Arduino, look for your own ... result = 1.0 / count * 1e6; // period in microseconds } */ int32_t taraValue = (int32_t)result - TaraOffset; tm.displayIntNum(taraValue, true); if (printSerialFlag) { Serial.println(taraValue); } CurrentValue = result; } } } // Read the button everyinterval_button delay if (currentMillis - previousMillis_button >= interval_button) { previousMillis_button = currentMillis; buttons = tm.readButtons(); } if (buttons != 0) { printSerialFlag = true; // set show tara ( current frequency is subtracted ) if (buttons == 1 << BUTTON_TARA) { if (DeviceState == BUTTON_COUNTER) { resetCounter(); tm.setLED(BUTTON_TARA, 1); delay(50); tm.setLED(BUTTON_TARA, 0); } else { if (ShowTaraFlag) { ShowTaraFlag = false; // toggle state tm.setLED(BUTTON_TARA, 0); TaraOffset = 0; } else { ShowTaraFlag = true; // toggle state TaraOffset = CurrentValue; ledsOff(); tm.setLED(BUTTON_TARA, 1); } } } if (buttons == 1 << BUTTON_PWMDUTY) { DeviceState = BUTTON_PWMDUTY; setDeviceStateLed(DeviceState); FreqCount.end(); } if (buttons == 1 << BUTTON_TLOW) { DeviceState = BUTTON_TLOW; setDeviceStateLed(DeviceState); FreqCount.end(); } if (buttons == 1 << BUTTON_THIGH) { DeviceState = BUTTON_THIGH; setDeviceStateLed(DeviceState); FreqCount.end(); } if (buttons == 1 << BUTTON_PERIOD) { DeviceState = BUTTON_PERIOD; setDeviceStateLed(DeviceState); FreqCount.begin(1000); } if (buttons == 1 << BUTTON_COUNTER) { initCounter(); resetCounter(); DeviceState = BUTTON_COUNTER; setDeviceStateLed(DeviceState); FreqCount.begin(1000); } if (buttons == 1 << BUTTON_FREQUENCY) { DeviceState = BUTTON_FREQUENCY; setDeviceStateLed(DeviceState); FreqCount.begin(1000); } // reset to default if (buttons == 1 << BUTTON_SERIAL) { ledsOff(); } } }