I am a arduino noob and i am writing a sketch to read the number of pulses in analog pin and interpret it in morse characters (dot or dash).
my objective is that if there is a single pulse it should be interpreted as dot and if there are 2 pulses (time interval of < 0.2s) it should be interpreted as dash. (unlike conventional morse code where pulse time is measured).
my sketch so far is as below. i am always getting dot and i realize i have some logical errors and not able to debug.
your help is greatly appreciated.
thanks in advance.
unsigned long pt = 0;
String morse = "";
String c_morse = "";
int vth = 1023;
int m = 0;
void setup()
{
Serial.begin (38400);
}
void loop()
{
delay(3000);
float val = analogRead(A0);
unsigned long ct = millis();
if (val > vth)
{
Serial.println("1");
if (c_morse == "")
{
pt = ct;
}
if (ct - pt < 200)
{
Serial.println("2");
pt = ct;
m++;
delay(50);
}
}
if (ct - pt > 1000)
{
Serial.println("3");
if (m == 1)
{
morse = ".";
Serial.println(morse);
}
if (m ==2)
{
morse = "-";
Serial.println(morse);
}
c_morse += morse;
Serial.println(c_morse);
pt = ct;
m = 0;
}
}
More information needed. It appears like a digital counting problem where you would use one of the digital pins or use the analog pin as a digital input. No idea of what your signal looks like but if not a clean digital signal a comparator would clean it up, sometimes even a Schmidt trigger digital part will do.
Good Luck & Have Fun!
Gil
float val = analogRead(A0);
unsigned long ct = millis();
if (val > vth)
condition ever going to be true ifint vth = 1023;and never changes ?
analogRead returns an int(unsigned), not a float btw.
Actually looking at it i don't even see how you could be getting anything..., m=0 and stays that if (val>vth) is never true.
val will never be greater than vth since a 10 bit analog max value is 1023. Having said that, if you are checking for a logic high or low you really should be using a digital input and counting the number of pulses. Analog gives you a reading between 0 and 1023 corresponding to 0-5V.
You have not given a detailed enough specification to determine how to code this. Are you saying once a pulse starts at the end of 0.2s you will either have 1 or 2 pulses? How much time in between pulses? Also, what is generating the pulses? If it is a mechanical switch then you will need to debounce it.
Some comments on your code below
unsigned long pt = 0; // <--- should be initialized to millis()
String morse = "";
String c_morse = "";
int vth = 1023;
int m = 0;
void setup()
{
Serial.begin (38400);
}
void loop()
{
delay(3000); // <----------- why delay 3 seconds?
float val = analogRead(A0); // <-------- analog is an int!!!
unsigned long ct = millis();
if (val > vth) // <------ will never be true!!!
{
// *** WILL NEVER GET HERE ***
Serial.println("1");
if (c_morse == "")
{
pt = ct; // ???????????????????????
}
if (ct - pt < 200)
{
Serial.println("2");
pt = ct;
m++;
delay(50);
}
}
if (ct - pt > 1000)
{
Serial.println("3");
if (m == 1)
{
morse = ".";
Serial.println(morse);
}
if (m ==2)
{
morse = "-";
Serial.println(morse);
}
c_morse += morse;
Serial.println(c_morse);
pt = ct;
m = 0;
}
}
its a mechanical switch i am working on and it produces sharp voltage pulses like a Dirac delta function.
Hence i am using analog input pin and not digital pin.
here i am using a threshold of as 800 (in the earlier post its taken as 1023) as a pulse detection point.
initial delay (3s) to remove the random peaks during reset/starting serial monitors etc.
when the button is presses, the analog input pin reads the pulse, which i am filtering using vth(threshold voltage value)
since i need time stamp of the pulse, i am using pt and ct as two variables (previous timestamp and current timestamp) as marker and rolling over/reset (i.e., pt = ct command).
time interval of <0.2s between pulses (double click) is treated as dash and if the time interval is >0.2s the pulses are treated as 2 individual dots.
pulse debounce is taken care by using the delay of 50ms.
I hope i cleared the queries.
i will implement the said changes like float to int and initializing pt etc.
its a mechanical switch i am working on and it produces sharp voltage pulses like a Dirac delta function.
Hence i am using analog input pin and not digital pin.
It is the same pin, you should probably use INPUT_PULLUP and ground it out when on, and then using (digitalRead() == LOW) as active Arduino takes anything below 2v as LOW. Anyway just a recommendation, it should probably work as is.