Converting a Char into a Char* (serial read)

Hi,

I am trying to use the aJson library to control my arduino. The plan is to send a JSON string via serial or ethernet and the arduino parses the string (using the libary) and then acts approprately. I have figured out the parsing element, but I am havving some trouble with the serial aspect. The library requires the JSON string to be in a char*, but the serial read is a char. So I need some way to convert a char to a char*.

I have attached the code I have currently, I know it won’t compile because of the conversion.

Any help would be greatly appreciated.

#include <aJSON.h>
#include <string.h>

char* aJsonString;
aJsonObject* root = aJson.createObject();
aJsonObject* parm = aJson.createArray();

void setup()

{
  Serial.begin(9600);
  Serial.println("************************\nTesting aJson with RPC\n************************");
  Serial.println("**********************\nPlease Enter a JSON String\n**********************");
}

 

void loop()
{
  read_char();
  //aJsonString = read_char();
  // See what we received...
  if (aJsonString==0) {
    // Unknown input
  }
  else {
    if (int test = 0){
      test = 1;
      // Perform whatever actions are defined for this input
      ParseJSON();
    }
  }
}


char* read_char()
{
  // Wait until some data becomes available
  // on the USB cable (this will loop
  // forever if you don't send it anything)
  char data = -1;
  while ((Serial.available() < 0) || (data < 0)) {
    delay(1);
    data = Serial.read();
  }
  char *message = data; //I know this doesn't work, but this is essentially what I want to do.
  return message;
}

void ParseJSON()

{
  Serial.print("Starting to Parse: ");
  Serial.println(aJsonString);

  root = aJson.parse(aJsonString);

  aJsonObject* method = aJson.getObjectItem(root, "method");
  aJsonObject* params = aJson.getObjectItem(root, "params");
  aJsonObject* id = aJson.getObjectItem(root, "id");
  int ArraySize = aJson.getArraySize(params);

  int methodtype = method->type;
  int paramtype = params->type;
  int idtype = id->type;
  Serial.println(methodtype);
  Serial.println(paramtype);
  Serial.println(idtype);

  Serial.println("");
  Serial.println("** Printing the Parameters **");
  Serial.print("Method: ");
  Serial.println(method->valuestring);
  Serial.print("Params Array Size: ");
  Serial.println(ArraySize);
  for (int i = 0; i < ArraySize; i++){
    aJsonObject* test = aJson.getArrayItem(params, i);
    Serial.print("Parameter ");
    Serial.print(i);
    Serial.print(": ");
    Serial.println(test->valuestring);
  }
  Serial.print("Id: ");
  Serial.println(id->valuestring);
  Serial.println("");

  if(method->valuestring = "echo"){
    Serial.println("This demonstrates how to use the JSON output in an IF statement \n");
  }
  aJsonString = 0;
}

I think you are going to need a global buffer (char buff[255];) which you can fill with the characters as they arrive. You will need some way to determine when you have all the input characters. Then you terminate the string (buff[index] = '\0';) and pass the buffer to the library to parse (aJsonObject* jsonObject = aJson.parse(buff);). Don't worry that buff is a char [] and not a char *. When passed as a function argument they are indistinguishable (address of the first character of a null terminated string).

Thanks John,

I had to re-work the whole read in element in the end, but got it working :smiley: It’s not pretty, but I can tidy it up later. Thanks for the help

/*

This is a test script which:
* Waits for the user to input a JSON string into the serial window
* Collects the string 
* Parses the string 
* Outputs the details of the string (as per the standalone example)

NB: There is no error checking on the input. Incorrectly formated strings will still be parsed,
but will result in a nonsensical output

aJson_False is type 0
aJson_True is type 1
aJson_NULL is type 2
aJson_Int is type 3
aJson_Float is type 4
aJson_String is type 5
aJson_Array is type 6
aJson_Object is type 7
aJson_IsReference is type 128

*/

#include <aJSON.h>

char c[255];
char* message;
aJsonObject* root = aJson.createObject();
aJsonObject* parm = aJson.createArray();
int i = 0;
//This is a quick way of ensuring the ParseJSON function is only called once (until Reset() is called)
int runonce = 0; 


void setup()
{
  Serial.begin(9600);
  Serial.println("************************\nTesting aJson with RPC\n************************");
  Serial.println("**********************\nPlease Enter a JSON String\n**********************");
}


void loop()
{
  if (Serial.available() > 0) {
    char data;
    data = Serial.read();
    //slow the read in process, so we get all the characters
    delay(10);
    c[i] = data;
    i++;
  }
  else if (c[0] !=0 && runonce == 0) {
    runonce = 1;
    message = c;
    Serial.print("The full message is: ");
    Serial.println(message);
    ParseJSON(message);
  }
}

void Reset()
{
  runonce = 0;
  i = 0;
  message ="";
  c[0] = 0;
  Serial.println("************************\nTesting aJson with RPC\n************************");
  Serial.println("**********************\nPlease Enter a JSON String\n**********************");
}

void ParseJSON(char* aJsonString)
{
  Serial.print("Starting to Parse: ");
  Serial.println(aJsonString);

  root = aJson.parse(aJsonString);

  aJsonObject* method = aJson.getObjectItem(root, "method");
  aJsonObject* params = aJson.getObjectItem(root, "params");
  aJsonObject* id = aJson.getObjectItem(root, "id");
  int ArraySize = aJson.getArraySize(params);

  int methodtype = method->type;
  int paramtype = params->type;
  int idtype = id->type;
  Serial.println(methodtype);
  Serial.println(paramtype);
  Serial.println(idtype);

  Serial.println("");
  Serial.println("** Printing the Parameters **");
  Serial.print("Method: ");
  Serial.println(method->valuestring);
  Serial.print("Params Array Size: ");
  Serial.println(ArraySize);
  for (int i = 0; i < ArraySize; i++){
    aJsonObject* test = aJson.getArrayItem(params, i);
    Serial.print("Parameter ");
    Serial.print(i);
    Serial.print(": ");
    Serial.println(test->valuestring);
  }
  Serial.print("Id: ");
  Serial.println(id->valuestring);
  Serial.println("");

  if(method->valuestring = "echo"){
    Serial.println("This demonstrates how to use the JSON output in an IF statement \n");
  }
  Reset();
}

char *message = data; //I know this doesn't work, but this is essentially what I want to do.

If that is all you want to do then

char *message = &data; // which will have no meaning on leaving the read routine and data goes out of scope

You can buffer up strings and parse into other buffers then lex away when you have memory space. At least try and keep the strings short and parse a word at a time. Or you can read a char at a time and actively process if your match strings are organized well. But that takes a bit of technique and planning, not the standard approach. A state engine will usually do.