compare characters (or string) in "if" function

The goal is to compare an incoming character or string to a predefined character (or string) to decide whether further action is allowed or not.

During parsing in the below example a character is retrieved from a received LoRa packet and stored in the variable a.
The subsequent "if" condition needs to compare the contents of 'a' with a predefined character, namely 'A'.

The snippet below does not perform as expected, no proper comparison is executed. For the purpose of this program it does not actually matter whether a character or a string is compared.

Can someone please enlighten me on the correct syntax to be uesed please?

  // Read 4 bytes into 'a'
  uint16_t a;
  char LoRaStringA[12];
  for (int i = 0; i < sizeof(a); i++) {
    *(((uint8_t*)&a) + i) = (uint8_t)LoRa.read();
    itoa(a, LoRaStringA, 12);
  }

  if (a == 'A')
  {

    // Read 4 bytes into cycleTotal
    uint16_t cycleTotal;
    for (int i = 0; i < sizeof(cycleTotal); i++) {
      *(((uint8_t*)&cycleTotal) + i) = (uint8_t)LoRa.read();
    }
  }
  else {
    return;
  }

Why don't you just add a Serial print to check the value of a after you receive the packet? a will have to equal 65 decimal in order for a == 'A' to evaluate to true.

It might also help if you post your entire sketch.

Why are you converting a using base 12?

    itoa(a, LoRaStringA, 12);

Could you enlighten us with an example received string? Why are you declaring and comparing a 16 bit integer with a char?

  // Read 4 bytes into 'a'
  if (a == 'A')

If a really is 4 bytes long is it ever going to equal 'A' ?

   itoa(a, LoRaStringA, 12);

Do you really want to do this 4 times ?

You can use = to compare 2 characters, but you cannot use = to compare strings. To compare strings use the strcmp() function or the safer strncmp() function.

You can use = to compare 2 Strings, though using Strings on the small memory Arduinos can cause hard to find bugs. See the evils of strings.

ToddL1962:
Why don't you just add a Serial print to check the value of a after you receive the packet? a will have to equal 65 decimal in order for a == 'A' to evaluate to true.

It might also help if you post your entire sketch.

Good idea: serial.print; will do.
Entire code:

#include <SPI.h>
#include <LoRa.h>
#include <ESP8266WiFi.h>
const int csPin = 15;         // LoRa radio chip select   GPIO15(D8)->SS OF Lora module
const int resetPin = 2;       // LoRa radio reset         GPIO2(D4)->RESET OF Lora module
uint16_t cycleTotal;
//char a2[] = 'A'; // ID van LORA zender, identificeer karakter
// char a1[] = "0";
WiFiClient client;
const char* server = "api.thingspeak.com";
String apiKey = "WF6IVZHSXTAMHEQ0"; // Thingspeak channel
// DEFINE HERE THE KNOWN NETWORKS
const char* KNOWN_SSID[] = {"devolo-30d32d36517c","PollenenPattaten"};
const char* KNOWN_PASSWORD[] = {"VFJPJSMIJNNAPIQF", "Ziektes123"};
const int   KNOWN_SSID_COUNT = sizeof(KNOWN_SSID) / sizeof(KNOWN_SSID[0]); // number of known networks

void setup() {
  LoRa.setPins(csPin, resetPin);
  Serial.begin(9600);
  while (!Serial);

  Serial.println("LoRa Receiver");

  while (!LoRa.begin(868E6)) {      // initialisatie LoRa
    Serial.print(".");
    delay(500);
  }
  Serial.println("LoRa Initializing OK!");
  // put the radio into receive mode
  LoRa.receive();

  // setup for Multiple WIFI credentials
  boolean wifiFound = false;
  int i, n;
  // ----------------------------------------------------------------
  // Set WiFi to station mode and disconnect from an AP if it was previously connected
  // ----------------------------------------------------------------
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
  Serial.println("Setup done");

  // ----------------------------------------------------------------
  // WiFi.scanNetworks will return the number of networks found
  // ----------------------------------------------------------------
  Serial.println(F("scan start"));
  int nbVisibleNetworks = WiFi.scanNetworks();
  Serial.println(F("scan done"));
  if (nbVisibleNetworks == 0) {
    Serial.println(F("no networks found. Reset to try again"));
    while (true); // no need to go further, hang in there, will auto launch the Soft WDT reset
  }

  // ----------------------------------------------------------------
  // if you arrive here at least some networks are visible
  // ----------------------------------------------------------------
  Serial.print(nbVisibleNetworks);
  Serial.println(" network(s) found");

  // ----------------------------------------------------------------
  // check if we recognize one by comparing the visible networks
  // one by one with our list of known networks
  // ----------------------------------------------------------------
  for (i = 0; i < nbVisibleNetworks; ++i) {
    Serial.println(WiFi.SSID(i)); // Print current SSID
    for (n = 0; n < KNOWN_SSID_COUNT; n++) { // walk through the list of known SSID and check for a match
      if (strcmp(KNOWN_SSID[n], WiFi.SSID(i).c_str())) {
        Serial.print(F("\tNot matching "));
        Serial.println(KNOWN_SSID[n]);
      } else { // we got a match
        wifiFound = true;
        break; // n is the network index we found
      }
    } // end for each known wifi SSID
    if (wifiFound) break; // break from the "for each visible network" loop
  } // end for each visible network

  if (!wifiFound) {
    Serial.println(F("no Known network identified. Reset to try again"));
    while (true); // no need to go further, hang in there, will auto launch the Soft WDT reset
  }

  // ----------------------------------------------------------------
  // if you arrive here you found 1 known SSID
  // ----------------------------------------------------------------
  Serial.print(F("\nConnecting to "));
  Serial.println(KNOWN_SSID[n]);

  // ----------------------------------------------------------------
  // We try to connect to the WiFi network we found
  // ----------------------------------------------------------------
  WiFi.begin(KNOWN_SSID[n], KNOWN_PASSWORD[n]);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");

  // ----------------------------------------------------------------
  // SUCCESS, you are connected to the known WiFi network
  // ----------------------------------------------------------------
  Serial.print(F("WiFi connected, your IP address is "));
  Serial.println(WiFi.localIP());
}

void loop() {

  yield();
  onReceive(LoRa.parsePacket());
  // Schrijf hier alle software voor GIP

}


void onReceive(int packetSize) {
  // Try to parse packet
  if (packetSize == 0) {
    return;
  }
  // ----------------------------------------------------------------
  // Het ontvangen pakketje parsen
  // ----------------------------------------------------------------

  // Read 4 bytes into a
  uint16_t a;
  char LoRaStringA[12];
  for (int i = 0; i < sizeof(a); i++) {
    *(((uint8_t*)&a) + i) = (uint8_t)LoRa.read();
    //     LoRaString = a+(char)LoRa.read();
    itoa(a, LoRaStringA, 12);
  }
  // char a1[] = a;
  uint16_t b = 'A';
  if (a == b)
  {

    // Read 4 bytes into cycleTotal
    uint16_t cycleTotal;
    for (int i = 0; i < sizeof(cycleTotal); i++) {
      *(((uint8_t*)&cycleTotal) + i) = (uint8_t)LoRa.read();
    }
  }
  else {
    return;
  }


  // ----------------------------------------------------------------
  // Waardes weergeven op de seriële monitor
  // ----------------------------------------------------------------

  // Display read values
  Serial.print(" a = ");
  Serial.println(a);
  Serial.print(" gemiddelde afstand = ");
  Serial.print(cycleTotal);
  Serial.println("mm");

  Serial.print(" with RSSI ");
  Serial.println(LoRa.packetRssi());

  // ----------------------------------------------------------------
  // Gemiddelde afstand verzenden naar ThingSpeak
  // ----------------------------------------------------------------

  if (client.connect(server, 80)) // "184.106.153.149" or api.thingspeak.com
  {
    Serial.print(F(" Thingspeak works, gemiddelde afstand = "));
    Serial.print(cycleTotal);
    Serial.println(F("mm"));
    String postStr = apiKey;
    postStr += "&field1=";
    postStr += String(cycleTotal);
    postStr += "\r\n\r\n";
    client.print("POST /update HTTP/1.1\n");
    client.print("Host: api.thingspeak.com\n");
    client.print("Connection: close\n");
    client.print("X-THINGSPEAKAPIKEY: " + apiKey + "\n");
    client.print("Content-Type: application/x-www-form-urlencoded\n");
    client.print("Content-Length: ");
    client.print(String(postStr.length()));
    client.print("\n\n");
    client.println(postStr);
    delay(5000);
  }
  client.stop();
}

ToddL1962:
Why are you converting a using base 12?

    itoa(a, LoRaStringA, 12);

What would be a better base given this packet always will contain 4 bytes?

aarg:
Could you enlighten us with an example received string? Why are you declaring and comparing a 16 bit integer with a char?

Because 'a' was declared as an uint16_t I thought b also needed to be declared as such?

UKHeliBob:

  // Read 4 bytes into 'a'
  if (a == 'A')

If a really is 4 bytes long is it ever going to equal 'A' ?

   itoa(a, LoRaStringA, 12);

Do you really want to do this 4 times ?

Indeed; but 'a' is received as a uint16_t, so how should I declare the variable containing the equivalent that is supposed to be in 'a'?
What do you mean by "Do you really want this 4 times"? Sorry for my ignorance!

brice3010:
What do you mean by "Do you really want this 4 times"? Sorry for my ignorance!

It's inside this loop that runs it 4 times:

  for (int i = 0; i < sizeof(a); i++) {

aarg:
It's inside this loop that runs it 4 times:

  for (int i = 0; i < sizeof(a); i++) {

At the transmitter each packet contains 4 bytes. So 4 bytes per packet have to be parsed at the receiver.

Could any one of the bytes be an 'A' ?

If so, and assuming that you use the itoa() function correctly, what happens if the last of the 4 bytes is not an 'A' ? What will be in the a variable at the end of the for loop ?

UKHeliBob:
Could any one of the bytes be an 'A' ?

If so, and assuming that you use the itoa() function correctly, what happens if the last of the 4 bytes is not an 'A' ? What will be in the a variable at the end of the for loop ?

Would I be able to see this if a serial.print of both 'a' and 'b' is done?
What will be in the 'a' variable: at the transmitter this code is used:

char a[] = "A";
  LoRa.beginPacket();
  // Send 4 bytes (sizeof(a)) starting at the location of counter
  LoRa.write((const uint8_t*)&a, sizeof(a));
  // Send 4 bytes (sizeof(cycleTotal)) starting at the location of cycleTotal
  LoRa.write((const uint8_t*)&cycleTotal, sizeof(cycleTotal));
  LoRa.endPacket();

brice3010:
What would be a better base given this packet always will contain 4 bytes?

Doesn't matter how many bytes. Base 12 is an unusual base. I'm used to working in decimal (Base 10) or hexadecimal (base 16).

brice3010:
Would I be able to see this if a serial.print of both 'a' and 'b' is done?
What will be in the 'a' variable: at the transmitter this code is used:

char a[] = "A";

LoRa.beginPacket();
  // Send 4 bytes (sizeof(a)) starting at the location of counter
  LoRa.write((const uint8_t*)&a, sizeof(a));
  // Send 4 bytes (sizeof(cycleTotal)) starting at the location of cycleTotal
  LoRa.write((const uint8_t*)&cycleTotal, sizeof(cycleTotal));
  LoRa.endPacket();

In this case the length of a will be 2. One byte for the character 'A' and one byte for the nul '\0' terminating character. Therefore 2 bytes will be transmitted, not 4.

A sample of the expected data is always useful in these cases.
Are you sending bytes or ASCII chars?

You are not checking the packet size if it is <4 your read() will return -1's You should check available()

SafeString is my recommended replacement for Arduino Strings and lets you do similar string stuff while avoiding the Evils of Strings mentioned above

It allows you to do string compares using =
and includes a simple SafeString.read() method that checks available for you and prevents buffer overflow.

Change you Transmit to use print( ) instead of write.
You don't have to send in 4bytes lumps, the packetSize keeps track of the actual packsize

char a[] = "A";
  LoRa.beginPacket();
  LoRa.print(a); // one byte
  // Send 2 bytes (sizeof(cycleTotal)) starting at the location of cycleTotal
  LoRa.write((const uint8_t*)&cycleTotal, sizeof(cycleTotal));
  LoRa.endPacket();

Then in the receiver just read one char first and check for A
then read bytes into the cycleTotal uint16_t

  uint16_t cycleTotal;
  char a = LoRa.read();
  if (a == 'A') {
    // Read 4 bytes into cycleTotal
    for (int i = 0; i < sizeof(cycleTotal); i++) {
      *(((uint8_t*)&cycleTotal) + i) = (uint8_t)LoRa.read();
    }   
  } else {
    return;
  }

This should works as well (no prints)

char a = 'A';
  LoRa.beginPacket();
  LoRa.write((uint8_t)a); // one byte the A
  // Send 2 bytes (sizeof(cycleTotal)) starting at the location of cycleTotal
  LoRa.write((const uint8_t*)&cycleTotal, sizeof(cycleTotal));
  LoRa.endPacket();

ToddL1962:
Doesn't matter how many bytes. Base 12 is an unusual base. I'm used to working in decimal (Base 10) or hexadecimal (base 16).

Oh ok, thanks for that info! So I better change that to 16, I will try that?
A serial.print of both 'a' and 'b' gave 65 each.