0
\$\begingroup\$

Long time user, first time poster. I've started to fiddle around with Arduinos and electronics and I still have a hard time grasping some of the basic concepts sadly. Here is my issue.

I have this setup right now which works right as long as the square wave voltage is at 3 V. When I get to the 10-12 V range it starts calculating the wrong thing. I currently simulate the Tach signal via a signal generator that produces a square wave, but the real sensor itself will provide a square wave (50% duty cycle) with a voltage of 12 V and will pulse at 4 pulse per rotation.

eg : 1600 RPM = 106.667 Hz (1600*4/60)

Wiring diagram

I feel like I'm wired wrong but can't find he issue. I also tried to put a buck converter on the tach signal to no avail. I read about voltage dividers but don't fully grasp where it would go.

I'm using a arduino nano right now which doesn't really change anything to this issue I think. Also use a SH1106_128X64 OLED in case someone wants to test it. Here is the full code I run which I don't think is the source of the problem.

The overall logic is an interupt that counts pulses (FALLING) on PIN2 and calculates the RPM every 200 µs.

#include <Arduino.h>
#include <stdlib.h>
#include <U8g2lib.h>
#include <math.h>

U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
//U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

// '0', 20x24px
const unsigned char epd_bitmap_0 [] PROGMEM = {
  0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 
  0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 
  0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 
  0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x0f, 0xff, 
  0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f
};
// '2', 20x24px
const unsigned char epd_bitmap_2 [] PROGMEM = {
  0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 
  0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0xf0, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xf0, 0xff, 
  0x0f, 0xf0, 0xff, 0x0f, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 
  0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xff, 
  0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f
};
// '1', 20x24px
const unsigned char epd_bitmap_1 [] PROGMEM = {
  0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 
  0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 
  0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 
  0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xff, 0xff, 0x00, 0xff, 
  0xff, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00
};
// '3', 20x24px
const unsigned char epd_bitmap_3 [] PROGMEM = {
  0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 
  0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 
  0x0f, 0xff, 0xff, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 
  0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x0f, 0xff, 
  0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f
};
// '4', 20x24px
const unsigned char epd_bitmap_4 [] PROGMEM = {
  0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0x00, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xf0, 
  0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xf0, 0xff, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 
  0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 
  0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 
  0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f
};
// '5', 20x24px
const unsigned char epd_bitmap_5 [] PROGMEM = {
  0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0x00, 0x00, 0xff, 
  0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 
  0x0f, 0xff, 0xff, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 
  0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0xff, 0xff, 0x0f, 0xff, 
  0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f
};
// '6', 20x24px
const unsigned char epd_bitmap_6 [] PROGMEM = {
  0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0x00, 0x00, 0xff, 
  0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 
  0x0f, 0xff, 0xff, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 
  0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x0f, 0xff, 
  0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f
};
// '8', 20x24px
const unsigned char epd_bitmap_8 [] PROGMEM = {
  0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 
  0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 
  0x0f, 0xff, 0xff, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 
  0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x0f, 0xff, 
  0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f
};
// '9', 20x24px
const unsigned char epd_bitmap_9 [] PROGMEM = {
  0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 
  0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xf0, 
  0x0f, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 
  0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0xff, 0xff, 0x0f, 0xff, 
  0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f
};
// '7', 20x24px
const unsigned char epd_bitmap_7 [] PROGMEM = {
  0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 
  0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 
  0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 
  0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 
  0xf0, 0x0f, 0x00, 0xf0, 0x0f, 0x00, 0xf0, 0x0f
};

// 'BG_Top', 128x32px
const unsigned char epd_bitmap_BG_Top [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x1f, 0x00, 0x70, 0x00, 0x00, 0x1f, 0x00, 0xe0, 0x03, 0x00, 0x70, 0x00, 0x80, 0x0f, 0x00, 0xf8, 
  0x1b, 0x00, 0x60, 0x00, 0x00, 0x18, 0x00, 0x00, 0x03, 0x00, 0x78, 0x00, 0x80, 0x01, 0x00, 0x18, 
  0x1b, 0x00, 0x60, 0x00, 0x00, 0x1e, 0x00, 0xe0, 0x03, 0x00, 0x6c, 0x00, 0x80, 0x0f, 0x00, 0xf8, 
  0x1b, 0x00, 0x60, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0x00, 0x7c, 0x00, 0x00, 0x0c, 0x00, 0xd8, 
  0x1b, 0x00, 0x60, 0x00, 0x00, 0x03, 0x00, 0x60, 0x03, 0x00, 0x60, 0x00, 0x00, 0x0c, 0x00, 0xd8, 
  0x1f, 0x00, 0xf0, 0x00, 0x00, 0x1f, 0x00, 0xe0, 0x03, 0x00, 0x60, 0x00, 0x80, 0x0f, 0x00, 0xf8, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x04, 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x20, 
  0x04, 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x20, 
  0x04, 0x08, 0x20, 0x00, 0x01, 0x04, 0x20, 0x80, 0x00, 0x04, 0x10, 0x80, 0x00, 0x02, 0x10, 0x20, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x95, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x95, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x95, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x95, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x95, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x95, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x95, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xaa, 0xaa, 0xaa, 0xaa, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x55, 0x95, 
  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 
  0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f
};

// 'rpm', 20x9px
const unsigned char epd_bitmap_rpm [] PROGMEM = {
  0x00, 0x00, 0x00, 0xdf, 0xf7, 0x0f, 0xdb, 0xb6, 0x0d, 0xc3, 0xb6, 0x0d, 0xc3, 0xb6, 0x0d, 0xc3, 
  0xb6, 0x0d, 0xc3, 0xb7, 0x0d, 0xc0, 0x00, 0x00, 0xc0, 0x00, 0x00
};

// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 576)
const int epd_bitmap_allArray_LEN = 2;
const unsigned char* epd_bitmap_allArray[12] = {
  epd_bitmap_0,
  epd_bitmap_1,
  epd_bitmap_2,
  epd_bitmap_3,
  epd_bitmap_4,
  epd_bitmap_5,
  epd_bitmap_6,
  epd_bitmap_7,
  epd_bitmap_8,
  epd_bitmap_9
};


char rpmString[10];
int rpmStringLenght = 0;

volatile unsigned int pulseCount=0;
unsigned int pulseCountCopy = 0;
int currentRPM=0;
int previousRPM=0;
float timerRatio=0;
unsigned long pulseTimer = 0;
unsigned long pulseTimerPrevious = 0;
int pin = 2;
char printableRPM[] = "0";

//1 Minute in MicroSeconds
float MICROMINUTE = 60000000;
float diffPulseTimer;
boolean isDebug = true;

void setup()
{
  Serial.begin(9600);
  int checkPin = digitalPinToInterrupt(pin);
  
  if (checkPin == -1) {
    Serial.println("Not a valid interrupt pin!");
  } else {
    Serial.println("Valid interrupt pin");
    attachInterrupt(digitalPinToInterrupt(pin),PulseCounterISR,FALLING);
  }

  u8g2.begin();
  u8g2.setColorIndex(1);
  
  pulseTimerPrevious = micros(); 
}

void loop()
{
  pulseTimer = micros();
  if(pulseTimer - pulseTimerPrevious > 200000)
  {
    noInterrupts();
    //quickly copy and reset revCount and get a time stamp. Then restart the interrupts.
     pulseCountCopy = pulseCount;
    pulseCount=0;  
    interrupts();
    
    //DEBUG
    if(isDebug)
    {
      Serial.print("Pulse Count : " + String(pulseCountCopy));
    }
      
    diffPulseTimer = pulseTimer - pulseTimerPrevious;
    //DEBUG
    if(isDebug)
    {
      Serial.print(" Counts in: " + String(diffPulseTimer));
    }
    
    //Divider represents the PulseTimer duration in relation to a minute in MicroSeconds
    timerRatio = (MICROMINUTE/diffPulseTimer);
    //DEBUG
    if(isDebug)
    {
    Serial.print(" TimerRatio = " + String(timerRatio));
    }
    //RPM = Get 4 pulse per revolution so pulseCount/4 * the timerRatio and then rounded up to the hundreds so it doesn't display 998 rpm but 1000
    currentRPM = round((pulseCountCopy * timerRatio)/4.0 / 100)*100;
    //DEBUG
    if(isDebug)
    {
      Serial.println(" currentRPM = " + String(currentRPM));
    }
    if(currentRPM != previousRPM)
    {
      ltoa(currentRPM,rpmString,10);
      rpmStringLenght = strlen(rpmString);

      u8g2.firstPage();
      do{
        
        //For each digit of the number we parse the ASCII and get the value 
        for(int i=0;i<rpmStringLenght;i++)
        {
           //ASCII Converstion from rpmString ASCII value table (-48)
           u8g2.drawXBMP(10+22*i,38,20,24,epd_bitmap_allArray[rpmString[i]-48]);
        }
        u8g2.setColorIndex(1);//White Color
        u8g2.drawXBMP(0,0,128,32,epd_bitmap_BG_Top);
        u8g2.drawXBMP(103,50,20,9,epd_bitmap_rpm);
   
        u8g2.drawBox(2,14,map(currentRPM,0,6000,0,124),16);
      }
      while(u8g2.nextPage());

      previousRPM=currentRPM;
    }
    //Reset Pulse Timer Previous
    pulseTimerPrevious = pulseTimer;
  }
}

//Count Pulse whenever they occur via IRS (Interrupt)
void PulseCounterISR(){
  pulseCount++;
}
\$\endgroup\$
1
  • \$\begingroup\$ Welcome! Please inline your wiring diagram. Even better, draw a schematic of it. There is a built in schematic editor if you click on edit and then then schematic symbol. \$\endgroup\$
    – winny
    Mar 25 at 17:27

1 Answer 1

2
\$\begingroup\$

You have an 5V MCU.

It expects a 5V signal.

It won't see a 3V signal properly, and you are not allowed to give it more than 5V or you will damage the MCU with overvoltage.

You also haven't connected the signal generator ground to MCU. Either it is connected via some other route (through mains plugs and/or other cabling) or it is floating so it won't work due to being unconnected.

\$\endgroup\$
3
  • \$\begingroup\$ You made me realize that I actually wired the pullup resistor completely wrong. I fixed it. I think I'll be able to put the buck converter properly that way. Will circle back. \$\endgroup\$
    – sous
    Mar 25 at 21:56
  • \$\begingroup\$ @sous You can't use a buck converter for a pulse signal. The pull-up does not enable to use a buck regulator for this. \$\endgroup\$
    – Justme
    Mar 25 at 22:10
  • \$\begingroup\$ Would a simple voltage divider work then ? \$\endgroup\$
    – sous
    Mar 26 at 13:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.