Serial input char*

Hi,

I have a library and one of the functions I want to use takes char* as an argument.
What I want to do, is passing exactly the raw data I want to serial.

For example I want to send to serial port this "000111101100000001100001" and do the follow pseudo example

void loop(void) {
if (Serial.available() > 0)
{
some_kind_of_a_buffer[received++] = Serial.read();
buffer[received] = '\0';
}
if (buffer not empty)
myLib.sendData(buffer);
}

is that possible, can anyone provides an example?

Thanks in advance

For testing you could try the below with the serial monitor.

// zoomkat 7-30-11 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial test 0021"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(1);  //delay to allow byte to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

  if (readString.length() >0) {
    Serial.println(readString);

    readString="";
  } 
}

some_kind_of_a_buffer

would be char.

is that possible

Yes.

can anyone provides an example?

There are about a bazillion, at last count, examples around.

zoomkat:
For testing you could try the below with the serial monitor.

// zoomkat 7-30-11 serial I/O string test

// type a string in serial monitor. then send or enter
// for IDE 0019 and later

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial test 0021"); // so I can keep track of what is loaded
}

void loop() {

while (Serial.available()) {
    delay(1);  //delay to allow byte to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

if (readString.length() >0) {
    Serial.println(readString);

readString="";
  }
}

nice example but I want to call mylib.send(char*)

PaulS:

some_kind_of_a_buffer

would be char.

is that possible

Yes.

can anyone provides an example?

There are about a bazillion, at last count, examples around.

JHaskell's Blog: Serial Comm Fundamentals on Arduino

I study the article and see if that helps

jambel:

zoomkat:
For testing you could try the below with the serial monitor.

// zoomkat 7-30-11 serial I/O string test

// type a string in serial monitor. then send or enter
// for IDE 0019 and later

String readString;

void setup() {
  Serial.begin(9600);
  Serial.println("serial test 0021"); // so I can keep track of what is loaded
}

void loop() {

while (Serial.available()) {
    delay(1);  //delay to allow byte to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

if (readString.length() >0) {
    Serial.println(readString);

readString="";
  }
}

nice example but I want to call mylib.send(char*)

perhaps a conversion from String to char*

nice example but I want to call mylib.send(char*)

char test[] = "SomeStuff";

void fun(char *arr)
{
}

void setup()
{
}

void loop()
{
  fun(test);
}

will work. Pointers and arrays are very closely linked.

PaulS:

nice example but I want to call mylib.send(char*)

char test[] = "SomeStuff";

void fun(char *arr)
{
}

void setup()
{
}

void loop()
{
  fun(test);
}



will work. Pointers and arrays are very closely linked.

You do this with same types. The friend above creates a String, how can I convert it to char*?

Don't use a String to receive characters! You can too easily use up all the available RAM. I suggest declaring a fixed-size character array to hold the received characters. You will need to decide what is the maximum number of characters you want to receive, and what to do if you receive more than that.

When you have received the characters and appended a null character on the end, just pass your char[] buffer to the function. It will be converted to a char* pointer automatically.

I'd provide the code, but you haven't said how you want to determine when you have read the whole string. Maybe a delimiter character at the end of the string? Or a timeout?

perhaps a conversion from String to char*

Perhaps you can more clearly explain just what you want to accomplish. If you are concerned with single characters/bytes, perhaps the below is of interest.

byte INFO;

void setup (){
  Serial.begin (9600);
}

void loop ()
{
  if(Serial.available ())  
  {
    INFO = Serial.read();
    Serial.print(INFO);
  }
}

zoomkat:

perhaps a conversion from String to char*

Perhaps you can more clearly explain just what you want to accomplish. If you are concerned with single characters/bytes, perhaps the below is of interest.

byte INFO;

void setup (){
 Serial.begin (9600);
}

void loop ()
{
 if(Serial.available ())  
 {
   INFO = Serial.read();
   Serial.print(INFO);
 }
}

I don't want to print, I want to collect this kind of serial input to a char* buffer (000111101100000001100001) and after that pass it to a lib like myLib.send(buffer);

I want to collect this kind of serial input to a char* buffer

The String class has a toCharArray() method that will give you a char array from the String in zoomkat's code.

PaulS:

I want to collect this kind of serial input to a char* buffer

The String class has a toCharArray() method that will give you a char array from the String in zoomkat’s code.

Thanks for the tip

// zoomkat 7-30-11 serial I/O string test
// type a string in serial monitor. then send or enter
// for IDE 0019 and later
#include <myLib.h>

myLib mylib = myLib();

String readString;

void setup() {
  Serial.begin(9600);
}

void loop() {

  while (Serial.available()) {
    delay(1);  //delay to allow byte to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

  if (readString.length() >0) {
//    Serial.println(readString);
    char t[25];
    readString.toCharArray(t,25);
    mylib.send(t);
    readString="";
    Serial.println(t);
  } 
}

but myLib doesn’t seems to reply :frowning:

SOLVED!

Thanks a lot guys, the reason it wasn't reply is that I forgot to init :astonished:

I appreciate your help, thank you!

// for IDE 0019 and later
#include <RCSwitch.h>
#include <WString.h>

Unless you are using an old IDE, you probably don’t need the WString.h, as I think it is included in the string functions of IDE 0019 and later.

Another issue…

As I said everything works perfect from serial monitor but when it gets to my C# serial monitor it doesn’t work.

C# Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;	    // Serial stuff in here.

namespace Serial
{
    class Program
    {
	  static SerialPort port;
	  static void Main(string[] args)
	  {
		int baud = 9600;
		string name = "/dev/ttyACM0";
		BeginSerial(baud, name);
		port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
		port.Open();

		for (; ; )
		{
		    Console.Write("> ");
		    port.WriteLine(Console.ReadLine());
		}
	  }

	  static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
	  {
		for (int i = 0; i < (10000 * port.BytesToRead) / port.BaudRate; i++)
		    ;	 //Delay a bit for the serial to catch up
		Console.Write(port.ReadExisting());
		Console.WriteLine("");
		Console.WriteLine("> ");
	  }

	  static void BeginSerial(int baud, string name)
	  {
		port = new SerialPort(name, baud);
	  }

	  static int GetBaudRate()
	  {
		try
		{
		    return int.Parse(Console.ReadLine());
		}
		catch
		{
		    Console.WriteLine("Invalid integer.  Please try again:");
		    return GetBaudRate();
		}
	  }
    }
}

Arduino:

#include <mySwitch.h>

mySwitch myLib = mySwitch();

boolean sensorActive = false;
boolean previousSensorState = false;

int txPin = 4;
int pirPin = 3;
int tempPin = 0; 
int photocellPin = 1;
int photocellReading;

unsigned long cntr = 0;

String readString;

void setup(void) {
  Serial.begin(9600);

  myLib.enableTransmit(txPin);
  myLib.enableReceive(0, output);

  pinMode(pirPin, INPUT);
  digitalWrite(pirPin, LOW);

  sensorActive = false;
  previousSensorState = false;
}
 
void loop(void) {
  
  while (Serial.available())
  {
    delay(1); //delay to allow byte to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

  if (readString.length() == 24)
  {
    myLib.disableReceive();
    char inBin[25];
    readString.toCharArray(inBin,25);
    myLib.send(inBin);
    myLib.enableReceive(0, output);
    Serial.println("ACTIVITY");
  }
  else if (readString.toUpperCase() == "TEMP")
  {
    // Temp measurement
    int tempc = analogRead(tempPin);  

    tempc = (5 * tempc * 100.0) / 1024.0;
    int tempf = (tempc * 9)/ 5 + 32;
     
    Serial.print(tempc); Serial.print("C"); Serial.println("/"); //Serial.print(tempf); Serial.println("F"); 
  }
  else if (readString.toUpperCase() == "LIGHT")
  {
    // Light measurement
    photocellReading = analogRead(photocellPin);
     
    // We'll have a few threshholds, qualitatively determined
    if (photocellReading < 10) {
      Serial.println("Dark");
    } else if (photocellReading < 200) {
      Serial.println("Dim");
    } else if (photocellReading < 500) {
      Serial.println("Light");
    } else if (photocellReading < 800) {
      Serial.println("Bright");
    } else {
      Serial.println("Very bright");
    }
  }
  else if (readString.toUpperCase() == "SIGKILL")
    Serial.println("SIGKILL");  
  
  readString = "";
}

void output(unsigned long decimal, unsigned int length, unsigned int delay, unsigned int* raw) {
// some code
}

Any ideas?

I put some Serial.print(c) in while and after the loop a Serial.print(readString). Now I see in my app that it prints the results but no action on if/else statements

You have issues with both the C# code and the Arduino code.

		for (int i = 0; i < (10000 * port.BytesToRead) / port.BaudRate; i++)
		    ;	 //Delay a bit for the serial to catch up

This is useless. The compiler is smarter than you. It will see that the loop does nothing and remove it. You should too.

		string name = "/dev/ttyACM0";

What OS are you running on? As far as I know, C# only works on Windows, and this is not a Windows serial port name.

On the Arduino:

mySwitch myLib = mySwitch();

Lose the parentheses.

Class names generally start with a capital letter (Serial, Client, Server, etc.). You haven’t shown your code for your library, so we have no clue what it does.

but myLib doesn’t seems to reply

Show the code. Otherwise, you’re on your own.

  while (Serial.available())
  {
    delay(1); //delay to allow byte to arrive in input buffer
    char c = Serial.read();
    readString += c;
  }

zoomkat’s protestations carry little weight with me. You need to add an end-of-packet marker, and read serial data until that end of packet marker arrives. Get rid of the useless delay.

As I said everything works perfect from serial monitor but when it gets to my C# serial monitor it doesn’t work.

As has been said before, “it doesn’t work” is whining. “It does this, but I want it to do that” is useful information. We don’t do well with whining here. At least, I don’t.

wow, very aggressive mate :expressionless:

The library isn’t mine and the author don’t have an open licence, so…

Concerning the code, is parts from the internet. When tests and debug completed I do formation

As I said, the problem is in IF statements, they are not evaluate also I know that what I’ve send is taken since Serial.print(readString) tells me that

Thanks for your reply

As I said, the problem is in IF statements, they are not evaluate also I know that what I've send is taken since Serial.print(readString) tells me that

But, we can't see where you put that, or exactly how you are printing stuff, or what you are sending or seeing.

Serial.print("Received [");
Serial.print(readString);
Serial.println("]");
Serial.print("Length: ");
Serial.print(readString.length());

might reveal a cause.