SIM900 GSM/GPRS not getting a proper AT+CREG? answer - arduino

I'm using an Arduino UNO with attached IComsat SIM900 GSM/GPRS shield.
Using the following tutorial: Arduino Live GPS Tracker I'm stuck with the AT+CREG? command, which checks if the SIM-card is registered at the provider.
The following logic is used:
In the GSM_HTTP.INO file within the "void setup()" function, the following line gets executed modem.checkNetwork();
void setup() {
Serial.begin(9600);
Serial.println("GM862 monitor");
modem.switchOn(); // switch the modem on
delay(4000); // wait for the modem to boot
modem.init(); // initialize the GSM part of Module
modem.version(); // request modem version info
while (!modem.isRegistered()) {
delay(1000);
modem.checkNetwork(); // check the network availability
}
}
The function "checkNetwork()" is part of the included library GSM862.cpp and looks like this:
void GM862::checkNetwork() {
char buf[BUF_LENGTH];
char result;
requestModem("AT+CREG?", 1000, true, buf);
result = buf[21];
if (result == '1') {
state |= STATE_REGISTERED;
}
else {
state &= ~STATE_REGISTERED;
}
}
Now this is the important part: The value of "result" that gets received by the function "requestModem" returns cryptic values, but no netword status (number 0-5) which is why there is a endless loop trying to register without error or success message.
As this function gets the "buf" variable out of the function "requestModem" in GSM862.cpp, I've had a look at it as well:
byte GM862::requestModem(const char *command, uint16_t timeout, boolean check, char *buf) {
byte count = 0;
*buf = 0;
modem->flush();
modem->println(command);
count = getsTimeout(buf, timeout);
return count;
}
In order to have a look into the relevant variables for debugging purposes I've changed the last two functions into the following code:
-->checkNetwork
void GSM862::checkNetwork() {
char buf[BUF_LENGTH];
char result;
requestModem("AT+CREG?", 1000, true, buf);
result = buf[21];
Serial.print("Debugging buf2:");
Serial.print(buf[21]);
Serial.print("Debugging buf2:");
Serial.print(buf[1]);
Serial.print("Debugging buf2:");
Serial.print(buf[0]);
Serial.print("Debugging result2:");
Serial.println(result);
if (result == '1') {
state |= STATE_REGISTERED;
Serial.println("Network registered, home network...");
}
else {
state &= ~STATE_REGISTERED;
if(result == '0'){
Serial.println("Network not registered, not searching for a new operator to register to...");
}
if(result == '2'){
Serial.println("Still searching for an operators network to register to...");
}
if(result == '3'){
Serial.println("Network registration denied...");
}
if(result == '4'){
Serial.println("Network registration state unknown, probably still starting up...");
}
if(result == '5'){
Serial.println("Network registered, roaming...");
}
}
}
--> request Modem
byte GSM862::requestModem(const char *command, uint16_t timeout, boolean check, char *buf) {
byte count = 0;
*buf = 0;
modem->flush();
modem->println(command);
count = getsTimeout(buf, timeout);
Serial.print("Debugging command1:");
Serial.println(command);
Serial.print("Debugging count1:");
Serial.println(count);
Serial.print("Debugging buf1:");
Serial.println(buf);
Serial.print("Debugging timeout1:");
Serial.println(timeout);
return count;
}
Like I've mentioned above, it seems that the value out of "result" of the function "checkNetwork" which is actually the value of "buf[21]", displays a cryptic value when displayed on the terminal via Serial.println();
Do you have any idea why or what the exact problem is?

Network registration information (CREG) output depends on modem configuration.
By sending "AT+CREG=0" one can disable network registration code (which is your case)
By sending "AT+CREG=1" one can enable network registration
By sending "AT+CREG=2" one can enable network registration code with
location information (location area code and cell ID)
Options 2. and 3. will also automatically emit +CREG messages upon modem boot/network change.
ps: one should not forget to save current AT configuration by executing AT&W
more details on CREG can be found in "SIM900 AT COMMAND MANUAL"

Related

How to pass the this pointer to a task inside a class?

I am creating a library to manage our wifi network connection on many ESP32 devices.
Inside my library, i have a task that is looping with a 1 second pause started with an xTaskCreate inside my .begin() function. The problem is that i can't start the task if i haven't make it static in my .h file. So once the task is declared as static, i don't have access to the this-> pointer inside this task. Is there anyway i can send the this-> pointer inside my task like in parameters or something like that ?
Here is some code:
class EraWiFi{
public:
EraWiFi();
/*!
* #brief Initialize WiFi
* #return Returns true if successful
*/
bool begin(fs::FS &fs);
/*!
* #brief Start EraWiFi service
* #return Returns true if successful
*/
void downloadWiFi();
private:
static void wifiTask(void * parameter);
};
bool EraWiFi::begin(fs::FS &fs){
File file = fs.open("/WiFi.json", FILE_READ);
if(file){
DynamicJsonDocument wifi(2048);
DeserializationError error = deserializeJson(wifi, file);
file.close();
if (!error){
Serial.println("We have a VALID WiFi.json configurations file!");
Serial.println("Adding wifi networks:");
for (JsonArray arr : wifi.as<JsonArray>()){
Serial.print("SSID: ");
Serial.print(arr[0].as<char*>());
Serial.print(", KEY: ");
Serial.println(arr[1].as<char*>());
wifiMulti.addAP(arr[0].as<char*>(), arr[1].as<char*>());
}
}else{
Serial.println("We don't have a VALID WiFi.json configurations file!");
}
}else{
Serial.println("There is no WiFi.json configurations file!");
}
wifiMulti.addAP("Testing", "1234");
xTaskCreate(
this->wifiTask, // Function that should be called
"WiFiTask", // Name of the task (for debugging)
10000, // Stack size (bytes)
(void*)&this, // Parameter to pass
1, // Task priority
NULL // Task handle
);
return true;
}
void EraWiFi::downloadWiFi(){
Serial.println("Downloading WiFi.json from ErabliTEK Server.");
HTTPClient http;
// Send request
http.useHTTP10(true);
String url = "https://testing.testing.com/wifis/getWiFi/";
http.begin(url);
int httpResponseCode = http.GET();
if(httpResponseCode == HTTP_CODE_OK){
// Parse response
DynamicJsonDocument doc(2048);
DeserializationError error = deserializeJson(doc, http.getStream());
// Disconnect
http.end();
if (!error){
File file = fs.open("/WiFi.json", FILE_WRITE);
if(file){
// Serialize JSON to file
if (serializeJson(doc, file) == 0) {
Serial.println("Error saving WiFi.json!");
Serial.println(http.getString());
}else{
Serial.println("Succesfully saved WiFi.json!");
}
}
// Close the file
file.close();
}else{
Serial.println("Error downloading WiFi.json");
}
}else{
Serial.println("Problem connecting to " + url + " with http code: " + String(httpResponseCode));
}
}
void EraWiFi::wifiTask(void * parameters){
bool wifiConnected = false;
for(;;){
uint8_t wifiStatus = wifiMulti.run();
if((wifiStatus != WL_CONNECTED) and wifiConnected) {
wifiConnected = false;
Serial.println("WiFi not connected!");
}else if((wifiStatus == WL_CONNECTED) and !wifiConnected){
wifiConnected = true;
Serial.println("WiFi Connected.");
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
Serial.print("KEY: ");
Serial.println(WiFi.psk());
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
EraWiFi::downloadWiFi();
}
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
You're already doing that, you just don't realize it. Have a look at the FreeRTOS documentation on xTaskCreate() which explains how the fourth parameter pvParameters is a void pointer that gets passed on to the new task as its (one and only) input parameter.
The commented line here means you're taking the address of your EraWiFi object and passing it to the task:
xTaskCreate(
this->wifiTask,
"WiFiTask",
10000,
(void*)&this, //< Pointer gets forwarded to the task
1,
NULL
);
To use the pointer inside your task, you only need to cast it back from void*:
void EraWiFi::wifiTask(void * parameters){
EraWifi* p = static_cast<EraWifi*>(parameters); //< That's the same pointer
p->someMethod();
...
PS. Also note (before you poke at the same object from different threads, possibly causing hard-to-find bugs) that FreeRTOS provides excellent inter-thread communication facilities - the queues and task notifications often being the most useful ones. Check out their tutorial/book for an explanation.

Unable to store stream data in variable in Arduino programming

I'm unable to store the serial.port value in a variable. I want to send a message from Android telnet app, on and off. If on comes I want to print fan on, if off comes I want to print off. I'm able to print on and off while I'm statically fixing value. I'm unable to store the stream in a variable.
String stringOne;
void setup() {
digitalWrite(13, LOW);
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// send an intro:
Serial.println("\n\nString substring():");
Serial.println();
pinMode(13,OUTPUT);
}
void loop() {
digitalWrite(13,LOW);
// Set up a String:
stringOne ="+IPD 0,14 :ON";
int length = stringOne.length();
Serial.println(stringOne.length());
Serial.println(stringOne);
if (Serial.available() > 0) {
// substring(index) looks for the substring from the index position to the end:
if (stringOne.substring(length-2,length) == "ON") {
Serial.println("FAN ON");
digitalWrite(13,HIGH);
// delay(2000);
}
if (stringOne.substring(length-3,length) == "OFF") {
Serial.println("FAN OFF");
digitalWrite(13,LOW);
// delay(2000);
}
}
// you can also look for a substring in the middle of a string:
// do nothing while true:
while (true);
}
Well, while editing your question, I couldnt help noticing that infinite loop at the end of your code.
// do nothing while true:
while(true)
In this case, even if your code was all right, you cant expect to get next data.
void loop --> Remember it is itself a infinite loop
update 1:
your logic to use the serial port is wrong;
Remember, serial port only recieves a single character at a time.
if you send "hello" from pc, at the other end, arduino will recieve h, e, l, l, o
The trick is to collect all letters into a array. and then use our logic in it.
char commandbuffer[20]; //an array to hold our characters
int i=0;
if (Serial.available() > 0) {
while( Serial.available() >0) { //read until all data we send arrives
char c = Serial.read();
commandbuffer[i]= c; //we are actually storing it one by one
i++;
}
}
commandbuffer[i]='\n';
for(int j = 0; j<i; j++){
Serial.print(commandbuffer[j]);// and show it one by one too
}
now when you send "hello", it will print hello back. I hope this give you some idea. Happy coding.

Arduino + ESP8266, How can i send Continous Get Request?

I have a code that was available on this website https://hackaday.io/project/3072/instructions . I made the code work by modifying it a little but the main problem is that it serves the GET request only once. What i want is continuous page fetch and there should be no TCP connection closing.
I have tried different methods but the connection always breaks after 1 GET request.
Moreover, if i do not send any GET request then it serves the domain's index page continuously without breaking TCP connection.
This is the original code http://dunarbin.com/esp8266/retroBrowser.ino.
And this is mine.
#define SSID "vivek"
#define PASS "bustedparamour21"
#define DEST_HOST "www.electronics2work.com"
#define DEST_IP "31.170.161.234"
#define TIMEOUT 10000 // mS
#define CONTINUE false
#define HALT true
#define ECHO_COMMANDS // Un-comment to echo AT+ commands to serial monitor
// Print error message and loop stop.
void errorHalt(String msg)
{
Serial.println(msg);
Serial.println("HALT");
while(true){};
}
// Read characters from WiFi module and echo to serial until keyword occurs or timeout.
boolean echoFind(String keyword)
{
byte current_char = 0;
byte keyword_length = keyword.length();
// Fail if the target string has not been sent by deadline.
long deadline = millis() + TIMEOUT;
while(millis() < deadline)
{
if (Serial1.available())
{
char ch = Serial1.read();
Serial.write(ch);
if (ch == keyword[current_char])
if (++current_char == keyword_length)
{
Serial.println();
return true;
}
}
}
return false; // Timed out
}
// Read and echo all available module output.
// (Used when we're indifferent to "OK" vs. "no change" responses or to get around firmware bugs.)
void echoFlush()
{while(Serial1.available()) Serial.write(Serial1.read());}
// Echo module output until 3 newlines encountered.
// (Used when we're indifferent to "OK" vs. "no change" responses.)
void echoSkip()
{
echoFind("\n"); // Search for nl at end of command echo
echoFind("\n"); // Search for 2nd nl at end of response.
echoFind("\n"); // Search for 3rd nl at end of blank line.
}
// Send a command to the module and wait for acknowledgement string
// (or flush module output if no ack specified).
// Echoes all data received to the serial monitor.
boolean echoCommand(String cmd, String ack, boolean halt_on_fail)
{
Serial1.println(cmd);
#ifdef ECHO_COMMANDS
Serial.print("--"); Serial.println(cmd);
#endif
// If no ack response specified, skip all available module output.
if (ack == "")
echoSkip();
else
// Otherwise wait for ack.
if (!echoFind(ack)) // timed out waiting for ack string
if (halt_on_fail)
errorHalt(cmd+" failed");// Critical failure halt.
else
return false; // Let the caller handle it.
return true; // ack blank or ack found
}
// Connect to the specified wireless network.
boolean connectWiFi()
{
String cmd = "AT+CWJAP=\""; cmd += SSID; cmd += "\",\""; cmd += PASS; cmd += "\"";
if (echoCommand(cmd, "OK", CONTINUE)) // Join Access Point
{
Serial.println("Connected to WiFi.");
return true;
}
else
{
Serial.println("Connection to WiFi failed.");
return false;
}
}
// ******** SETUP ********
void setup()
{
Serial.begin(9600); // Communication with PC monitor via USB
Serial1.begin(9600); // Communication with ESP8266 via 5V/3.3V level shifter
Serial1.setTimeout(TIMEOUT);
Serial.println("ESP8266 Demo");
delay(2000);
Serial.println("Module is ready.");
echoCommand("AT+GMR", "OK", CONTINUE); // Retrieves the firmware ID (version number) of the module.
echoCommand("AT+CWMODE?","OK", CONTINUE);// Get module access mode.
// echoCommand("AT+CWLAP", "OK", CONTINUE); // List available access points - DOESN't WORK FOR ME
echoCommand("AT+CWMODE=1", "", HALT); // Station mode
echoCommand("AT+CIPMUX=1", "", HALT); // Allow multiple connections (we'll only use the first).
//connect to the wifi
boolean connection_established = false;
for(int i=0;i<5;i++)
{
if(connectWiFi())
{
connection_established = true;
break;
}
}
if (!connection_established) errorHalt("Connection failed");
delay(5000);
//echoCommand("AT+CWSAP=?", "OK", CONTINUE); // Test connection
echoCommand("AT+CIFSR", "", HALT); // Echo IP address. (Firmware bug - should return "OK".)
//echoCommand("AT+CIPMUX=0", "", HALT); // Set single connection mode
}
// ******** LOOP ********
void loop()
{
// Establish TCP connection
String cmd = "AT+CIPSTART=0,\"TCP\",\""; cmd += DEST_IP; cmd += "\",80";
if (!echoCommand(cmd, "OK", CONTINUE)) return;
delay(2000);
// Get connection status
if (!echoCommand("AT+CIPSTATUS", "OK", CONTINUE))
return;
// Build HTTP request.
cmd = "GET /";
cmd +="iot/graphing.php?a=1&b=ldr&c=41 ";
cmd += "HTTP/1.1\r\nHost: ";
cmd += DEST_HOST;
cmd += ":80\r\n\r\n";
// Ready the module to receive raw data
if (!echoCommand("AT+CIPSEND=0,"+String(cmd.length()), ">", CONTINUE))
{
echoCommand("AT+CIPCLOSE", "", CONTINUE);
Serial.println("Connection timeout.");
return;
}
// Send the raw HTTP request
echoCommand(cmd, "OK",CONTINUE ); // GET
// Loop forever echoing data received from destination server.
while(true)
while (Serial1.available())
Serial.write(Serial1.read());
errorHalt("ONCE ONLY");
}
This code makes get request only once. How can i make it serve GET request Continously without closing TCP connection?
THANKS in Advance!!
You need to close your connection using AT+CIPCLOSE and then start a new connection again.
For example, if you need to make two connections everytime(like making connection with 2 websites) , you can make 1 connection, then close this connection. Now make another connection and close it.
I made 2 connections in my loop() function using above logic and it is working fine.

Initializing Xbee S1 by an Arduino mini pro

I am trying to configurate my XBee module by an Arduino pro mini that is connected to my computer by de FTDI basic from sparkfun.
I already can write and send data from the Xbee to another Xbee module by the Arduino.
My problem is that I want to configure the Xbee by the arduino. I am sending ‘+++’ with the arduino to my Xbee and want to receive the ‘OK’ from the Xbee with the serial monitor from the arduino editor. The problem is that I can send it but never receive and ‘OK’, and when I am trying to configure the Xbee the configuration never happened. So I cant reach the Xbee command line.
uint8_t pinRx = 0, pinTx = 1; //Initialise pins on the Arduino
char GotChar;
long BaudRate = 4800;
int incomingByte=0;
SoftwareSerial mySerial( pinRx , pinTx ); //Initialise SoftwareSerial
void init_USB()
{
Serial.begin(BaudRate);
Serial.println("Start");
mySerial.begin(BaudRate);
}
void init_XBee()
{
Serial.begin(9600);
int check = 0;
while(T_XBEE_CONTROLLER_CheckOK() == 0)
{
Serial.println("CheckOK");
Serial.write("+++");
delay(2000);
}
Serial.println("ATCH 8\r");
delay(2000);
Serial.write("ATID 1234\r");
delay(2000);
Serial.write("+++");
delay(2000);
Serial.write("ATPL 0\r");
delay(2000);
Serial.write("+++");
delay(2000);
Serial.write("ATAP 2\r");
delay(2000);
}
int T_XBEE_CONTROLLER_CheckOK()
{
char ch[2];
ch[0] = 0x00;
while(! ((ch[0] == 'O' ) && (ch[1] == 'K') ))
{
ch[0] = mySerial.read();
ch[1] = mySerial.read();
if((ch[0] != 'O') && (ch[1] != 'K') && (ch[2] != '\r'))
{
Serial.println("FAILED");
return 0;
}
Serial.println("SUCCES");
return 1;
}
return 0;
}
it is a stupid answer but first of all, you should check that your Xbee is configured as AT device instead of API device. If it is API mode, the module wont understand the messages.
To do that you just have to use X-CTU application and read the configuration of the module, and change it to AT device.
Hope that helps.
Thanks for the response and the help, and also sorry for the late response.
I already solved the problem. The problem was the function write(). If you want to reach the command mode from the XBee you should only send "+++". If there is some kind of character behind the "+++" you can't reach the command line. The function write put a (for me) unknown character behing the "+++". So that's the problem for not reaching the command line.
To resolve this problem just use the function print("+++"). After using this function it is possible to reach the command line.
You have to read from the serial right after you send the +++ command, because this is where the xbee writes 'OK'. Also a better way to respect the guard times is to wait for a reply, and test to see if it is 'OK'.
Here is my code, I don't remember if it was working the last time I checked but I will just paste it here and you can modify it as you like. All it does is broadcast A1, B2, C3, etc.
There's a lot of commenting out where I was experimenting, but the regular comments are informative. Make sure you go through it step by step, it's quite simple when you get your head around it. Don't forget to change the destination address low to 0xFFFF if you want to broadcast.
In the end you'll come to the same realisation I did that AT mode is not suitable for configuring the xbee by writing programs.
For example I had an xbee constantly transmitting the number '2', and when another xbee was entering command mode using this code, it would receive the number 2 from the remote xbee when it should have received the 'OK' message from the local xbee, thus the program didn't acknowledge it being in command mode and breaking. When entering command mode you'd think an xbee would turn it's receiver off, but that's not the case so you can easily get into trouble.
If you want to do it the right way, have a look at API mode. I have series 1 xbee's so I'm implementing the Digimesh protocol, which so far I haven't seen anyone online do, but it's almost identical to the Zigbee so it's easy. If you'd like I can give you my code for that which can serve as a simple example.
/*
unicast_configure
Configure an XBee for unicast transmission and transmit
some characters to test
*/
#include <SoftwareSerial.h>
// Pins on Bees Shield:
SoftwareSerial xbee(2, 3); // TX, RX
boolean configured;
char c = 'A';
boolean configureRadio() {
// Set the data rate for the SoftwareSerial port:
xbee.begin(9600);
// Put the radio in command mode:
Serial.write("Entering command mode\r");
delay(1000);
while(xbee.available()>0) {xbee.read();}
xbee.write("+++");
while(xbee.available()>0) {xbee.read();}
//delay(1000);
//while(xbee.available() > 0) {Serial.write(xbee.read());}
String ok_response = "OK\r"; // The response we expect
// Read the text of the response into the response variable
// This satisfies the guard time by waiting for the OK message
String response = String("");
while (response.length() < ok_response.length()) {
if (xbee.available() > 0) {
response += (char) xbee.read();
}
}
Serial.println("response1: " + response);
// If we got received OK, configure the XBee and return true:
if (response.equals(ok_response)) {
Serial.println("Enter command mode successful");
// Restore to default values:
Serial.println("Restoring default values before making changes");
xbee.write("ATRE\r");
Serial.println("Setting addr high");
xbee.write("ATDH0\r"); // Destination high
//while(xbee.available() > 0) {Serial.write(xbee.read());}
Serial.println("Setting addr low");
xbee.write("ATDL1\r"); // Destination low-REPLACE THIS
//while(xbee.available() > 0) {Serial.write(xbee.read());}
Serial.println("Setting MY address");
xbee.write("ATMYFFFF\r");
// Apply changes:
Serial.println("Applying changes");
xbee.write("ATAC\r");
/*
///////////////////////////////////////////////
// Write to non-volatile memory:
// Use similar technique as above to satisfy guard time
Serial.write("Saving\r");
xbee.write("ATWR\r");
String response2 = String("");
//while (xbee.available() > 0) {Serial.write(xbee.read());}
while (response2.length() < ok_response.length()) {
if (xbee.available() > 0) {
response2 += (char) xbee.read();
}
}
Serial.println("response2: " + response2);
if (response2.equals(ok_response)) {
Serial.println("Save successful");
}
else { Serial.println("Save not successful");
return false;
}
// And reset module:
Serial.println("Resetting");
xbee.write("ATFR\r");
///////////////////////////////////////////////
*/
Serial.write("Exit command mode\r");
xbee.write("ATCN\r"); // Exit command mode
//while(xbee.available() > 0) {Serial.write(xbee.read());}
Serial.write("Finished\r");
return true;
} else {
return false; // This indicates the response was incorrect
}
}
void setup() {
Serial.begin(9600); // Begin serial
configured = configureRadio();
}
void loop() {
// Test transmission:
if (configured) {
xbee.print(c);
Serial.print(c);
c = c + 1;
if (c > 'Z') { c = 'A'; }
}
else {
Serial.println("Not configured (in loop)");
delay(5000);
Serial.println("Retrying configuration");
configured = configureRadio();
}
delay(1500);
}

Arduino Serial communication output

I have 2 Arduinos Leonardo and I want them to communicate itself, so I did the following code:
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
}
void loop() {
String outMessage = ""; // String to hold input
while (Serial.available() > 0) { // check if at least 1 char is available
char inChar = Serial.read();
outMessage.concat(inChar); // add inChar to outMessage
}
if (outMessage != "") {
Serial.println("Sent: " + outMessage); // View Arduino 1 in Serial Monitor 1
Serial1.print(outMessage); // Send to Arduino 2
}
while (Serial1.available() > 0) {
Serial.print("Received: "); // View Arduino 1 in Serial Monitor 2
Serial.print(Serial1.read()); // Received from Arduino 1
Serial.println();
}
}
I want to send a message from Arduino 1, print in Serial Monitor and send via TX1 to Arduino 2 and vice-versa. The problem is that I don't receive what I was expecting. For instance if I type test:
Arduino 1:
Sent: test
Arduino 2:
Received: t
Received: e
Received: s
Received: t
I also tryed to do the receiving side like the sending side and use Serial.write but with no sucess.
Is there a easier way to do that or to fix it?
Thanks
Has mentioned by Hans, you need a protocol.
This is what I use to consider a message in Arduino to be a complete message:
char inData[10];
int index;
boolean started = false;
boolean ended = false;
String message =("I am Arduino 1 and I am ready");
void setup(){
Serial.begin(9600);
Serial.println(message);
}
void loop()
{
while(Serial.available() > 0)
{
char aChar = Serial.read();
if(aChar == '>')
{
started = true;
index = 0;
inData[index] = '\0';
}
else if(aChar == '<')
{
ended = true;
}
else if(started)
{
inData[index] = aChar;
index++;
inData[index] = '\0';
}
}
if(started && ended)
{
int inInt = atoi(inData);
Serial.println(inInt);
}
// Get ready for the next time
started = false;
ended = false;
index = 0;
inData[index] = '\0';
}
So, basically a message is considered completed only if it is between the special characters ><, like this: >message<. Then you can do the same on reading.
It does not have to be too complicated. If you look carefully at your last whlie-loop you can see that the software does not get a chance to read more than one character each time it passes through the loop. So that is what you get: one character at a time.
In your first while-loop you did better: you collected all the incoming letters until nothing was available and then sent them all at once. So if you make your last loop look more like the first one, you'll get a better result.
As mentioned a protocol to frame messages is needed between devices. A quick way to do this is to use Bill Porter's EasyTransfer library which does exactly what you are trying to do, over either UART or I2C. It has several examples.
Serial.read() reads only one byte every time you use it. A simple solution would be to store each byte on a char array while Serial.available>0 and then print the String with the whole message that was sent.
char message[40];
int count = 0;
while(Serial.available()>0){
message[count++] = Serial.read();
}
Serial.println(message);

Resources