Hello,
I am trying to convert a pwm signal to a frequency with an Arduino Uno.
Therefore I'm using an 4n35 optocoupler (to avoid any ground loop).
This works great but there is a problem with my code.
When I use my code in another code that puts info on the serial monitor the calculated value doesnt seem right anymore above a certain value. I
m trying to measure up to 1000Hz but in the bigger code the measurements are only accurate up to 200Hz. Above 200Hz the Arduino starts giving wrong values, like 6 times as high, along with some other crappy values.
When I measure the incoming signal at the Arduino with an oscilloscope everything looks normal.
Of course there is a maximum frequency that can be measured accurately but I don`t think it has to do something with that, does it?
As you can see I use MegunoLink Pro to log everything:D
I hope you can help me:)
The first code is the 'naked' code.
int val;
int prev_val = 0;
float t, cur_t;
int interruptPin = 2;
volatile int state = LOW;
void setup() {
Serial.begin(115200);
attachInterrupt(digitalPinToInterrupt(interruptPin), rpm, CHANGE);
}
void loop() {
}
void rpm() {
int sig = digitalRead(2);
if (sig == HIGH) val = HIGH;
else val = LOW;
if (prev_val == 0 && val == 1) {
cur_t = micros();
int hertz = 1000000 / (cur_t - t);
Serial.print("{TIMEPLOT:Speed|DATA|Speed|T|"); //MegunoLink
Serial.println(hertz);
Serial.println("}");
t = micros();
}
prev_val = val;
}
The second code, the integrated code:
#include "CommandHandler.h"
#include "MegunoLink.h"
#include <OneWire.h>
OneWire ds(3);//2
CommandHandler<> SerialCommandHandler;
TimePlot MyPlot;
int OnTime = 0;
int Trackbar = 0;
int Fan = 6;//3
int a = 0;
int b = 0;
int warningLed = LOW;
unsigned long previousMillis = 0;
const long interval = 100;
int ledState = LOW;
int val; //the digital value of the incoming analog signals
int prev_val = 0; //last value
float t, cur_t; //time variables
int interruptPin = 2;//3
volatile int state = LOW;
void setup() {
Serial.begin(115200);
SerialCommandHandler.AddVariable(F("OnTime"), OnTime);
SerialCommandHandler.AddVariable(F("Trackbar"), Trackbar);
pinMode(10, INPUT); //Set 10 at the Arduino as input
pinMode(Fan, OUTPUT);
pinMode(8, OUTPUT);
digitalWrite(8, LOW);
attachInterrupt(digitalPinToInterrupt(interruptPin), rpm, CHANGE);
//Set graph properties for Megunolink
MyPlot.SetTitle("Temperature sensors");
MyPlot.SetXlabel("Time in [h]");
MyPlot.SetYlabel("Degrees in [C]");
Serial.println("{TIMEPLOT|STYLE|Temp1:bn_1}");
Serial.println("{TIMEPLOT|STYLE|Temp2:rn_1}");
Serial.println("{TIMEPLOT|STYLE|Temp3:bn_1}");
Serial.println("{TIMEPLOT|STYLE|Temp4:rn_1}");
Serial.println("{TIMEPLOT|STYLE|Temp5:bn_1}");
Serial.println("{TIMEPLOT|STYLE|Temp6:rn_1}");
}
void loop() {
unsigned long currentMillis = millis();
byte i;
byte present = 0;
byte type_s = 0;
byte data[12];
byte addr[8];
int celsius;
//Write frequency to Megunolink, once every sensorcheck
if (a == 0) {
Table t;
t.SendData("Frequency", (Trackbar*0.3563)-3.2857, "Hz");
}
//Read out data sensors
if ( !ds.search(addr)) {
ds.reset_search();
delay(5);
Serial.println();
a = 0;
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); //Parasite power supply
delay(85);
present = ds.reset();
ds.select(addr);
ds.write(0xBE);
for ( i = 0; i < 9; i++) {
data[i] = ds.read();
}
int16_t raw = (data[1] << 8) | data[0];
byte cfg = (data[4] & 0x00);
if (cfg == 0x00) raw = raw & ~7;
//Conversion and display in MegunoLink
celsius = raw / 16.0;
a = ++a;
Serial.print("{TIMEPLOT:Temp");
Serial.print(a, DEC);
Serial.print("|DATA|Temp");
Serial.print(a, DEC);
Serial.print("|T|");
Serial.print(celsius);
Serial.print("}");
Serial.println("");
//Warning alarm light coolant temp
if (((a<=4) && (celsius > 25))||((a>4) && (celsius > 27))) {
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
ledState=!ledState;
digitalWrite(8, ledState);
}
}
else {
digitalWrite(8, LOW);
}
}
//RPM Measurment
void rpm() {
int sig = digitalRead(3); //read raw value of hall sensor
if (sig == HIGH) val = HIGH; //convert it to digital 0,1 form
else val = LOW;
if (prev_val == 0 && val == 1) { //check for rising edge
cur_t = micros(); //Set time
int hertzDyno = 1000000 / (cur_t - t); // [1/s]
Serial.print("{TIMEPLOT:Speed|DATA|Speed|T|");
Serial.print(hertzDyno);
Serial.println("}");
t = micros(); //Reset time
}
prev_val = val; //Reset value
}