My "Strobe" sketch.

Just for the benefit for all, this is the working sketch:

#define outputpin 13

String Sfrequency = "";
int frequency;
void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(outputpin, OUTPUT);
}
void loop()
{
  while (Serial.available() > 0)
  {
    int newchar = Serial.read();
    if (isDigit(newchar))
    {
      Sfrequency += (char)newchar;
    }
    if (newchar == '\n')
    {
      Serial.println("frequency");
      Serial.println(Sfrequency);
      Serial.println("Value");
      Serial.println(Sfrequency.toInt());
      frequency = Sfrequency.toInt();
      Serial.println(frequency);
      Sfrequency = "";
    }
  }
  if (frequency >= 1)
  {
    digitalWrite(outputpin, HIGH);
    delay(1000/(2*frequency));
    digitalWrite(outputpin, LOW);
    delay(1000/(2*frequency));
  }
  

}

Enter a frequency up to 1kHz.

Enter 0 to stop the output.

lost_and_confused: ... String Sfrequency = ""; int frequency; ... Sfrequency += (char)newchar;

I believe this is a classical newbie problem when programming C. The first statement quoted above allocates an array of one byte containing a zero to terminate the string and create a pointer to this array. After this array is an int called frequency.

What you are effectively doing when appending characters to the Sfrequency-array is overwriting the frequency int.

What you need to do is to allocate an array that can contain all of the characters that you will add to it and put the characters into that.

Hope this helps. Good luck!

I believe this is a classical newbie problem when programming C

I believe this is a classical newbie problem when encountering the String class :stuck_out_tongue_closed_eyes:

Yeah, guilty as changed.

I still don't understand what is means to "read" input from the serial port.

So I found a serial reader which looks for the \n terminator - which had me going for a while as I forgot to set the "newline" in the window. But anyway....

I read the sketch as reading in each character and adding (concatenating?) them until it sees the \n.

Then there is this "ifdigit" which then magically makes it from a string into a real number which can be used in the program.

"Stupidly" my choice of names may be problematic as I didn't know the prefix S was reserved to qualify String.

Anyway, for some reason the sketch started to work. Still have to check the accuracy of the number entered and the output. But as it doesn't need to be THAT accurate, the adjustment could be easily enough done.

Now I just need to get a big transistor on the output and drive a heap of LEDs and make a strobe light and use it with that post I posted about the water and 25Hz a while ago.

My last comment was directed at "bengtb" - what s/he wrote relates to C strings, not the String class, and so was incorrect in this context.

Then there is this "ifdigit" which then magically makes it from a string into a real number which can be used in the program.

No, it just returns true if the character lies in the range '0'...'9' and false otherwise.

"Stupidly" my choice of names may be problematic as I didn't know the prefix S was reserved to qualify String.

There is no prefix "S" reserved for anything.

AWOL,

Ok, thanks.

But in my sketch, the stuff read in with the serial.read() is a string though - right?

So, given I type 50 that is more an ASCII string than a value. That is done with the "ifdigit()" - right?

And so then that variable - frequency - is usable in the sketch.

I can't just read the "Sfrequency" and use it huh?

Sorry, I am just head banging this sketch from other ones given in the example ones. Cutting parts and sticking them together to get what I want to be done.

Yeah, maybe I should research it a bit more, but I think this is how I "research" and/or learn.

Yes, probably not the best way, but just now alas it is the best way I can get to work for me.

:-/

But in my sketch, the stuff read in with the serial.read() is a string though - right?

No, the "stuff" read in with Serial.read is a character (char), but you're putting it in a [u]S[/u]tring, which is a class, as opposed to a C [u]s[/u]tring which is simply a "char" buffer with a null-terminator.

So, given I type 50 that is more an ASCII string than a value. That is done with the "ifdigit()" - right?

Wrong. The 50 you type in is two ASCII characters, with the specific values 0x35 and 0x30. They are neither a string, nor a String, until you make them into one or the other (or both). "ifdigit" simply returns "true" if the parameter is in the range 0x30..0x39 inclusive, "false" otherwise.

Apologies.

Char, String.

But as they are read in with that bit of code, the "value" in my Sfrequency isn't usable in that format.

I do need that bit of code to convert it to an integer.

I do need that bit of code to convert it to an integer

And here it is:

frequency = Sfrequency.toInt();

Good, I was on the right track.

Thanks for the reassurance.

Only very slightly tested, I wrote this at lunchtime - it doesn’t use String, it doesn’t use “delay” and it allows decimal fractions.

const byte strobePin = 13;

unsigned long halfPeriod;
bool enabled;

void setup()
{
  Serial.begin(9600);
  pinMode(strobePin, OUTPUT);
}

void loop()
{
  static unsigned long lastMicros;
  unsigned long currentMicros = micros ();
  if (enabled && 
     (currentMicros - lastMicros >= halfPeriod)) 
  {
    digitalWrite(strobePin, !digitalRead (strobePin));
    lastMicros = currentMicros; 
  }  
}

void serialEvent ()
{
  const byte bufferSize = 10;
  static char buffer [bufferSize + 1];
  static byte bufferIndex;

  while (Serial.available ()) 
  {
    char inChar = (char)Serial.read ();
    if (inChar == '\n') {
      float frequency = atof (buffer);
      if (frequency != 0.0) 
      {
        Serial.print ("Frequency = ");
        Serial.println (frequency);
        enabled = true;
        halfPeriod = 500000 / frequency;
      } 
      else 
      {
        enabled = false;
        digitalWrite(strobePin, LOW);
      }  
      bufferIndex = 0;
      buffer [0] = '\0';
    } 
    else 
    {
      if ((bufferIndex < bufferSize) && 
          (isdigit (inChar) || inChar=='.')) 
      {
        buffer [bufferIndex++] = inChar;
        buffer [bufferIndex] = '\0';
      }
    }  
  }
}

Thanks AWOL.

Shall download and try.

Ok, dumb question: void serialEvent ()

Where is it called/used?