morse code by counting analog pulses

Hello friends,

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

when is this

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;
  }

}

Hey guys, thank you for the reply.

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.

  1. initial delay (3s) to remove the random peaks during reset/starting serial monitors etc.

  2. when the button is presses, the analog input pin reads the pulse, which i am filtering using vth(threshold voltage value)

  3. 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).

  4. 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.

  5. 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.