title: Put integer and double into char array

text:
# Question
Title: Put integer and double into char array
I want to print text and numbers mixed in a table with Serial.print(); from a char array. My problem is the conversion between the different data types. My idea is to print the data of the rows in a for loop with the variable i and the columns in a for loop with the variable j.

I have in the following example two variable, one is type integer and the second is a double. Now i want to add the values of the variables into the char-array, but I can't find a way to do this...

In my main program the variables need to have this data types and should be inserted later into the char array.

Does someone have a solution for this challenge?

Here is a small example code:

```
int a = random(0, 100);
double b = random(0, 100);

char* myStrings[][6] = {"This is string 1", "This is string 2", "This is string 3",
                        "This is string 4", "This is string 5", "This is string 6"
                       };

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

void loop() {

  //now put the integer and double variables into the char array in the second column

  //Print the values
  for (int i = 0; i < 2; i++)
  {

    for (int j = 0; j < 6; j++)
    {
      Serial.print(myStrings[i][j]);
      Serial.print("  ");
      delay(100);
    }
    Serial.println();
  }

}

```

Many thanks in advance.

Guss

EDIT: The output should look like this: Headline (in this example it is the text "This is string 1", "This is string 2"...) and then the values of the variables in the next row. It should be like this:

```
This is String 1     This is String 2     This is String 3

Variable a           Variable b           Variable int

Variable double      Variable double      Variable int

```

# Answer
First of all, you should decide for a datastructure for you table. There are many options with various advantages and disadvantages. I am choosing a statically allocated table here, with a fixed width for each entry in the table and a fixed number of columns. One may also use pointers to strings which are allocated on the heap or elsewhere, but I find this to be the simplest.

Anyways, the basic problem doesn't change: We want to write a integer value in some string buffer. I am using the C library function `snprintf()` here. This function is like `printf()`, just that it writes its output to a given buffer of a maximum size. Thus, we can use simple format strings here and some workarounds for non-working format strings (floating points..)

Here is the code.

```
#include <Arduino.h>

/* A table is a 2 dimensional array of char buffers.
   The core element is a char buffer of fixed size.
   The number of columns must be fixed at compile time.
   Rows can by dynamically added in the structure without having to
   declare the number of elements.
   You can declare the number of rows at compile time, but do not need to fill them.
   Thus you can dynamically add rows to the table.
 */

#define MAX_ENTRY_SIZE 20
#define NUM_COLUMNS 3
#define COLUMN_PRINT_WIDTH MAX_ENTRY_SIZE

char myTable[][NUM_COLUMNS][MAX_ENTRY_SIZE] = {
        {"Column 1", "Column 2" ,"Column 3"}, //Row 1
        {"Variable a", "Variable b", "Variable int"}, //Row 2
        {"Variable double", "Variable double" ,"Variable double"}, //Row 1
};

char* get_table_entry(int row, int column) {
    char* entry = myTable[row][column];
    return entry;
}

void write_int_to_table(int value, int row, int column) {
    //Get a pointer to where the entry is
    char* entry = get_table_entry(row, column);
    //write a new string inside it
    snprintf(entry, MAX_ENTRY_SIZE, "%d", value);
}

void write_double_to_table(double value, int row, int column) {
    //Same as above, different format string..
    char* entry = get_table_entry(row, column);
    //Formatting floats on an Arduino Uno is tricky. %f formatters don't work (cut out due to size.)
    //use String API instead
    String stringFloat(value);
    const char* cString = stringFloat.c_str();
    strncpy(entry, cString, MAX_ENTRY_SIZE);
}

void print_table() {
    //Get number of Rows
    int numRows = sizeof(myTable) / (MAX_ENTRY_SIZE * NUM_COLUMNS);
    for(int row = 0; row < numRows; row++) {
        //Print all columns of this row
        for(int column = 0; column < NUM_COLUMNS; column++) {
            char* entry = get_table_entry(row, column);
            Serial.print(entry);
            //fill with spaces to the right
            for(unsigned int i=0; i< COLUMN_PRINT_WIDTH - strlen(entry); i++) Serial.print(" ");
        }
        Serial.println();

        //Table header seperator
        if(row == 0)
            Serial.println("============================================");
    }
}

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

void loop() {
    int a = random(0, 100);
    double b = random(0, 100);

    Serial.print("Will write new values for a = ");
    Serial.print(a);
    Serial.print(" and b = ");
    Serial.println(b);

    //write these in the second row (first row after header), first and second column.
    write_int_to_table(a, 1, 0);
    write_double_to_table(b, 1, 1);

    //Print table again
    print_table();
    Serial.println();
    Serial.println();

    delay(5000);
}

```

Two rounds give the output:

```
Column 1            Column 2            Column 3
============================================
Variable a          Variable b          Variable int
Variable double     Variable double     Variable double

Will write new values for a = 7 and b = 49.00
Column 1            Column 2            Column 3
============================================
7                   49.00               Variable int
Variable double     Variable double     Variable double

```
> 1 votes

---
Tags: string, array, data-type
---


# Question
Title: Infrared distance sensor picks up distances that are not there
I have connected an Infrared sensor to my Arduino Uno and I've set this code up to blink whenever a distance of less than 50 cm is picked up. If there is an object less than 50 cm away, it does pick it up. However, with nothing in front of it it still blinks at random intervals. The sensor is new. Where do you think the problem is?

```
int sensorPin = 0;
int ledPin = 13;

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
  float distance = 12343.85 * pow(analogRead(sensorPin),-1.15);
  if(distance < 50){
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
  }
  delay(50);
}

```

# Answer
> 1 votes
I see one problem with your code and how it relates to this device.

The output from the sensor is not the monotomic function you describe; not over its entire range. Your conversion function describes only a section of the response. The device is only intended to be used when an object is in range 10-80 cm.

You should check that the voltage at the analog input is valid before performing the math:

```
int v;

v = analogRead(sensorPin);
// sensor is valid in range 0.4 to 2.5 V
if((82 < v) && (v < 512)) {
  // voltage is in usable range, can convert
  distance = 12343.85 * pow(v,-1.15);
  if(distance < 50) {
    digitalWrite(ledPin, HIGH);
    delay(1000);
    digitalWrite(ledPin, LOW);
  }
}
else {
  // no valid reading - probably just skip and try again on next loop
}

```

With that the false triggers may be eliminated.

# Answer
> 1 votes
Looks to me like there could be a signficant figures issue. Arduino can really only handle 7 digits of precision. You hit that right at your first constant in your distance variable, then you multiply by an integer to a power of -1.15. It's likely there are errors there that trip to less than 50, which would give you false positives.

As for the Sharp IR sensors, just buy an IR photodiode and LED for less than $1 USD and build and calibrate your own IR detector. You can calibrate it to a range of about 1 m. That's my recommendation. I did something similar after being frustrated by the cost of the Sharp IR Detectors. Wrote about it on my blog, if you're interested:

https://engineersportal.com/blog/2018/1/17/infrared-obstacle-detector-for-less-than-1

---
Tags: arduino-uno, sensors
---


title: Temperature control using a DHT11

text:
# Question
Title: Temperature control using a DHT11
I am trying to do a project on temperature control and found an example but cannot get the code to work. I have read forums and tried to fix the issue which is below the code.

Code:

```
#include<DHT.h>      // Including library for dht
#include<LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
#define dht11dpin 12
DHT11;
#define pwm 9
#byte degree[8] =
{
  0b00011,
  0b00011,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000
};

#void setup()
{
  lcd.begin(16, 2);
  lcd.createChar(1, degree);
  lcd.clear();
  lcd.print("   Fan Speed  ");
  lcd.setCursor(0, 1);
  lcd.print("  Controlling ");
  delay(2000);
  analogWrite(pwm, 255);
  lcd.clear();
  lcd.print("Circuit Digest ");
  delay(2000);
}

void loop()
  DHT11.read(DHT11pin);
  int temp = DHT11.temperature;
  lcd.setCursor(0, 0);
  lcd.print("Temperature:");
  lcd.print(temp);   // Printing temperature on LCD
  lcd.write(1);
  lcd.print("C");
  lcd.setCursor(0, 1);
  if (temp < 26 )
  {
    analogWrite(9, 0);
    lcd.print("Fan OFF            ");
    delay(100);
  }
  else if (temp == 26)
  {
    analogWrite(pwm, 51);
    lcd.print("Fan Speed: 20%   ");
    delay(100);
  }
  else if (temp == 27)
  {
    analogWrite(pwm, 102);
    lcd.print("Fan Speed: 40%   ");
    delay(100);
  }
  else if (temp == 28)
  {
    analogWrite(pwm, 153);
    lcd.print("Fan Speed: 60%   ");
    delay(100);
  }
  else if (temp == 29)
  {
    analogWrite(pwm, 204);
    lcd.print("Fan Speed: 80%    ");
    delay(100);
  }
  else if (temp > 29)
  {
    analogWrite(pwm, 255);
    lcd.print("Fan Speed: 100%   ");
    delay(100);
  }
  delay(3000);
}

```

Error:

```
In file included from C:\Users\neilb\Documents\Arduino\sketch_jan20b\sketch_jan20b.ino:2:0:
C:\Users\neilb\Documents\Arduino\libraries\DHT_sensor_library/DHT.h:32:15: error: expected unqualified-id before numeric constant
 #define DHT11 11
               ^
C:\Users\neilb\Documents\Arduino\sketch_jan20b\sketch_jan20b.ino:6:1: note: in expansion of macro 'DHT11'
 DHT11;
 ^
C:\Users\neilb\Documents\Arduino\libraries\DHT_sensor_library/DHT.h:32:15: error: expected initializer before numeric constant
 #define DHT11 11
               ^
C:\Users\neilb\Documents\Arduino\sketch_jan20b\sketch_jan20b.ino:35:1: note: in expansion of macro 'DHT11'
 DHT11.read(DHT11pin);
 ^
sketch_jan20b:36: error: request for member 'temperature' in '11', which is of non-class type 'int'
 int temp=DHT11.temperature;
                ^
sketch_jan20b:37: error: 'lcd' does not name a type
   lcd.setCursor(0,0);
   ^
sketch_jan20b:38: error: 'lcd' does not name a type
   lcd.print("Temperature:");
   ^
sketch_jan20b:39: error: 'lcd' does not name a type
   lcd.print(temp);   // Printing temperature on LCD
   ^
sketch_jan20b:40: error: 'lcd' does not name a type
   lcd.write(1);
   ^
sketch_jan20b:41: error: 'lcd' does not name a type
   lcd.print("C");
   ^
sketch_jan20b:42: error: 'lcd' does not name a type
   lcd.setCursor(0,1);
   ^
sketch_jan20b:43: error: expected unqualified-id before 'if'
   if(temp <26 )
   ^
sketch_jan20b:50: error: expected unqualified-id before 'else'
     else if(temp==26)
     ^
sketch_jan20b:57: error: expected unqualified-id before 'else'
      else if(temp==27)
      ^
sketch_jan20b:64: error: expected unqualified-id before 'else'
      else if(temp==28)
      ^
sketch_jan20b:71: error: expected unqualified-id before 'else'
     else if(temp==29)
     ^
sketch_jan20b:77: error: expected unqualified-id before 'else'
      else if(temp>29)
      ^
sketch_jan20b:83: error: expected constructor, destructor, or type conversion before '(' token
   delay(3000);
        ^
sketch_jan20b:84: error: expected declaration before '}' token
 }
 ^
exit status 1
request for member 'temperature' in '11', which is of non-class type

```

# Answer
It's a bit hard to see, but

```
DHT11;

```

does not look like a correct statement, assuming DHT11 is a class (not a define like shown) it should be something like

```
DHT11 dht;

```

where dht is an instance and you can use that.

Than in

```
DHT11.read(DHT11pin);

```

you should replace it by

```
dht.read(DHT11pin);

```
> 1 votes

---
Tags: sensors, temperature-sensor, temperature
---


# Question
Title: Rfid reader and SD card shield won't work together
I recently encountered a problem that's been bugging me for days. I want to make a project using a RFID reader and log data on an SD card with an Arduino Nano, but apparently no matter what I do, I can't seem to make them work together on SPI. They both work individually, and the SD shield works in parallel with the RFID reader, but the RFID doesn't work in parallel with the SD shield.

I'm absolutely sure that the wiring is correct, slave select on both modules are wired to different digital pins, and both are connected through bidirectional level shifters.

I noticed that the RFID reader works fine when I disconnect the MISO pin from the SD shield. I tried putting a diode between SD MISO and digital pin 12, I tried adding pullup resistors on both SS pins, I tried adding resistors on MISO lines, I tried pulling HIGH the SS i don't use, and low the one I want active. Nothing seemes to work and I'm out of ideas. The last thing I will try is conencting the modules on separate VCC, but I don't have faith that it will make any difference.

I hope someone has some advice for my problem.

Thanks in advance

# Answer
> 0 votes
SD cards (or really their breakout boards) don't tend to obey the rules with regards to SPI. In particular the MISO pin isn't set to high impedance when the slave select is not selected.

You can fix this with a tri-state buffer that you feed the SD card's miso line to and controlled by the slave select. The output from the buffer goes to the arduino's MISO.

# Answer
> 0 votes
The only way I could get it to work was to buy a separate SD logger shield (which contains an SD card via SPI).

When I used the SRAM (SPI) together with the SD card (SPI) it never did work. At least not on an Arduino (Uno or Mega).

---
Tags: arduino-nano, spi, rfid, sd
---


title: Buffer reverse to string

text:
# Question
Title: Buffer reverse to string
A few hours since I started messing with my first Arduino and I was trying to understand a small program and need some help. The program sends out the MAC address to the serial port. As it's little endian, the "printBufferReverse" reverses the buffer as shown below. But instead of sending this data to the serial port, how do I store the same data into a string variable? Thanks so much

```
#include <bluefruit.h>
void scan_callback(ble_gap_evt_adv_report_t* report)
{
  uint8_t len = 0;
  uint8_t buffer[32];
  memset(buffer, 0, sizeof(buffer));

  // MAC is in little endian --> print reverse
  // NOTE: I want to store this into a string variable
  // NOTE: the reversing
  Serial.printBufferReverse(report->peer_addr.addr, 6, ':');
  Serial.print("\n");

  /* TX Power Level */
  if (Bluefruit.Scanner.parseReportByType(report,
    BLE_GAP_AD_TYPE_TX_POWER_LEVEL, buffer, sizeof(buffer)))
    {
      Serial.printf("%14s %i\n", "TX PWR LEVEL", buffer[0]);
      memset(buffer, 0, sizeof(buffer));
    }
}

```

And the below line how do I store the data to a string instead of sending to serial port? It's adding a hypen to make the end result look like this:12-09-69-57-45-45-43-41-52-45-20

```
Serial.printBuffer(report->data, report->dlen, '-');

```

I don't want to send this to serial port but to store in a string variable.

This is the board that I am using: https://www.adafruit.com/product/3406

## Complete code

```
/*********************************************************************
 This is an example for our nRF52 based Bluefruit LE modules

 Pick one up today in the adafruit shop!

 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 MIT license, check LICENSE for more information
 All text above, and the splash screen below must be included in
 any redistribution
*********************************************************************/

#include <bluefruit.h>

/* For a list of EIR data types see:
 *    https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile
 *    Matching enum: cores/nRF5/SDK/components/softdevice/s132/headers/ble_gap.h */

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

  Serial.println("Scanning for beacons");
  Serial.println("------------------------------------\n");

  // Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1
  // SRAM usage required by SoftDevice will increase dramatically with number of connections
  Bluefruit.begin(0, 1);

  // Set max power. Accepted values are: -40, -30, -20, -16, -12, -8, -4, 0, 4
  Bluefruit.setTxPower(4);

  /* Set the device name */
  Bluefruit.setName("Bluefruit52");

  /* Set the LED interval for blinky pattern on BLUE LED */
  Bluefruit.setConnLedInterval(250);

  /* Start Central Scanning
   * - Enable auto scan if disconnected
   * - Filter out packet with a min rssi
   * - Interval = 100 ms, window = 50 ms
   * - Use active scan (used to retrieve the optional scan response adv packet)
   * - Start(0) = will scan forever since no timeout is given
   */
  Bluefruit.Scanner.setRxCallback(scan_callback);
  Bluefruit.Scanner.restartOnDisconnect(true);
  Bluefruit.Scanner.filterRssi(-80);
  //Bluefruit.Scanner.filterUuid(BLEUART_UUID_SERVICE); // only invoke callback if detect bleuart service
  Bluefruit.Scanner.setInterval(160, 80);       // in units of 0.625 ms
  Bluefruit.Scanner.useActiveScan(true);        // Request scan response data
  Bluefruit.Scanner.start(0);                   // 0 = Don't stop scanning after n seconds

  Serial.println("Started ...");
}

void scan_callback(ble_gap_evt_adv_report_t* report)
{
  uint8_t len = 0;
  uint8_t buffer[32];
  memset(buffer, 0, sizeof(buffer));
  boolean hasPayload;
  String bleDvcID;
  String advPayload;

  hasPayload = false;
  bleDvcID = "";
  advPayload = "";

  /* Display the timestamp and device address */
  /*
  if (report->scan_rsp)
  {
    Serial.printf("[SR%10d] Packet received from ", millis());
  }
  else
  {
    Serial.printf("[ADV%9d] Packet received from ", millis());
  }
  */
  // MAC is in little endian --> print reverse
  // bleDvcID = printBufferReverse(report->peer_addr.addr, 6, ':');
  // char buffer[18] = "";
  /*
    snprintf(buffer, "%02X-%02X-%02X-%02X-%02X-%02X", 18,
        report->peer_addr.addr[5],
        report->peer_addr.addr[4],
        report->peer_addr.addr[3],
        report->peer_addr.addr[2],
        report->peer_addr.addr[1],
        report->peer_addr.addr[0]
    );
   */
  Serial.printBufferReverse(report->peer_addr.addr, 6, ':');
  Serial.print("\n");

  /* Raw buffer contents */
  Serial.printf("%14s %d bytes\n", "PAYLOAD", report->dlen);
  if (report->dlen)
  {
    hasPayload = true;
    Serial.printf("%15s", " ");
    Serial.printBuffer(report->data, report->dlen, '-');
    Serial.println();
  }

  /* RSSI value */
  Serial.printf("%14s %d dBm\n", "RSSI", report->rssi);

  /* Complete Local Name */
  if(Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME, buffer, sizeof(buffer)))
  {
    Serial.printf("%14s %s\n", "COMPLETE NAME", buffer);
    if (strcmp((const char*)buffer, "Temperature Fren")==0)
    {
        Serial.println("Found beacon!");
    }
    memset(buffer, 0, sizeof(buffer));
  }

  /* TX Power Level */
  if (Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_TX_POWER_LEVEL, buffer, sizeof(buffer)))
  {
    Serial.printf("%14s %i\n", "TX PWR LEVEL", buffer[0]);
    memset(buffer, 0, sizeof(buffer));
  }

  /* Check for UUID16 Complete List */
  len = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE, buffer, sizeof(buffer));
  if ( len )
  {
    printUuid16List(buffer, len);
  }

  /* Check for UUID16 More Available List */
  len = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE, buffer, sizeof(buffer));
  if ( len )
  {
    printUuid16List(buffer, len);
  }

  /* Check for UUID128 Complete List */
  len = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE, buffer, sizeof(buffer));
  if ( len )
  {
    printUuid128List(buffer, len);
  }

  /* Check for UUID128 More Available List */
  len = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE, buffer, sizeof(buffer));
  if ( len )
  {
    printUuid128List(buffer, len);
  }

  /* Check for BLE UART UUID */
  /*
  if ( Bluefruit.Scanner.checkReportForUuid(report, BLEUART_UUID_SERVICE) )
  {
    Serial.printf("%14s %s\n", "BLE UART", "UUID Found!");
  }
  */
  /* Check for DIS UUID */
  /*
  if ( Bluefruit.Scanner.checkReportForUuid(report, UUID16_SVC_DEVICE_INFORMATION) )
  {
    Serial.printf("%14s %s\n", "DIS", "UUID Found!");
  }
  */
  /* Check for Manufacturer Specific Data */
  /*
  len = Bluefruit.Scanner.parseReportByType(report, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA, buffer, sizeof(buffer));
  if (len)
  {
    Serial.printf("%14s ", "MAN SPEC DATA");
    Serial.printBuffer(buffer, len, '-');
    Serial.println();
    memset(buffer, 0, sizeof(buffer));
  }
  */
  Serial.println();
}

void printUuid16List(uint8_t* buffer, uint8_t len)
{
  /* Serial.printf("%14s %s", "16-Bit UUID"); */
  for(int i=0; i<len; i+=2)
  {
    uint16_t uuid16;
    memcpy(&uuid16, buffer+i, 2);
    /* Serial.printf("%04X ", uuid16); */
  }
  /* Serial.println(); */
}

void printUuid128List(uint8_t* buffer, uint8_t len)
{
  (void) len;
  /* Serial.printf("%14s %s", "128-Bit UUID"); */

  // Print reversed order
  for(int i=0; i<16; i++)
  {
    const char* fm = (i==4 || i==6 || i==8 || i==10) ? "-%02X" : "%02X";
    /* Serial.printf(fm, buffer[15-i]); */
  }

  /* Serial.println(); */
}

void loop()
{
  // Toggle both LEDs every 1 second
  digitalToggle(LED_RED);

  delay(1000);
}

```

# Answer
You can do it with snprintf\_P:

```
char mac[18];

snprintf_P(mac, 18, (PGM_P)F("%02X-%02X-%02X-%02X-%02X-%02X"),
    report->peer_addr.addr[5],
    report->peer_addr.addr[4],
    report->peer_addr.addr[3],
    report->peer_addr.addr[2],
    report->peer_addr.addr[1],
    report->peer_addr.addr[0]
);

```

That is, assuming that `report->peer_addr.addr` is an array of 6 bytes.

If your strange board doesn't support the `_P` variants of string manipulation functions then you can drop that part along with the `(PGM_P)F(...)` bit:

```
char mac[18];

snprintf(mac, 18, "%02X-%02X-%02X-%02X-%02X-%02X",
    report->peer_addr.addr[5],
    report->peer_addr.addr[4],
    report->peer_addr.addr[3],
    report->peer_addr.addr[2],
    report->peer_addr.addr[1],
    report->peer_addr.addr[0]
);

```

Doing so on an Ardunio, though, would waste RAM.
> 2 votes

---
Tags: buffer
---


title: nRF24L01 Problem

text:
# Question
Title: nRF24L01 Problem
I'm trying to code a simple transmitter - Receiver program with nRF24L01

Very simple code. Compiles. But when I try to test it using serial monitor. But only the first character is printed on the screen just once.

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN 9
#define CSN_PIN 10

const uint64_t pipe = 0xE8E8F0F0E1LL;

RF24 radio(CE_PIN, CSN_PIN);

int smth[1];  // the transmitter data
int x=0;  // the copy of the receiver data
char rec[1]; //the receiver data

int ledPin = 3; // choose the pin for the LED
int inPin = 7;   // choose the input pin (for a pushbutton)
int val = 0;     // variable for reading the pin status

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);  // declare LED as output
  pinMode(inPin, INPUT);    // declare pushbutton as input

  radio.begin();
  radio.openWritingPipe(pipe);  //originally transmitter
}

void loop(){
  val = digitalRead(inPin);  // read input value
  if (val==HIGH) {         // check if the input is HIGH (button released)
    digitalWrite(ledPin, HIGH);  // turn LED OFF
    Serial.println('1');
    smth[0] = '1';
    radio.write(smth, sizeof(smth));
  } else {
    digitalWrite(ledPin, LOW);  // turn LED ON
    Serial.println('0');
    smth[0] = '0';
    radio.write(smth, sizeof(smth));
  }
}

```

---

Serial Monitor :

0

---

Instead of printing a zeros for infinite time till I change the mode of the switch, even though if I change the mode of the switch from low to high, nothing is printed on the screen.

I'm using Library for instance http://playground.arduino.cc/InterfacingWithHardware/Nrf24L01

Any help?

# Answer
A quick look at the library header files shows you should call `radio.stopListening()` before calling `radio.write()` for the module to switch to transmit mode. This could be what is blocking the `radio.write` in the else block. I also recommend you try a `byte` array first, to get things working, just in case `int`s are the issue.
> 0 votes

# Answer
Completing TisteAndii reply I suggest to have a look at init. According to the RF24 classe list, it seems radio.begin(); and radio.openWritingPipe(pipe); are "void" function. I personnaly use NRFLite from Dave Parson and his lib send a return value for his \_radio.init function. That's interesting because a lot of lib have a "send feature" which don't return until the receiver replied. So if you turn on your nRF and send data while the receiver is OFF, you're blocked. With a test at init, you can check that and loop until the receiver is available.

Note: I let my answer, but that's not the good one. As indicate in the coment, the init function dont tell if the receiver is avaible, but only if the nRF is connected (your nRF, so not the other one).
> 0 votes

---
Tags: arduino-uno, nrf24l01+
---


# Question
Title: How to properly construct objects on ATmega2056?
I was wondering the correct method to construct objects for use in the setup and loop scopes. I tried working constructing in the global scope, but I get garbage values printed to serial (probably from misusing pointers)? If I use the new keyword, then it works, but I heard that that is not best practice.

I is there a better way I should do this?

```
// navigator.cpp

#include "navigator.h"

Navigator::begin(Waypoint* w, int count) {
  waypoints = w;
  pointCount = count;
  next = 0;                               // start with first waypoint
  course = 90;                          // Notice that initial course is due East

  Serial.println('here');
}

```

-

```
// navigator.h

#define _navigator_h

#if defined(ARDUINO) && ARDUINO >= 100
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

struct Waypoint {
  double lat, lon;
};

class Navigator {
public:
  begin(Waypoint* w, int);
};

#endif

```

-

```
// TransAt.ino

#include "navigator.h"

Waypoint w = { 43.36, -75.1 };  // These objects must be accessible in both setup() and loop(), but we can't use the new keyword
Navigator nav();                    // That means we have to do a lot of the heavy lifting here

uint32_t timer = millis();

void setup() {
  nav.begin(&w, 1);
}

void loop()
{

}

```

# Answer
> I tried working constructing in the global scope, but I get garbage values printed to serial ...

Constructors in global scope are called before `init` and `setup` and thus are probably executing too soon for you. This would account for the garbage printed to serial, because your constructor is printing before the `Serial.begin()` call.

You can put constructors in global scope, however they should do fairly trivial things (eg. setting a counter to zero, or a pointer to NULL). Do not rely upon the system being initialized, thus do not call functions like `millis`, nor should you be using dynamic memory allocation at this point.

Most classes defer their "real" initialization to a `begin` function (eg. `Serial.begin`) because it is safe to do that, usually in the `setup` function.
> 2 votes

---
Tags: programming, c++
---


title: Reading Arduino Serial Input

text:
# Question
Title: Reading Arduino Serial Input
I am reading an input from my Ohaus weighing scale using it's RS232 output using this code:

```
#define HWSERIAL Serial1

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

void loop() {
  int incomingByte;

  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    Serial.print("USB received: ");
    Serial.println(incomingByte, DEC);
    //HWSERIAL.print("USB received:");
    //HWSERIAL.println(incomingByte, DEC);
  }
  if (HWSERIAL.available() > 0) {
    incomingByte = HWSERIAL.read();
    Serial.print("UART received: ");
    Serial.println(incomingByte);
    //HWSERIAL.print("UART received:");
    //HWSERIAL.println(incomingByte);
  }
}

```

When pressing the print button on the scale, I was expecting data to come over in single burst with just the readings, but what I am getting is the expected data, but the scale keeps sending data afterwards (ES over and over). I need to parse out just what's needed. The below is the output from the console on my computer.

```
UART received:
UART received:
UART received:
UART received:
UART received: 0
UART received: .
UART received: 0
UART received: 0
UART received:
UART received:
UART received:
UART received:
UART received:
UART received:
UART received: ?
UART received: (This is a CR)

UART received: (This is a LF)

UART received:
UART received:
UART received:
UART received:
UART received: 0
UART received: .
UART received: 4
UART received: 0
UART received:
UART received:
UART received:
UART received:
UART received:
UART received:
UART received: ?
UART received: G
UART received:
UART received:
UART received: (CR)

UART received: (LF)

UART received: E
UART received: S
UART received: (CR)

UART received: (LF)
... (The ES loops over and over until the print button is pressed again)

```

0.00 is the current scale reading and 0.40 is the tare weight. That's all I need and I can't figure out how to parse it. The blocks aren't the same length so how do I pull out the needed information and ignore the repetitive 'ES'? I'm not 100% sure if I'm even going about this the right way?

Output as DEC

```
UART received: 32
UART received: 32
UART received: 32
UART received: 32
UART received: 48
UART received: 46
UART received: 48
UART received: 48
UART received: 32
UART received: 32
UART received: 32
UART received: 32
UART received: 32
UART received: 32
UART received: 63
UART received: 13
UART received: 10
UART received: 32
UART received: 32
UART received: 32
UART received: 32
UART received: 48
UART received: 46
UART received: 52
UART received: 48
UART received: 32
UART received: 32
UART received: 32
UART received: 32
UART received: 32
UART received: 32
UART received: 63
UART received: 71
UART received: 32
UART received: 32
UART received: 13
UART received: 10
UART received: 69
UART received: 83
UART received: 13
UART received: 10
UART received: 69
UART received: 83
...

```

# Answer
> 2 votes
From the manual: http://dmx.ohaus.com/WorkArea/showcontent.aspx?id=4294974226

> The balance will return “ES” for invalid commands.

Check to make sure you're using the correct serial parameters that the RX line is wired correctly.

---
Tags: arduino-leonardo, rs232
---


# Question
Title: AT command is not responding on serial monitor
I am trying to send `AT` commands to `ESP8266`. I re-flashed `ESP8266` https://i.stack.imgur.com/z0hoc.jpg I followed this tutorial http://remotexy.com/en/help/esp8266-firmware-update/ and I hope it re-flashed successfully as there was no error.

When I uploaded this program http://www.pastebin.com/frhZY7tD I am trying to run AT command at 9600 baud rate on serial monitor then no response..

Below is how my circuit looks like

```
#include "SoftwareSerial.h"

SoftwareSerial esp8266(2, 3); // RX, TX

void setup()
{
  Serial.begin(9600); // serial port used for debugging
  esp8266.begin(9600);  // your ESP's baud rate might be different
}

void loop()
{
  if(esp8266.available())  // check if the ESP is sending a message
  {
    while(esp8266.available())
    {
      char c = esp8266.read();  // read the next character.

      Serial.write(c);  // writes data to the serial monitor
    }
  }

  if(Serial.available())
  {
    delay(10);  // wait to let all the input command in the serial buffer
    // read the input command in a string
    String cmd = "";
    while(Serial.available())
    {
      cmd += (char)Serial.read();
    }
    // send to the esp8266
    esp8266.println(cmd);
  }
}

```

Trying to execute `AT` command -

On clicking on send button then it shows empty response like below -

When I unplug power wire and plug it back then it prints some garbled message on serial monitor. I checked voltage on RX also, it was around 3.5V that seems also OK.

I am facing this issue after I flashed WiFi firmware to `ESP8266` then back AT firmware. It seems that AT firmware was not flashed successfully so I tried to erase everything using below command.

> esptool.py --port /dev/ttyUSB0 erase\_flash

```
C:\Users\williams>esptool.py --port COM4 -b 9600 erase_flash
esptool.py v1.3
Connecting...................

A fatal error occurred: Failed to connect to ESP8266: Timed out waiting for pack
et header

```

Before execute above command, I made changes in my circuit like below :-

# Update

I have re-flashed ESP8266 on 115200 baud rate, and uploaded empty program then it started to respond `AT` commands. I connected as like above only change is TX to TX and RX to RX respectively. Alright!

```
AT

OK
AT

OK
AT+GMR

AT version:0.50.0.0(Sep 18 2015 20:55:38)
SDK version:1.4.0
compile time:Sep 18 2015 21:46:52
OK

```

Well, I want to send `AT` commands from the Arduino serial monitor window to `ESP8266` and print `ESP8266` response to the command. When I upload above program then it stops to respond, same result as like empty screen this is weird. Isn't ?

# Answer
The ESP's AT firmware is probably configured for a higher baud rate, 115200 is typical. SoftwareSerial only works reliably up to 9600 baud. It can transmit "reliably enough" at 115200 for you to blindly send change-baud commands, though the ESP's response will probably be garbled. So you need to either: Reduce the ESP's baud rate or use the Uno's hardware serial port for the ESP, which means giving up the Uno's terminal output and makes it a pain to reconnect your PC each time you need to update the Uno's code. I've described the process of changing the ESP's baud-rate in more detail in this answer.

Update: I'm not familiar with various AT comand-interpreter revs; my ESPs are all running with the firmware rev came on them; "AT+GMR" (show version info) replies:

```
AT version:0.40.0.0(Aug  8 2015 14:45:58)
SDK version:1.3.0
Ai-Thinker Technology Co.,Ltd.
Build:1.3.0.2 Sep 11 2015 11:48:04

```

There is no AT+CIOBAUD command listed in my ESP8266 AT Instruction Set document rev 1.5.3). The only one listed that affects baud rate - and the one I use - is:

```
AT+UART_DEF=<baud>,<databits>,<stopbits>,<parity>,<flowcontrol>

```

, or:

```
AT+UART_DEF=9600,8,1,0,0

```

for 9600 baud, 8 bits, 1 stop-bit, no parity, no flow control. You probably know, but just in case, note that you will lose communication immediately after you change the ESP's baud rate, until you then change the local baud rate to match.

Update2:

> This is program pastebin.com/dquCNYJj I am not sure what wrong I am doing

That code sets SoftwareSerial to 115200 baud; it can not run fast enough to receive data at that speed.

Update 3:

Since you've updated the ESP's firmware unsuccessfully, it's hard or impossible to know what's going on. The output in your screenshot looks rather like the result of a baud mismatch between the ESP and your terminal. You need to get a clean firmware update to the ESP before you can expect it to respond correctly and rely on its output to diagnose any other problems.

Update 4:

I'm not sure if we're talking about the same thing so please forgive me if you already know this; we might be talking about (at least) three different baud-rates:

1. The rate in use during flashing of new firmware to the ESP;
2. The default rate that new firmware will start listening at, whenever it is booted;
3. The actual rate used at any given time between the ESP with its new firmware and the Arduino or some other device external to the ESP.

My own experience is with using the factory-installed AT Interpreter firmware. I have never needed to update it so I don't have personal experience with (1).

(2) and (3) are programmable by the Arduino. When I first use a new ESP (or after you've just re-flashed its AT Interpreter), it will listen at a factory-default baud rate (mine have all defaulted to 115200). There are commands to change the current rate (not saved across a reboot) and/or the default baud (saved for all future sessions).

I almost always change its default rate to 9600 to use it with an Arduino software serial port. This is my initialization for a new device, using an Arduino to talk to the ESP. (Don't transmit my '#...' comments):

```
# Start talking at the ESP's default rate (115200 on my factory-fresh ones).
AT+RST                         # Reset
AT+UART_DEF=9600,8,1,0,0       # Default baud to 9600,N,8,1,no flow ctl
# Here, change the Arduino's port to match: 9600 in this case.
AT+CWMODE=1                    # Station mode (client)
ATE0                           # Command echo off

```

From now on, the ESP will wake up listening at 9600 baud, in Station Mode as a client, with no command echo.
> 3 votes

# Answer
On your last picture, you should connect the Rx of your Arduino to the Tx of your ESP8266 and vice versa.

If you did that and it doesn't work, try to upload an example sketch in order to determine if it's the code or the connexions that are problematic. **I recommend that you use the WiFiScan example**, since that example doesn't require to change the code or to include other libraries othet than the ones from ESP8266Community.
> 2 votes

# Answer
Is it possible that this is a hardware connection issue? According to the datasheet of the ESP8266, it states that the maximum voltage input is 3.6V, but by connecting directly to the Arduino, the signal output by Arduino would be more than 3.6V. (Around 5V output)

Instead of connecting directly, you might want to perform Level shifting first? (5V to 3.3V, vice versa)

(Here's the link to the ESP8266 datasheet: https://nurdspace.nl/images/e/e0/ESP8266\_Specifications\_English.pdf)
> 0 votes

# Answer
First of all, Please check if you are giving proper voltage and current both to ESP8266. I've seen it not working if it doesn't get proper voltage and current.

Secondly, Connect your Rx,Tx of ESP8266 to Rx,Tx of Arduino respectively. Then, try doing one thing, just upload empty sketch having empty setup() and loop() function only.

Then, open serial monitor select your baud rate (mostly either 9600 or 115200) and you are all done! Sending "AT" via serial monitor input field will show you "OK" in serial monitor response window.
> 0 votes

# Answer
Try this:

```
/*
  Software serial multple serial test

 Receives from the hardware serial, sends to software serial.
 Receives from software serial, sends to hardware serial.

 The circuit:
 * RX is digital pin 2 (connect to TX of other device)
 * TX is digital pin 3 (connect to RX of other device)

 Note:
 Not all pins on the Mega and Mega 2560 support change interrupts,
 so only the following can be used for RX:
 10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

 Not all pins on the Leonardo and Micro support change interrupts,
 so only the following can be used for RX:
 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).

 created back in the mists of time
 modified 25 May 2012
 by Tom Igoe
 based on Mikal Hart's example

 This example code is in the public domain.

 */
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // Serial.println("Goodnight moon!");

  // set the data rate for the SoftwareSerial port
  mySerial.begin(115200);
  // mySerial.println("Hello, world?");
}

void loop() { // run over and over
  if (mySerial.available()) {
    Serial.write(mySerial.read());
  }
  if (Serial.available()) {
    mySerial.write(Serial.read());
  }
}

```
> 0 votes

---
Tags: arduino-uno, serial, esp8266, softwareserial
---


title: Where are the Arduino Due registers?

text:
# Question
Title: Where are the Arduino Due registers?
Having most of my experience on ATmega chips, and just starting up with Arduino (to reduce hardware development time) I'm happy to see that the usual registers such as `TIMSK0`, `PCICR`, `TCNT1H` and others can be used from the Arduino IDE just as they appear in the Atmel datasheet.

Migrating to the Arduino Due, however, came with a shock: the registers specified in the datasheet of the Cortex-M3 are not recognized by the Arduino IDE (although I downloaded the extension necessary for being able to select the Due). I wanted to do something very simple, like configuring a timer. I found `TC_CMR0` in the datasheet, but the Arduino IDE doesn't recognize it. I found an example using the Arduino Due with timers in an obscure forum, and they used `REG_PWM_CMR0`. I tried it in the Arduino IDE, and it was accepted by the compiler.

I searched the Arduino and other forums, and couldn't find any hint whatsoever about the naming of the registers. Why are the names of the registers different? And can I find a conclusive documentation about the register names, or am I doomed to research each and every one of the hundreds of registers individually?

# Answer
There are a few files in the Arduino Due core that you should have a look at. They give great insight into the SAM register set up; variant.h, variant.cpp and chip.h

After that you can dive into the libsam and the many components (include/source).

The SAM code has a very different structure and style compared to AVR.

Cheers!
> 1 votes

# Answer
I found almost everything I needed to know from the CPUs datasheet here. I got the link from the Due page on the Arduino website.

For all the registers I was interested in, in my case the Parallel IO registers, it seems to be the case that the Arduino library names them the same as the datasheet, but prepended with "REG\_" so PIOC\_OWDR (Output Write Disable Reg for PIO port C) becomes REG\_PIOC\_OWDR.

In addition to finding the register names, the datasheet obviously contains a lot more useful information about how the CPU works and how to get the most out of it.

I also found the header files in the Arduino library (arduino\hardware\sam\1.6.4\system\CMSIS\Device\ATMEL\sam3xa\include\instance\instance\_pioc.h for the example above) to be good places to look up what the registers are called.
> 0 votes

# Answer
The Arduino Due files you are after are located here on a Windows PC:

```
 C:\Users\name\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.11\system\CMSIS\Device\ATMEL\sam3xa\include\component

```
> -1 votes

---
Tags: arduino-due
---


# Question
Title: How can I find the time taken while a function is being called?
I tried using millis, but I wanted to know if there is any better way to find out the exact time from when a function is called and finally when it terminates.

# Answer
There is `micros()` which returns the number of microseconds the board has been active. But it rolls over much more frequently (a bit over an hour vs the month and a half for `millis()`)

```
unsigned long preFunction = micros();
foo();
unsigned long timeElapsed = micros() - preFunction;

```
> 2 votes

# Answer
Beyond the answer of ratchet freak, I also suggest to (for test only), put it in a loop and divide it to get a better result, like:

```
unsigned long preFunction = micros();
for (int i = 0; i < 1000; i++)
{
  foo();
}
unsigned long timeElapsed = (micros() - preFunction) / 1000;

```

The number of repeats depend on the length of foo(), make sure it will not have a value beyond an unsigned long.
> 0 votes

# Answer
The most accurate method would be to toggle a pin high right before the function, and low after.

If you than connect an oscilloscope or logic analyzer to the pin, you can measure the exact time it took for the function to execute.
> -1 votes

---
Tags: millis
---


title: NRF24L01 receiving even if no data sent

text:
# Question
Title: NRF24L01 receiving even if no data sent
I am using nRF24L01 to communicate between two micro controllers. Both are Arduino Uno.

The question i have here is , even if i do not send any data from sender to receiver , the receiver device is constantly checking for the data, and the blank data is being received per second. And also no data is received by receiver which is sent by sender.

I am sharing the code for both sender and receiver.

Please suggest me what wrong i am doing.

Receiver Code :

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CNS, CE
String response;
boolean done = false;

void setup() {

 delay(500);
 Serial.begin(9600);

 radio.begin();
 radio.setPALevel(RF24_PA_MIN);
 radio.openReadingPipe(0, 0xF0F0F0F0AA);
 radio.startListening();

}

void loop() {

   if (radio.available()) {

   radio.read(&response, sizeof(response));
   done = true;

}

if (done) {
  Serial.println(response);
}

done = false;
delay(1000);

}

```

Sender Code:

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CNS, CE
String request;

void setup() {

delay(500);
Serial.begin(9600);

radio.begin();
radio.openWritingPipe(0xF0F0F0F0AA);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();

}

void loop() {

   while ( Serial.available() > 0 )  {

   request = Serial.readString();

   Serial.println(request);
   radio.write(&request, sizeof(request));

   delay(1000);

 }
}

```

# Answer
I've written a code for NRF24L01+ based on the datasheet.run them on your arduino and test them.CE pin is PIN7 in arduino and CSN is PIN8 in arduino. NRF\_monitorRegisters() shows all Registers of NRF.It's nice to test your NRF maybe it helps:

for transmitter:

```
#include <SPI.h>

int sending = 1;
int data = 7;

void IRQ() {
  Serial.println("STATUS register from IRQ ISR :  ");
  digitalWrite(8, 0);
  SPI.transfer(0x07);
  delay(10);
  Serial.println(SPI.transfer(0xff), BIN);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x08);
  delay(10);
  Serial.println(SPI.transfer(0xff), BIN);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x07 + 0x20);
  delay(10);
  SPI.transfer(0xff);
  delay(10);
  digitalWrite(8, 1);
}

void NRF_transmitterBegin() {

  //reading
  /*digitalWrite(8, 0);
    SPI.transfer(0x00);
    delay(10);
    Serial.println(SPI.transfer(0xff), BIN);
    delay(10);
    digitalWrite(8, 1);*/

  pinMode(7, OUTPUT);  //CE
  pinMode(8, OUTPUT);  //CSN
  delay(100);
  digitalWrite(8, 1);
  digitalWrite(7, 0);

  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.begin();
  delay(1000);

  digitalWrite(8, 0);   //flush TX_FIFO
  SPI.transfer(0xe1);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);   //flush RX_FIFO
  SPI.transfer(0xe2);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x07 + 0x20);
  delay(10);
  SPI.transfer(0xf0);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x00 + 0x20);
  delay(10);
  SPI.transfer(0x0e);
  delay(10);
  digitalWrite(8, 1);
  delay(10);

  /*digitalWrite(8, 0);
    SPI.transfer(0x11 + 0x20);
    delay(10);
    SPI.transfer(0x3f);
    delay(10);
    digitalWrite(8, 1);*/

  //Down for DYNPL
  digitalWrite(8, 0);
  SPI.transfer(0x1c + 0x20);
  delay(10);
  SPI.transfer(0x01);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x1d + 0x20);
  delay(10);
  SPI.transfer(0x04);
  delay(10);
  digitalWrite(8, 1);
  //Up for DYNPL

  digitalWrite(8, 0);
  SPI.transfer(0x01 + 0x20);
  delay(10);
  SPI.transfer(0x3f);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x02 + 0x20);
  delay(10);
  SPI.transfer(0x03);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x03 + 0x20);
  delay(10);
  SPI.transfer(0x03);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x04 + 0x20);
  delay(10);
  SPI.transfer(0xff);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x05 + 0x20);
  delay(10);
  SPI.transfer(0x4c);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x06 + 0x20);
  delay(10);
  SPI.transfer(0x06);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x0a + 0x20);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x10 + 0x20);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  digitalWrite(8, 1);

  attachInterrupt(digitalPinToInterrupt(2), IRQ, FALLING);
  delay(10);

}

void NRF_transmit(int whatIsData , float data , float hum) {    //hum is used just for temp&humidity
  /*
     byte 0 says what is our data:  1 -> data and humidity    2 -> movement   3 -> gas

     1(float) :   byte 1 -> integer part of temp  byte 2 -> fractional part of temp   byte 3 -> integer part of humidity    byte 4 -> fractional part of humidity    byte 5 -> %battery
     2(binary) :  byte 1 -> %battery
     3(float) :   byte 1 -> integer part of gas   byte 2 -> fractional part of gas    byte 3 -> %battery

     %battery feature is in progress ...
  */

  int byte0 = 0 , byte1 = 0 , byte2 = 0 , byte3 = 0 , byte4 = 0 , byte5 = 0;
  float buf = 0;

  byte0 = whatIsData;

  switch (whatIsData) {
    case 1: {

        byte1 = data;
        buf = data - byte1;
        byte2 = buf * 10;

        byte3 = hum;
        buf = hum - byte3;
        byte4 = buf * 10;

        break;
      }
    case 2: {

        break;
      }
    case 3: {

        byte1 = data;
        buf = data - byte1;
        byte2 = buf * 10;

        break;
      }
    default: {
        break;
      }
  }

  digitalWrite(8, 0);
  SPI.transfer(0xe1);   //flush TX_FIFO empty
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0xa0);   //write on TX_FIFO
  delay(10);
  SPI.transfer(byte0);
  delay(10);
  SPI.transfer(byte1);
  delay(10);
  SPI.transfer(byte2);
  delay(10);
  SPI.transfer(byte3);
  delay(10);
  SPI.transfer(byte4);
  delay(10);
  SPI.transfer(byte5);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(7, 1);   //CE High
  delay(1);
  digitalWrite(7, 0);   //CE Low

}

void NRF_monitorRegisters() {

  for (int i = 0; i < 30; i++) {
    digitalWrite(8, 0);
    SPI.transfer(i);
    delay(10);
    Serial.print(i , HEX);
    Serial.print(" -> ");
    Serial.println(SPI.transfer(0xff), BIN);
    delay(10);
    digitalWrite(8, 1);
  }
  Serial.println("");

}

void setup() {

  Serial.begin(115200);

  NRF_transmitterBegin();
  NRF_monitorRegisters();

}

void loop() {

  NRF_transmit(3 , 15.1 , 0);

  delay(1000);
}

```

for receiver :

```
#include <SPI.h>

long int lastTime = 0;

void IRQ() {

  int whatIsData = 0;
  int byte1 = 0 , byte2 = 0 , byte3 = 0 , byte4 = 0 , byte5 = 0;
  float data = 0 , hum = 0 , buf = 0;

  /*Serial.println("STATUS register from IRQ ISR :  ");
    digitalWrite(8, 0);
    SPI.transfer(0x07);
    delay(10);
    Serial.println(SPI.transfer(0xff), BIN);
    delay(10);
    digitalWrite(8, 1);*/

  digitalWrite(8, 0);
  SPI.transfer(0x61);
  delay(10);
  whatIsData = SPI.transfer(0xff);
  delay(10);
  byte1 = SPI.transfer(0xff);
  delay(10);
  byte2 = SPI.transfer(0xff);
  delay(10);
  byte3 = SPI.transfer(0xff);
  delay(10);
  byte4 = SPI.transfer(0xff);
  delay(10);
  byte5 = SPI.transfer(0xff);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);   //flush RX_FIFO
  SPI.transfer(0xe2);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x07 + 0x20);
  delay(10);
  SPI.transfer(0xf0);
  delay(10);
  digitalWrite(8, 1);
  delay(10);

  switch (whatIsData) {
    case 1: {

        buf = byte2;
        data = byte1 + buf / 10;
        buf = byte4;
        hum = byte3 + buf / 10;

        Serial.print("Received data from DHT22 -> temp:");
        Serial.print(data);
        Serial.print("  humidity:");
        Serial.println(hum);

        break;
      }
    case 2: {

        Serial.println("Received data from PIR -> Move detected");

        break;
      }
    case 3: {

        buf = byte2;
        data = byte1 + buf / 10;

        Serial.print("Received data from gas sensor -> %gas:");
        Serial.println(data);

        break;
      }
    default: {

        Serial.println("a problem accured");

        break;
      }
  }

}

void NRF_receiverBegin() {

  //reading
  /*digitalWrite(8, 0);
    SPI.transfer(0x00);
    delay(10);
    Serial.println(SPI.transfer(0xff), BIN);
    delay(10);
    digitalWrite(8, 1);*/

  pinMode(7, OUTPUT);  //CE
  pinMode(8, OUTPUT);  //CSN
  delay(100);
  digitalWrite(8, 1);
  digitalWrite(7, 0);

  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.begin();
  delay(100);

  digitalWrite(8, 0);   //flush TX_FIFO
  SPI.transfer(0xe1);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);   //flush RX_FIFO
  SPI.transfer(0xe2);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x07 + 0x20);
  delay(10);
  SPI.transfer(0xf0);
  delay(10);
  digitalWrite(8, 1);
  delay(10);

  digitalWrite(8, 0);
  SPI.transfer(0x00 + 0x20);
  delay(10);
  SPI.transfer(0x0f);
  delay(10);
  digitalWrite(8, 1);
  delay(10);

  /*digitalWrite(8, 0);
    SPI.transfer(0x11 + 0x20);
    delay(10);
    SPI.transfer(0x01);
    delay(10);
    digitalWrite(8, 1);*/

  //Down for DYNPL
  digitalWrite(8, 0);
  SPI.transfer(0x1c + 0x20);
  delay(10);
  SPI.transfer(0x01);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x1d + 0x20);
  delay(10);
  SPI.transfer(0x04);
  delay(10);
  digitalWrite(8, 1);
  //Up for DYNPL

  digitalWrite(8, 0);
  SPI.transfer(0x01 + 0x20);
  delay(10);
  SPI.transfer(0x3f);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x02 + 0x20);
  delay(10);
  SPI.transfer(0x03);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x03 + 0x20);
  delay(10);
  SPI.transfer(0x03);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x04 + 0x20);
  delay(10);
  SPI.transfer(0xff);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x05 + 0x20);
  delay(10);
  SPI.transfer(0x4c);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x06 + 0x20);
  delay(10);
  SPI.transfer(0x06);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x0a + 0x20);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  digitalWrite(8, 1);

  digitalWrite(8, 0);
  SPI.transfer(0x10 + 0x20);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  SPI.transfer(0xaa);
  delay(10);
  digitalWrite(8, 1);

}

void NRF_startListening() {

  attachInterrupt(digitalPinToInterrupt(2), IRQ, FALLING);

  digitalWrite(7, 1);   //CE High
  Serial.println("Listening started");

}

void NRF_monitorRegisters() {

  for (int i = 0; i < 30; i++) {
    digitalWrite(8, 0);
    SPI.transfer(i);
    delay(10);
    Serial.print(i , HEX);
    Serial.print(" -> ");
    Serial.println(SPI.transfer(0xff), BIN);
    delay(10);
    digitalWrite(8, 1);
  }
  Serial.println("");

}

void setup() {

  Serial.begin(115200);

  NRF_receiverBegin();
  NRF_startListening();
  NRF_monitorRegisters();

}

void loop() {

  /*if (millis() - lastTime > 20000) {
    NRF_monitorRegisters();
    lastTime = millis();
  }*/

}

```
> 1 votes

# Answer
You may have reversed the wire:

```
RF24 radio(7, 8); //  CE,CNS

```
> 0 votes

---
Tags: arduino-uno, serial, softwareserial, nrf24l01+, rf
---


title: Why can't my IF statement see a global?

text:
# Question
Title: Why can't my IF statement see a global?
I'm rather new to Arduino programming. I have a problem compiling the following bit of code:

```
const int relay1 = 10;  //Power Relay 1
const int relay2 = 11;  //Power Relay 2
const int relay3 = 12;  //Toggle Relay
const int button1 = 3;
const int button2 = 4;
const int button3 = 5;

//---Button States---\\
int button1State;   //Current state of Button 1
int button2State;   //Current state of Button 2
int button3State;   //Current state of Button 3
int button1State_prev = LOW;  //Previous state of Button 1
int button2State_prev = LOW;  //Previous state of Button 2
int button3State_prev = LOW;  //Previous state of Button 3

//---General Variables---\\
int userSelection = 0;
int interlockState = 0;
int platformState = 0;

//---Interval-Tracking Variables---\\
unsigned long lastTime_Debounce1 = 0;   //Button 1 debounce time
unsigned long lastTime_Debounce2 = 0;   //Button 2 debounce time

//---Activity Delays---\\
const unsigned int relayDelay = 10;           //Delay between relay actions (ms)
const unsigned int debounceDelay = 60;        //Delay for button de-bouncing (ms)

void setup() {
  //Configure Pins
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);

  digitalWrite(relay1, LOW);
  digitalWrite(relay2, LOW);
  digitalWrite(relay3, LOW);
}

void loop() {
  //Read value of each input pin
  int button1Reading = digitalRead(button1);  //Current reading of Button 1
  int button2Reading = digitalRead(button2);  //Current reading of Button 2
  int button3Reading = digitalRead(button3);  //Current reading of Button 3

  //Debounce Button1
  if (button1Reading != button1State_prev) {
    lastTime_Debounce1 = millis();
  }
  button1State_prev = button1Reading;
  if ((millis() - lastTime_Debounce1) > debounceDelay) {
    if (button1Reading != button1State) {
      button1State = button1Reading;
    }
  }

  //Debounce Button2
  if (button2Reading != button2State_prev) {
    lastTime_Debounce2 = millis();
  }
  button2State_prev = button2Reading;
  if ((millis() - lastTime_Debounce2) > debounceDelay) {
    if (button2Reading != button2State) {
      button2State = button2Reading;
    }
  }

```

For some reason, the compiler is convinced that the variable `lastTime_Debounce1` in the second IF-statement, on Line 54, has not been declared in-scope. I don't understand how this is possible, since the variable in question is a defined and initialized global.

If I comment-out the first trio of IF-statements (handling Button 1), the second trio (handling button 2) has no problem compiling, even though it does exactly the same thing in exactly the same way.

I checked all the usual suspects: spelling, braces, semicolons, even commented-out blocks of code one at a time, but I can't find the source of the problem. I'm using the Arduino 1.8.2 IDE.

Can someone please point out the mistake I'm missing?

# Answer
> 28 votes
The backslash in your comments are the problem. As per C++ language definitions, a `\` at the end of the line is interpreted as a "line continuation". Thus, your comment gets continued in the next line and your variable declaration and initialization is commented out.

This is apparent when opening your code with a good syntax highlighting program, like Notepad++.

Removing all `\\` from the end of the comment line solves your problem.

Side note: For more info, look at https://stackoverflow.com/a/30290133/5296568. Backslashes at the end of a line are actually useful when used in multi-line macro definitions.

---
Tags: c++, compilation-errors
---


# Question
Title: Why the program keeps applying what is in loop in first case and stops in the second one?
In the first program after removing hand from the button it keeps on, means it keeps applying what is in the loop:

```
int led = 13;
int button = 12;
void setup() {
  pinMode(led, OUTPUT);
  pinMode(button, INPUT);
             }
void loop() {
  if (digitalRead(button) == HIGH)
  {
    digitalWrite(led, HIGH);
  }
             }

```

while in the second one it needs to press the button every time in order to apply what is in the loop,means to flash in this case,

```
int led = 13;
int button = 12;
void setup() {
  pinMode(led, OUTPUT);
  pinMode(button, INPUT);
            }
void loop() {
  if (digitalRead(button) == HIGH)
  {
    digitalWrite(led, HIGH);
    delay(1000);
    digitalWrite(led, LOW);
    delay(1000);
  }
           }

```

Why different behavior although the same structure?

The problem is illustrated in this video : https://www.youtube.com/watch?v=u5WGvKwJYFY&t=2s

# Answer
> 2 votes
You read `value` only once ... what do you expected?

In the first sketch, you put the LED ON and never turn it OFF, no matter what.

In the second sketch, you put the LED ON and one second later you turned it OFF. As the `value` doesn't change, it keeps repeating.

You mistake: you read the button in `setup`. You have to read in each `loop` iteration.

```
void loop() {
  value = digitalRead(button);
  if (value == HIGH)
  {
    digitalWrite(led, HIGH);
    delay(1000);
    digitalWrite(led, LOW);
    delay(1000);
  }

```

# Answer
> 1 votes
This iteration of your code is better. Now, the difference in behavior is that nothing in the first code ever executes `digitalWrite(led, LOW);`, while each iteration though the second code does. Therefore the LED remains on forever in code 1, and depends on the button press in code two.

If the behavior you desire is that the code remembers if the button has ever been pressed, latch that event in some state variable, and then in `loop()`, act on the value of the state variable:

```
int led = 13;
int button = 12;
int everHit = 0;
void setup() {
  pinMode(led, OUTPUT);
  pinMode(button, INPUT);
}

void loop() {
  if (digitalRead(button) == HIGH) everHit = 1;
  if (everHit) {
    digitalWrite(led, HIGH);
    delay(1000);
    digitalWrite(led, LOW);
    delay(1000);
  }
}

```

---
Tags: led, switch, flash
---


# Question
Title: Having trouble passing data through RF24
I have three RF24, all of them are connected to one arduino-uno each. The first one has sensors that sends data to the second one then the second one passes it to the third one. The first pass from RF24 #1 to RF24 #2 is successful but from the RF24 #2 to RF24 #3 there seems to be a problem.

Code for the RF24 #1 (I just copied the setup and loop the other functions are for the sensors, I think it's unnecessary):

```
//Libraries for temperature
#include <OneWire.h>
#include <DallasTemperature.h>
#define motor1 8
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

//for pH meter
#define SensorPin A0            //pH meter Analog output to Arduino Analog Input 0
#define Offset 0.00            //deviation compensate
#define LED 13
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    //times of collection
int pHArray[ArrayLenth];   //Store the average value of the sensor feedback
int pHArrayIndex = 0;

//for NRF24L01
RF24 radio(7, 8); // CE, CSN
const uint64_t waddress = 0xB00B1E50D2LL;
struct package {
  float temperature, ph, Do, inch, cm1;
};
typedef struct package Package;
Package data;
int LID = 4, LOD = 6;

//for ultrasonic
const int trigPin = 3;
const int echoPin = 4;
long duration, inches, cm, meter;

void setup(void)
{
  // start serial port
  radio.begin();
  radio.openWritingPipe(waddress);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();

  pinMode(LED, OUTPUT);
  // Start up the library
  sensors.begin();
}

/*
   Main function, get and show the temperature
*/

void loop(void)
{
  static unsigned long samplingTime = millis();
  static unsigned long printTime = millis();
  static float pHValue, voltage;
  if (millis() - samplingTime > samplingInterval)
  {
    pHArray[pHArrayIndex++] = analogRead(SensorPin);
    if (pHArrayIndex == ArrayLenth)pHArrayIndex = 0;
    voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024;
    pHValue = 3.5 * voltage + Offset;
    samplingTime = millis();
  }
  if (millis() - printTime > printInterval)  //Every 800 milliseconds, print a numerical, convert the state of the LED indicator
  {
    digitalWrite(LED, digitalRead(LED) ^ 1);
    // call sensors.requestTemperatures() to issue a global temperature
    // request to all devices on the bus

    sensors.requestTemperatures(); // Send the command to get temperatures

    // After we got the temperatures, we can print them here.
    // We use the function ByIndex, and as an example get the temperature from the first sensor only.

    //Serial.print(pHValue,2);
    //Serial.print(",");
    //Serial.print(sensors.getTempCByIndex(0));

    radio.write(&data, sizeof(data));

    data.ph = (pHValue);
    data.temperature = (sensors.getTempCByIndex(0));
    Serial.print(data.ph);
    Serial.print(data.temperature);
    Serial.print(data.Do);
  }
}

```

RF24 #2

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
RF24 radio(7, 8); // CE, CSN
const uint64_t raddress = 0xB00B1E50D2LL;
const uint64_t waddress = 0xB00B1E50B1LL;
struct package {
  float temperature, ph, Do, inch, cm1;
};
typedef struct package Package;
Package data;

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(waddress);
  radio.openReadingPipe(1, raddress);
  radio.setPALevel(RF24_PA_MIN);
}

void loop() {
  radio.startListening();

  while (radio.available()) {
    radio.read(&data, sizeof(data));
    Serial.print(data.ph);
    Serial.print(",");
    Serial.print(data.temperature);
    Serial.print(",");
    Serial.print(data.Do);
    Serial.print(",");
    Serial.print(data.inch);
    Serial.print(",");
    Serial.println(data.cm1);
  }
  if (radio.write(&data, sizeof(data))) {
    Serial.println(" delivery failed");
  }
  radio.stopListening();
  delay(200);
}

```

RF24 #3

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
int lid = 2 , lod = 4;
RF24 radio(7, 8); // CE, CSN
const uint64_t raddress = 0xB00B1E50B1LL;
struct package {
  float temperature, ph, Do, inch, cm1;
};
typedef struct package Package;
Package data;

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

  radio.begin();
  radio.openReadingPipe(2, raddress);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
  pinMode(lid, OUTPUT);
  pinMode(lod, OUTPUT);
}

void loop() {
  unsigned long startTimer = millis();
  bool timeout = false;

  while (!radio.available() && !timeout) {
    if (millis() - startTimer > 500 )
    {
      timeout = true;
    }
    // radio.read(&temperature, sizeof(temperature));
    //radio.read(&Do, sizeof(Do));
  }
  if (timeout) {
    Serial.println("Failed to receive data");
  }
  else {
    radio.read(&data, sizeof(data));

    Serial.print(data.ph);
    Serial.print(",");
    Serial.print(data.temperature);
    Serial.print(",");
    Serial.print(data.Do);
    Serial.print(",");
    Serial.print(data.inch);
    Serial.print(",");
    Serial.println(data.cm1);
  }
}

```

The serial monitor for RF24 #2 displays:

```
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
6.92,28.25,7.20,15.00,38.00
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
 delivery failed
6.91,28.25,7.20,15.00,38.00

```

RF24 #3 Serial Monitor:

```
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00
0.00,0.00,0.00,0.00,0.00

```

Sometimes RF24 #3 receives the data and prints it continuously. I don't know why. Most of the time it displays the above.

Edit: Revision

Update: It turns out that RF24 #3 continuous to print even if RF24 #2 is unplugged/not powered.

# Answer
You should always call `stopListening()` right before you `write()`. Also `write()` returns true when messages are delivered so your condition is wrong. Try changing the `loop()` in the second node to:

```
void loop() {
  while (radio.available()) {
    radio.read(&data, sizeof(data));
    Serial.print(data.ph);
    Serial.print(",");
    Serial.print(data.temperature);
    Serial.print(",");
    Serial.print(data.Do);
    Serial.print(",");
    Serial.print(data.inch);
    Serial.print(",");
    Serial.println(data.cm1);

    radio.stopListening();
    if (!radio.write(&data, sizeof(data))) {
      Serial.println("Delivery failed");
    }
    radio.startListening();
  }
}

```

If a packet is available, it's read, printed and forwarded. The third node's `loop()` should also be adjusted to something like:

```
bool new_data = false;

void loop() {
  if (radio.available()) {
    radio.read(&data, sizeof(data));

    Serial.print(data.ph);
    Serial.print(",");
    Serial.print(data.temperature);
    Serial.print(",");
    Serial.print(data.Do);
    Serial.print(",");
    Serial.print(data.inch);
    Serial.print(",");
    Serial.println(data.cm1);
    new_data = true;
  }
  if (new_data) {
    // do stuff
    new_data = false;
  }
}

```

Data is sent in 32-byte payloads and your entire package is 20 bytes (without padding), assuming a float = 4 bytes. So a complete packet has either arrived or it hasn't; no point in waiting in one place. `new_data` lets you know when there's new stuff obviously and you clear the flag when you're done processing the data. This way, you can do other stuff while you wait for a packet to show.
> 0 votes

---
Tags: arduino-uno, sensors, timers, nrf24l01+
---


# Question
Title: strcmp() returns 0 when chars are different
I am trying to build a sketch that reads a single number from the Serial Monitor and uses it to light a 7 segment display with this number.

I need to compare the input with the known values, stored in a char array, to know which character was typed in and associate the matching binary combination to light the 7 segment display.

I have made a sample code extracted from the sketch, just to test if I am able to pass a char and get the correct result back:

```
char nums[] = "0123456789."; // The characters we will check against

/* Tried also these, same results
      char nums[12] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '\0'};
      char nums[] = "456789.0123";
*/

void setup() {
  Serial.begin(9600);
  Serial.println("Write a single character"); Serial.println(" ");
}

void loop() {
  if (Serial.available() > 0) {
    char text = Serial.read(); // Read a single char from serial
    Serial.print("Character provided is: "); Serial.println(text);
    char c = parseChar(text); // Evaluate the char
    Serial.print("Character returned is: "); Serial.println (c);
    if (strcmp(c, text) == 0) { // Check if the returned char is the same
      Serial.print("      CORRECT character returned");
    } else {
      Serial.print("      WRONG character returned");
    }
    Serial.println(" ");
  }
}

char parseChar(char c) {
  int comp = 0;
  Serial.println("----- parseChar() START-----");
  Serial.print("  Parameter 'c' is: "); Serial.println(c);
  for (int i = 0; i < sizeof(nums) ; i++) { // Check the values of the array one by one
    comp = strcmp(c, nums[i]); // Compare the chars
    Serial.print("  Compare to nums["); Serial.print(i); Serial.print("] = "); Serial.print(nums[i]); Serial.print(" --> Result: "); Serial.println(comp);

    /* If the check matches, return the character at that index.
       For simplicity, it just returns the matching char of the array,
       that should be the same as the one sent in to the function.
    */
    if (comp == 0) {
      Serial.println("----- parseChar() END (found) -----");
      return nums[i];
    }
  }
  Serial.println("----- parseChar() END (not found)-----");
  return 0;
}

```

The function works well for all numbers from 0 to 6. However, for any number over 6, or any other character, the strcmp() function returns always 0, so the returned character is the index 0 of the array, regardless of the character typed.

This is the Serial Monitor output for different characters:

```
Write a single character

Character provided is: 3
----- parseChar() START-----
  Parameter 'c' is: 3
  Compare to nums[0] = 0 --> Result: 1
  Compare to nums[1] = 1 --> Result: 1
  Compare to nums[2] = 2 --> Result: 1
  Compare to nums[3] = 3 --> Result: 0
----- parseChar() END (found) -----
Character returned is: 3
      CORRECT character returned

Character provided is: 6
----- parseChar() START-----
  Parameter 'c' is: 6
  Compare to nums[0] = 0 --> Result: -6
  Compare to nums[1] = 1 --> Result: 1
  Compare to nums[2] = 2 --> Result: 1
  Compare to nums[3] = 3 --> Result: 1
  Compare to nums[4] = 4 --> Result: 1
  Compare to nums[5] = 5 --> Result: 1
  Compare to nums[6] = 6 --> Result: 0
----- parseChar() END (found) -----
Character returned is: 6
      CORRECT character returned

Character provided is: 7
----- parseChar() START-----
  Parameter 'c' is: 7
  Compare to nums[0] = 0 --> Result: 0
----- parseChar() END (found) -----
Character returned is: 0
      WRONG character returned

Character provided is: g
----- parseChar() START-----
  Parameter 'c' is: g
  Compare to nums[0] = 0 --> Result: 0
----- parseChar() END (found) -----
Character returned is: 0
      WRONG character returned

```

As you can see, the parseChar() function never returns a "not found" result, even for chars that are not in the array. In fact, it never loops through the array, as the first comparison returns 0 always.

I can't figure out why the strcmp() function returns 0 when the chars are different. Am I missing something?

# Answer
> 4 votes
`strcmp` is not for comparing a single character like your `c` parameter. It is for comparing a null-terminated string. I'm a little surprised you didn't get a compiler error, but there it is.

If you want to compare individual characters, just compare them with `==`.

---
Tags: arduino-uno, serial, programming
---


# Question
Title: Purposely create compile error to fail the upload
I would like to create a compile error so sketch does not upload in certain cases.

I have written a library with a function that adds pins being used to an array. If the same pin is used twice I want to fail the compilation (preferably with an error that explains why). Is this possible?

```
void CheckPinNum(int newPinNum){
  for (int i=0; i <= PinArrayLength; i++){
    if (newPinNum == PinArray[i])
      failCompilation("You entered same pin twice!");
  }
}

```

# Answer
It's impossible to check dynamic behavior compile time.

However, the best 'alternative' I can think of, is during the setup set all pin numbers (if that is possible).

And if something is wrong, let the 'user' or client know something is wrong. In extreme cases, just by putting the Arduino in an endless loop, in best cases, send a serial line, blink a light or whatever feedback.

You can do the same later on (when CheckPinNumber needs to be called in the loop, so not at setup), but the sooner you can do these checks, the better.
> 0 votes

# Answer
To answer the question asked in the title:

```
#if some_condition
# error Some error message
#endif

```

But note that this technique only works at *compile time*, which probably makes it useless for you.
> 1 votes

---
Tags: arduino-ide, compile, compilation-errors, custom
---


# Question
Title: Running multiple programs with one Arduino
Is it a problem to use multiple softwares to read the data that came from the same USB port simultaneously?

I have a board connected to a PC by USB, which is read by an application developed in C#. I display the data from the board in a table form.

Now I have to plot the data. The problem is that both the board and the software are deployed and can't be modified. So I have to create another program to do that, but the user should be able to run both softwares simultaneously.

Thank you!

# Answer
The question is not so much about Arduino, but about PC serial ports. There are programs/drivers out there that allow a user to "split" a serial port into two or more virtual serial ports, each of which can be opened by separate Windows applications, such as your C# programs.

Some of these programs or drivers are commercial and not free, and some are free.

https://www.fabulatech.com/serial-port-splitter-help/serial-port-splitting.html

http://www.eterlogic.com/help/vspe/UsageSplitPage.html

http://www.aggsoft.com/tcp-com/tcp-com-com-splitting.htm
> 0 votes

---
Tags: arduino-uno, arduino-leonardo, c#
---


# Question
Title: Drive a 12V pump do I need a l293 driver
Me and my girlfriend are working on a small automatic plant watering system. Our first goal is to make an electrical 12V pump suck water out of a bottle.

As we were reading tutorials online we noticed that many people hook up a driver such as the l293 to their arduino in order to control the pump (essentially a brushed DC motor).

http://www.ti.com/lit/ds/symlink/l293.pdf

Our pump is 12V 4.2 W.

My question is do we really need a driver like that for just activating / deactivating the pump ?

In my understanding the driver offers an H-bridge setup allowing to control up to two motors in both directions.

Are there any other reasons to prefer this driver instead of a simple MOSFET / Transistor setup with such a simple use case like ours ?

Thank you for your help.

Best regards

# Answer
Unless you wish to reverse the direction of the pump without reconnecting the wires in the opposite way, there is no need for a L293. A MOSFET that operates as a switch should be sufficient in your case. You can also try to PWM it and reduce/control the water flow.
> 2 votes

---
Tags: arduino-uno, motor
---


# Question
Title: Joysitck with servo, LED array and buzzer
Does anybody know of a sketch that can turn a single servo 180 degrees clockwise/counterclockwise with the x axis of a joystick, light a bar graph LED with the Y axis, and sound a buzzer when the joystick button is depressed.

# Answer
> 3 votes
You have a distinct set of requirements that you could turn into a sketch yourself. I'm guessing you have never written a program before, in which case the problem really is you don't know how to do what you want to.

So, break the problem down into small chunks. The less complex a problem the more likely you are to find a generic solution on the web that you can 'borrow'.

1. How do you turn a servo?
2. How do you read the position of a joystick?
3. How do you light a LED bar graph?
4. How do you sound a buzzer?

I'm pretty certain that you can find pages that tells you how to do each of those in separate sketches. Once you have each of those working you need to merge the setup functions, making sure they don't over write each other and then tackle the loop functions (which will be more difficult). BUT I know there are posts on here about how to merge two sketches into one.

I'm 99% certain you will not find a sketch that does what you want. I'm 99% certain you will be able to coble together a solution that will do what you want if you break it down.

If you get stuck, post the code you have and explain your problem and people will help.

Good luck.

---
Tags: led, servo, buzzer, joystick
---


# Question
Title: Arduino Interrupts Classes and Namespace
I'm working inside the Arduino IDE environment and have made a class that builds on the Adafruit RDG LCD with interrupts While looking at how to combine the `Attach Interrupt()` into my class I came across this post about using namespaces

> Why make a class then? What about a namespace?
>
> A class with one instance is like a group with one person in it.
>
> -nickgammon

Understanding that Mr.Gammon is kind of a big deal around these parts, I'd like to understand how to insert/alter my current class into a namespace format. Currently, the most in-depth tutorial I've found is here, but I don't see how I would mix in the `Attach Interrupt()` function

Right now, my code looks like

```
/**** Pre-Setup *****/
#define Menu_PIN 3
voltile bool flag;

//Init Class
class LcdMenu : public Adafruit_RGBLCDShield
{
  public:
  MenuFoo()
}
LcdMenu LcdM;

//run Setup
void setup()   /****** SETUP: RUNS ONCE ******/
{
  pinMode(Menu_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(Menu_PIN), ProcMenu, FALLING);
}

void loop()
{
  if(flag){
    LcdM.MenuFoo();
    flag=false;
  }
}

//Handles Inturrupts for Class
void ProcMenu()
{
  flag=true;
}

//define MenuFoo
void LcdMenu::MenuFoo(){[code]}

```

As I understand it, Implementing a namespace would eliminate the need for the `ProcMenu()` function making my code easier to read/maintain.

# Answer
In this particular instance, and since you are inheriting from a class of a known library, making your own class makes sense. You just have to be aware that, although you can in principle have multiple instances of a class, you can only have *one single handler* for a particular interrupt. Thus the handler cannot be a regular method of the class (a method that knows it has been called for `this` instance), but it can be a `static` method. Such a method is much like a regular function which uses (abuses?) the class as a sort of namespace.

I would try something along these lines:

```
class LcdMenu : public Adafruit_RGBLCDShield
{
public:
  LcdMenu();
  void begin([params]) {
    Adafruit_RGBLCDShield::begin([params]);
    attachInterrupt(digitalPinToInterrupt(Menu_PIN), handleInterrupt, FALLING);
  }
  void MenuFoo();
  void update() {
    if (flag) {
      MenuFoo();
      flag=false;
    }
  }
private:
  static volatile bool flag;
  static void handleInterrupt() { flag = true; }
}

volatile bool LcdMenu::flag;

```

Then you just have to call `LcdM.update()` in `loop()`.
> 1 votes

# Answer
I don't it will change your design.

The main reason to use namespaces is to have an extra 'layer' of hierarchy.

Like a book that can be divided in chapters (classes). But if you want to combine multiple books (projects) than you use name classes (e.g. to prevent name clashes of equally named class names).
> 0 votes

---
Tags: interrupt, class
---