Testing code: Also using 7 Segment with MAX7219 Using library Here: https://github.com/wayoda/LedControl
PinChange interrupt with : https://github.com/NicoHood/PinChangeInterrupt
Sensor: IR transistor+IR LED eg: https://item.taobao.com/item.htm?spm=a230r.1.14.23.676236d4xU15rA&id=543241524310&ns=1&abbucket=6#detail
Does not work in sunlight ( as speculated )
#include "PinChangeInterrupt.h" #include "LedControl.h" const int d_in = 8; const int c_wire = 28; // 28 Wires. // current step unsigned long g_step = 0; unsigned long ts_fps; const unsigned long ts_fps_interval = 20; LedControl lc = LedControl(4, 6, 5, 1); // Remember time and count #define buffersize 64 int ct_ptr; // current unsigned long ct_ts[2][buffersize]; void setup() { //Attach counter pinMode(d_in, INPUT_PULLUP); attachPCINT( digitalPinToPCINT(d_in), d_count, RISING ); //clear buffer memset(ct_ts,0,sizeof(ct_ts)); //clear display lc.shutdown(0, false); lc.setIntensity(0, 8); lc.clearDisplay(0); Serial.begin(115200); } void loop() { unsigned long ts_frame = millis(); if ( ts_frame - ts_fps >= ts_fps_interval ) { ts_fps = ts_frame; unsigned long step_diff = g_step - ct_ts[0][ct_ptr]; unsigned long time_diff = ts_frame - ct_ts[1][ct_ptr]; double d_cps = 1000; // count per second (cuz time diff is in ms, so need to start with 1000) d_cps *= step_diff; d_cps /= time_diff; double d_rpm = d_cps * 60; d_rpm /= c_wire; //how many wires // remember time and count ct_ts[0][ct_ptr] = g_step; ct_ts[1][ct_ptr] = ts_frame; ct_ptr++; ct_ptr %= buffersize; if(Serial){ Serial.println(d_rpm); } // d_rpm to digits double d_rpm_disp = d_rpm; double d_rpm_pos = 1000; for( int i = 0; i < 8; i++ ){ int digit = 0; // remembers digit if( d_rpm_disp / d_rpm_pos >= 1 ){ digit = d_rpm_disp / d_rpm_pos; d_rpm_disp -= digit * d_rpm_pos; } boolean dot = false; if( abs(d_rpm_pos - 1) < 0.001 ){ // with dot dot = true; } lc.setDigit(0, 7 - i, digit, dot); d_rpm_pos /= 10; } } } void d_count(void) { g_step++; }