message:
My Arduino got stuck and continuous looping in if condition

I'm using RTC and when the if condition is true the Time gots stuck and the condition keeps looping. Please help

Here is my code:

    // CONNECTIONS:
    // DS1302 CLK/SCLK --> 5
    // DS1302 DAT/IO --> 4
    // DS1302 RST/CE --> 2
    // DS1302 VCC --> 3.3v - 5v
    // DS1302 GND --> GND
    #include <Servo.h>
    #include <ThreeWire.h>
    #include <RtcDS1302.h>

    ThreeWire myWire(4,5,2); // IO, SCLK, CE
    RtcDS1302<ThreeWire> Rtc(myWire);
    int servoPin = 3;
    Servo Servo1;
    void setup ()
    {
        Serial.begin(57600);
        Servo1.attach(servoPin);
    //    Serial.print("compiled: ");
    //    Serial.print(__DATE__);
        Serial.println(__TIME__);

        Rtc.Begin();

        RtcDateTime compiled = RtcDateTime(__TIME__);
        printDateTime(compiled);
        Serial.println();

        if (Rtc.GetIsWriteProtected())
        {
            Serial.println("RTC was write protected, enabling writing now");
            Rtc.SetIsWriteProtected(false);
        }

        if (!Rtc.GetIsRunning())
        {
            Serial.println("RTC was not actively running, starting now");
            Rtc.SetIsRunning(true);
        }

        RtcDateTime now = Rtc.GetDateTime();
        if (now < compiled)
        {
            Serial.println("RTC is older than compile time!  (Updating DateTime)");
            Rtc.SetDateTime(compiled);
        }
        else if (now > compiled)
        {
            Serial.println("RTC is newer than compile time. (this is expected)");
        }
        else if (now == compiled)
        {
            Serial.println("RTC is the same as compile time! (not expected but all is fine)");
        }
    }

    void loop ()
    {
        RtcDateTime now = Rtc.GetDateTime();

        printDateTime(now);
        Serial.println();
        delay(5000);

    //here is my problem>>>>

        if(now.Hour() == 22 && now.Minute() == 40)
        {
          Servo1.write(0);
          delay(1000);
          Servo1.write(90);
          delay(1000);

        }

    //////////////////////

        delay(5000);

    }

    #define countof(a) (sizeof(a) / sizeof(a[0]))

    void printDateTime(const RtcDateTime& dt)
    {
        char datestring[20];
    //u/u/u
        snprintf_P(datestring,
                countof(datestring),
                PSTR("u:u:u"),
    //            dt.Month(),
    //            dt.Day(),
    //            dt.Year(),
                dt.Hour(),
                dt.Minute(),
                dt.Second() );
        Serial.print(datestring);
    }

body:
What is being brought to your attention is the following part of your code...

    //here is my problem>>>>

    if(now.Hour() == 22 && now.Minute() == 40)
    {
      Servo1.write(0);
      delay(1000);
      Servo1.write(90);
      delay(1000);
    }

In this code you use an "if" statement and ask:
   if the now.Hour is equal 22 AND if the now.Minute is equal 40 then
    write a 0 to your servo then
    delay for 1000
    then write a 90 to your servo
    and wait another 1000

What is being brought to your attention is that until now.Hour changes or
until now.Minute changes your write 0, delay, write 90, delay will continue
on and on and on until now.Hour changes (which will take a while) or now.Minute
changes. Since minutes are 60 seconds long your code will repeat for all of those
60 seconds...

If you were to change your code to include, oh, lets say now.Second() (like this)--

    if(now.Hour() == 22 && now.Minute() == 40 && now.Second() == 00)

Then your code will repeat over and over until now.Second changes (which will take 1 second).

By the time your loop gets back to the "if" statement now.Second will no longer be 00 and it will not be "stuck" for you...

********
As has been brought to my attention, your 5 second delay will be a problem, so you might find that changing it will allow the now.Second "fix" to work.

In the following part of your code change delay(5000)

    void loop ()
    {
        RtcDateTime now = Rtc.GetDateTime();

        printDateTime(now);
        Serial.println();
        delay(5000);
    }

to something like delay(1000) or so.

That way it will only wait 1 second before dropping out of the loop and checking the loop with the newly added now.Second(). This will make the printDateTime(now) happen every second instead of every 5 seconds, but it shouldn't get "stuck".

Hopefully this helps you to better understand how time (and its parts) work.


sender: user

message:
why sound appears between VCC and GND pins in esp8266 module?

When I use esp8266 as **STATION** mode and connect a speaker between VCC(3.3v) and GND pin a sound appears like "doop doop". what is this sound?
I test this in version 01 and 12 of esp8266 module and this appear in both versions.
maybe you ask me why I connect speaker to this pins. problem is that when I use pwm of esp8266 for playing a sound, this sound ("doop doop") appear to it also.
What is problem? How can I fix this?

sender: assistant

body: It's called "noise" and is to be expected. Wi-Fi devices are generally very electrically noisy - and the ESP8266 is no exception.


message:
Can Arduinos keep a 500mu timer?

I need to output a serial message on a 500 microsecond interval (10 bytes), can be a little slower but no more than 1 milisecond between messages.

Can it be done with an Arduino? I know there is a delayMicro(), but not sure if it has the resolution.

body:
It's not related to the delayMicro, but to the max speed of the Serial/UART driver, which is not documented, but according to some people it can reach 500 kbps.

However, 10 bytes, each 500 us (2000 Hz) means 10 * 11 (including some stop/start bit) * 2000 = 220.000 bits, so you have some headroom left. Maybe there is also some timing overhead.

Anyway, probably the only way to go is using an interrupt, and expect the Uno is not able to do anything else.

A better option might be to send less or send smarter (i.e. not 10 bytes, but maybe some compressed/binary form if not already thought about).


message:
One Arduino collects data, several other Arduinos use the data. What is a simple way to do this?

I am looking for a way to exchange a few bytes of data from one Arduino to two or more additional Arduinos. It's a one way communication and speed is not a problem. 10Hz is fast enough.

**Data Collector Arduino:** I have one Arduino with SPI and I2C shields which collects and analyzes data from a CAN-BUS in a motorcycle. The CAN-BUS supplies lots of information but I filter it down to few info like which lights are on, intake temperature, motor RPM, which gear.

**Light Control Arduino:** This Arduino should know which lights are on. Depending on low beam, high beam, indicators, etc. it will control additional lights which are not part of the original bike.

**Motor Control Arduino:** This Arduino should know the current RPM, gear, etc. and work with that data.

**The question is how do I "transfer" the data from the data collector to the other Arduinos?** If it would be a little simpler I would connect some digital pins which the data collector would write and the others would read. But there are not enough pins for my needs and why use 10 pins when maybe 2 are enough.

All the Arduinos use SPI and I2C connected devices so I don't think it's a good idea to use SPI or I2C for communication between the Arduios.

I guess Serial communication would work with 2 Arduinos but not with 3 or even more. Maybe I could use multiplexing or something like that?

Maybe I could let the data collector Arduino write data into some kind of shared memory and the other Arduinos could read it?

**What do you suggest? I am sure there are simple solutions out there but I didn't find anything. I don't mind any extra ICs.**

Before someone suggest to do all in one Arduino: Maybe it would be possible. But I really like to keep the modules (Arduinos) separate and I want to be able to add others later if I want to. Then I only want to change the software of the collector Arduino and don't touch the others.

body: You can do it simply by addition of extra RX and TX pins by use of library like Software Serial Library. For reference you can go here https://www.arduino.cc/en/Tutorial/TwoPortReceive . By using this library you can increase number of ports in master arduino and you probably can give command to other slave arduino commands through master arduino. In this way each arduino can communicate with each other.


body:
It is possible to send out data from one Arduino to multiple others at once via serial (UART). You simply connect the TX of your master Arduino to the RX of all the slave Arduinos. All receiving Arduinos will get the same data with that. You only need 1 pin (for the connection sender TX to the multiple RX). This is a bit limited to the number of slaves and the speed, but that doesn't seem to be an issue here (since you only have a few).

This is a 1-way communication, since at any line there must not be more than 1 TX (sender). If you have more than 1 TX on a line, you will burn your hardware as soon as both TX send out data simultaneously.

I remember some sites that stated it to be possible to also do multiple sender UART, when you adhere to a protocol and put in some safety hardware (I think they used diodes and current limiting resistors). But that is somewhat out of scope here. If you really need a 2-way communication, you maybe should rethink the whole structure of your solution. As Juraj suggested in his comment, it might then be easier to unite the functions to less Arduinos.

---

Be sure, that the Arduinos share the same ground. This is needed for any communication, when you don't utilize extra hardware (like an optocoupler).


message:
Applying 5v to analogWrite Pin

I am controlling a motor with an Arduino Nano, that motor is controlled by Cytron MD-10c motor controller.

i want to wire a momentary switch in parallel with the analog output PIN from the Arduino and PWM input on the MD-10c, the switch will connect the 5v output from Arduino to the PWN input on the MD-10c. Basically an override to go full power.

Is there any risk of damage with this sort of wiring with the switch?

body:
Yes, depending on the current that will flow.

If your PWM output pin is connected to 5V without a current limiting resistor, nothing will happen during the `HIGH` phases of the PWM, but you will short the input pin during the `LOW` phases.

According to the [manual of your motor controller][1], you should be able to use a current limiting resistor to prevent this.
Since the ATMega328P on your Arduino Nano can sink a maximum of 40 mA, that resistor should be at least 125 Ohms. A resistor larger than 1 kOhm should work fine.

The other option would be installing a diode between your Arduino Nano and the motor controller.
This does not require the use of a current limiting resistor.
The motor controller would still work, since the minimal voltage for the pin state to be detected as `HIGH` is 3V ([1]), much lower than the ~4.3V you're left with after a diode.

  [1]: https://www.robotshop.com/media/files/pdf2/cyt-132-v2.3.pdf


message:
Frequency measuring using Arduino (AC analog input)

What I aim to do:
To measure the frequency of an AC analog signal generated by an electrodynamic shaker, which has a peak voltage of 10V-- using an Arduino Uno.

What I have tried:
Tried using a circuit similar to an optocoupler (using a 2N2222) transistor to take pulse input, using the `pulsein()` function. However the duration is always returning as 0.

My questions:

* Is this method an acceptable way of measuring frequency?
* What could I be doing wrong such that the time duration is always returning 0?
* Is there an easier way of carrying out this work?

Will put up the code if asked for. However it is basically just defining a few variables (for pins, duration etc), and then using the `pulsein` function.

![Here is the image of the circuit diagram]
(https://i.stack.imgur.com/jW4ll.jpg)

body:
This project includes a frequency counter.

https://www.instructables.com/id/Oscilloscope-in-a-Matchbox-Arduino/

From the project page:
This oscilloscope costs the price of an Arduino Nano (£2 and a display (£3) plus a few pence for resistors, etc. It's specification is:

 - max 1M samples/second, min 1000sps
 - 8-bits per sample
 - DC 0-5V; AC +/- 550mV, AC +/- 117mV, AC +/- 25mV
 - USB "PC scope" or built-in display
 - could be battery-powered
 - optional logic display
 - **optional frequency meter**
 - optional voltmeter
 - optional signal generator

My comment: I build it, it's a nice little project and the author is an expert programmer.


body:
> Is this method an acceptable way of measuring frequency?

Nope, not at all.

> What could I be doing wrong such that the time duration is always returning 0?

You are misusing pulsein(), it doesn't work like that; look up the documentation for it!

> Is there an easier way of carrying out this work?

Yes; there are many ways, you can research many of them. One thing you can do is make a peak detector, either in hardware or software, and then design a way to get a counts/time, which should correlate to the frequency!


message:
MQTT subscribe callback fails to be called in ESP8266 deepsleep mode

Refer to

 - https://arduino.stackexchange.com/questions/61229/esp8266-deep-sleep-and-mqtt

I executed the code in the given link. However i am not able to receive the subscribe message that are send from MQTT test broker(MQTT Lens) on the serial console.

Please help.
I am receiving successful call to both publish methods

    #include <ESP8266WiFi.h>
    #include <PubSubClient.h>
    const char* ssid = "honored";
    const char* ss_pswd = "12345678";
    const char* mqtt_server = "iot.eclipse.org";

    void callback(char* topic, byte* payload, unsigned int length);
    WiFiClient EspClient;

    PubSubClient client(EspClient);

    void wifi_setup() {
      Serial.print("Connecting to: ");
      Serial.println(ssid);
      WiFi.begin(ssid, ss_pswd);
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println(".");
      }
      Serial.println("");
      Serial.println("WiFi connected");
      Serial.println("IP address: ");
      Serial.println(WiFi.localIP());
    }
    void reconnect() {
      while (!client.connected()) {
        Serial.print("Attempting MQTT connection...");
        String ClientId = "ESP8266";
        ClientId += String(random(0xffff), HEX);
        if (client.connect(ClientId.c_str())) {
          Serial.println("connected");
          client.publish("outtopic", "hello world, finally");
          client.subscribe("/room/test");
        } else {
          Serial.print("failed, rc=");
          Serial.println(client.state());
          Serial.println("Try again...");
          delay(5000);
        }
      }
    }
    void sendMQTTMessage() {
      Serial.println("sending your message");
      if (!client.connected()) {
        reconnect();
      }
      client.publish("/sensor/pir", "on");
    }
    void callback(char* topic, byte* payload, unsigned int length) {
      Serial.print("Message arrived: ");
      Serial.println(topic);
      for (int i = 0; i < length; i++) {
        Serial.print((char)payload[i]);
      }
    }

    void setup() {
      Serial.begin(115200);
      wifi_setup();
      client.setServer(mqtt_server, 1883);
      sendMQTTMessage();
      client.setCallback(callback);
      delay(2000);
      Serial.println("going into deep sleep");
      ESP.deepSleep(10 * 1000000);
    }

    void loop() {

    }

body:
My solution:
update_mqtt() is called before deepSleep

    PubSubClient mqtt_client(client);
    boolean cb = false;

    void callback_mqtt_switch(char* topic, byte* payload, unsigned int length) {
      String lowerstr = "";
      for (uint8_t i = 0; i < length; i++) {
        lowerstr += (char)payload[i];
      }
      lowerstr.toLowerCase();
      DebugOut("Sleep payload: " + lowerstr);
      if (!back_to_sleep) {
        sleep_on = lowerstr == "ein";
      }
      cb = true;
    }

    void update_mqtt() {
      int i = 0;
      while (!cb && i++ < 30) {
        mqtt_client.loop();
        delay(10);
      }
      #ifdef TEST
        Serial.print("Warte ");
        Serial.println(i * 10); // max. 300ms gewartet
      #endif
      cb = false;
    }


message:
Can i use a sparkfun rfid qwiic without an id-xxla?

[Sparkfun rfid qwiic][1]

[id-20la][2]

I am using an Arduino UNO R3.

You should assume that i don't know anything. If yes can you give some information about how to do it? Thanks for any help.

  [1]: https://www.sparkfun.com/products/15191
  [2]: https://www.antratek.com/rfid-reader-id-20

body: No. It is not an RFID reader. It just interfaces to an RFID reader. You need an RFID reader to read RFID tags. That Sparkfun board just controls the reader and reads the data from it.


message:
Strange artifact in writing to serial while executing loop

Hope you can see this.

https://gist.github.com/DevilWAH/60ad144d2858f53845ac2e80f84bb070

The main file in this is "morse-led-rfid" which is taking reading data of an RFID tag and then displaying the text as Morse code on to a APA102 / Dotstar LED strip.

The issue is when the function updatestrip(tempbuffer[i]); is called.

    Serial.println(F("\n**Start Reading**\n"));

      for (uint8_t i = 1; i < 15; i++)
      {
       if (i != 3 && i!= 7 && i != 11 && i != 15 ) // Skip the non data blocks
        {
         readblock (i, key);
           for (uint8_t i = 0; i < 16; i++)
             {
          updatestrip(tempbuffer[i]);
          Serial.write(tempbuffer[i]);
            }
        }
      }

This is what I am calling to scroll the LED strip and write the letter in morse. if in the code snip it above i comment out "updatestrip...." then i get the txt from the RFID tag printer to serial as i would expect.

as a soon as i un comment it, the strip displays the morse code but the serial output gets garbled, it misses letters, prints reversed "?'s" and repeats its self?

Good output = "My Bunny is the best"
Bad output = "?Bunny is the ?t" (question marks reversed)

Further investigation i found if i leave it uncommented but go all the way to the bottom of the "more-strip" sheet and comment out the "else statement in the shiftLED function" the serial again displays correctly, but of course the led don't :)

    void shiftLED() // shift all LED up 1
      {
        for(uint16_t i = ledCount; i > 0; i--)
        {

          if ((colors[i - 1].red == 0 ) && (colors[i - 1].green == 0 ))
           {
              colors[i] = cblack;
            }
          else if (i > 19 && i < 40)
          {
            colors[i] = cred;
          }
         // else
         // {
         //   colors[i] = cgreen;
         // }
         // }

     }

Can any one suggest why the else statement a few function down is affecting the "serial.write(tempbuffer[i])" in the main loop?

body:
In your code `colors` is declared as

    rgb_color colors[ledCount];

This means that the very first iteration of this cycle in `shiftLED`

    for (uint16_t i = ledCount; i > 0; i--)
    {
      // access colors[i]
    }

will access `ledCount[ledCount]` which is obviously out of bounds (and will actually *write* into that location!). The behavior is undefined after that.

Using unsigned types for "backward" array iteration requires a bit of skill. The common idioms are

    for (uint16_t i = ledCount; i > 0;)
    {
      --i; // do this ASAP

      // access colors[i]
    }

or

    for (uint16_t i = ledCount; i-- > 0;)
    {
      // access colors[i]
    }

or

    // Careful: this technique is not usable with unsigned types
    // narrower than `unsigned int`
    for (uint16_t i = ledCount - 1; i != -1; --i)
    {
      // access colors[i]
    }

This is assuming that you want to iterate over the whole array: from `[ledCount - 1]` all the way back to `[0]`.

But if you intended to iterate back to `[1]` and stop short of `[0]` (which is apparently the case), then a simple fix for your cycle would be

    for (uint16_t i = ledCount - 1; i > 0; i--)
    {
      // access colors[i]
    }

I.e. simply start from `ledCount - 1`, not from `ledCount`.


message:
Restoring all fuse bits on AtMega328P-PU

I'm worked with Low Fuse bits in AVRDUDEPROG 3.3. Fuses was non-inverted. And by mistake I enabled SUT1 and SUT0, when SUT0 was enabled. And when I programmed avr,
it shows me error that avrdude.exe: initialization failed, rc=-1. I have read I can restore it with Avr Fuse Doctor, but I can't buy or make with pcb. Can I recover avr with:
```cpp
#include <avr/io.h>

int main(void) {
    DDRB = 0xFF;
    while(1) {
        PORTB ^= 0xFF;
    }
}
```

and load it to another avr and connect it to broken avr?

Can I make doctor on breadboard or Can I do it with usbasp/isp?

Can I load a new bootloader in it?

body:
The following is from:
https://www.allaboutcircuits.com/projects/atmega328p-fuse-bits-and-an-external-crystal-oscillator/

"The two bits to be avoided unless you are absolutely certain you know what you are doing are bit7, the RSTDISBL (external reset disable) bit and bit 5, the SPIEN (Serial Peripheral Interface Enable) bit. Disabling either one is often the cause for "bricked" Atmel µCs; "leave them alone" is good advice."

According to the article SUT0 and SUT1 are clock start up time related bits. It doesn't seem as though it is necessary to use anything special to change them.

You will find the information at the website very usefu. I know I have.

The High Voltage (other names too) programmer you have mentioned should not be necessary if you only changed the SUT0 and SUT1 fuses.

HOWEVER, if you did change the SPIEN or RSTDISBL fuses, you should either get one of the special programmers or just purchase another 328P microprocessor.

If you search the internet for "AVR High Voltage programmer" you will find many ideas for how to build one.

This link :https://electronics.stackexchange.com/questions/33/arduino-as-avr-programmer/71
provides good information.


message:
Why my servo motor is always on?

[![Schematic][1]][1]

    #include <Servo.h>

    Servo myservo;

    int pos = 0;

    void setup() {

    pinMode(2, INPUT);
    myservo.attach(9);

    }

    void loop() {

      if (digitalRead(2) == LOW) {

        for (pos = 0; pos <= 180; pos += 1) {
          myservo.write(pos);
          delay(15);
        }

        for (pos = 180; pos >= 0; pos -= 1) {
          myservo.write(pos);
          delay(15);
        }
      }
      else {
        myservo.write(0);
        delay(15);
      }
    }

  [1]: https://i.stack.imgur.com/hnYrF.png "Schematic"

body: It looks like you need to enable the pull-up resistor on D2.  As written D2 is left floating and most likely is a low voltage relative to ground.  Enabling the pull up resistor will force the pin high until you flip the switch.


message:
MXCHIP IoT DevKit too many initializers for 'unsigned char [0]

**Question**

Trying to call the Display `draw` API using the sample code for the [azure logo bitmap sample code][1]. I'm unable to reach a point where I can the API because breaks when constructing the bitmap char arrays in my `BMPManager` class. I'm also testing custom bitmaps using this [pixelcraft][2] tool.

>In file included from /Users/gregorydegruy/Code/GitHub/_mr.u/mxchip/Main.ino:5:0:
sketch/srcsrc/BMPManager.cpp:4:2371: error: too many initializers for 'unsigned char [0]' unsigned char AzureBMP[] = {0,0,0,0,0,0,0,0,0,0,0,0, . . .

**Main**

    void loop()
    {
        Screen.print("start prgm...");
        delay(1000);
        Screen.draw(0, 0, 128, 8, bitMapManager.get_azure_bitmap());
        delay(5000);
        Screen.draw(0, 0, 128, 8, bitMapManager.get_nintendo_bitmap());
    }

**BMPManager**

    class BMPManager
    {
        private:
            unsigned char AzureBMP[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,192,192,224,240,56,12,192,240,224,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,224,224,224,224,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,224,248,252,254,255,255,63,15,3,64,248,254,255,255,255,255,255,252,248,224,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,240,252,127,31,3,3,15,127,254,240,192,0,0,0,0,8,28,28,28,28,156,220,252,124,60,28,0,0,0,252,252,248,0,0,0,0,0,0,252,252,248,0,0,0,0,252,252,252,112,56,28,28,28,0,128,224,240,248,28,28,12,12,28,248,248,240,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,224,248,252,255,255,255,255,63,15,3,0,0,0,0,0,0,3,7,15,31,63,127,255,255,255,255,255,252,240,224,128,0,0,0,0,0,0,64,112,124,127,31,7,7,7,7,7,7,7,7,31,127,126,120,64,0,96,112,120,126,127,103,99,97,96,96,96,0,0,0,63,127,127,240,224,224,96,96,56,127,127,127,0,0,0,0,127,127,127,0,0,0,0,0,0,15,63,127,123,243,227,227,227,227,99,99,35,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,8,8,8,8,8,12,12,12,12,12,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
            unsigned char NintendoSwitchBMP[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, 0xc0,0xc0,0xe0,0xe0,0xf0,0xf0,0xf8,0xf8, 0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, 0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, 0x00,0x00,0x00,0x00,0xf8,0xf8,0xf8,0xf8, 0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8,0xf8, 0xf8,0xf8,0xf0,0xf0,0xe0,0xe0,0xc0,0xc0, 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xc0,0xf0,0xfc,0xff,0xff, 0xff,0xff,0x7f,0x1f,0x0f,0x07,0x87,0x83, 0x83,0x81,0x81,0x81,0x81,0x81,0x01,0x01, 0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xfc,0xf0,0x80,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff, 0xff,0x0f,0x00,0x00,0xfe,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x78, 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x00,0x00,0x00,0xc0,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff, 0xff,0x00,0x00,0x00,0x00,0x01,0x03,0x03, 0x07,0x07,0x07,0x07,0x03,0x03,0x01,0x00, 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0x7f,0x3f,0x3f, 0x3f,0x3f,0x7f,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff, 0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xf1,0xc0,0x80,0x80,0x00, 0x00,0x80,0xc0,0xc0,0xf1,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff, 0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x0f,0x1f,0xff,0xff, 0xff,0xff,0xfe,0xf8,0xe0,0xe0,0xe0,0xc0, 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, 0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0x00,0x00,0x00,0x01,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, 0xff,0xff,0x1f,0x0f,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, 0x03,0x03,0x03,0x07,0x0f,0x0f,0x0f,0x1f, 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, 0x00,0x00,0x00,0x00,0x1f,0x1f,0x1f,0x1f, 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, 0x1f,0x0f,0x0f,0x0f,0x07,0x03,0x03,0x03, 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

        public:
            BMPManager() {}
            unsigned char* get_azure_bitmap() {
                return AzureBMP;
            }
            unsigned char* get_nintendo_bitmap() {
                return NintendoSwitchBMP;
            }
    };

  [1]: https://microsoft.github.io/azure-iot-developer-kit/docs/apis/display/#draw
  [2]: https://pixelcraft.cc/

body:
In C++ you are not allowed to declare non-static member arrays with unspecified size (empty `[]`). Supplying an in-class *brace-or-equal* (BoE) initializer for such non-static member array does not override this rule

    struct S
    {
      int a[] = { 1, 2, 3 }; // <-- ERROR: `[]` array declaration is not allowed here
    };

If you really need these arrays as *non-static* members of the class, you will have to explicitly specify their size (which is `1024` in your case). Once you do that, you will also be able to BoE initializers for them right inside the class definition

    class BMPManager
    {
    private:
      unsigned char AzureBMP[1024] = { /* whatever */ };
      unsigned char NintendoSwitchBMP[1024] = { /* whatever */ };
      ...
    };

The `=` is optional.

---

However, the real question in this case is whether you really need these arrays as non-static (and non-const) members of the class. Do you really need independent instances of these arrays in each instance of `BMPManager` class? Are these arrays supposed to be modifiable?

If you really need independent instances of such arrays in each object, then you will have to do what's shown above.

But if you don't need independent arrays in each object (which would probably also imply that the arrays are not supposed to change) then the proper way to go about it would be to declare them as `static` members

    class BMPManager
    {
    private:
      static unsigned char AzureBMP[];          // static const ?
      static unsigned char NintendoSwitchBMP[]; // static const ?
      ...
    };

and then define them in one of the `.cpp` files as

    unsigned char BMPManager::AzureBMP[] = { /* whatever */ };
    unsigned char BMPManager::NintendoSwitchBMP[] = { /* whatever */ };

Note that in this case you will not be able to use BoE initializers directly in class definition. The initializers are supplied at the point of static member definition in `.cpp` file.

This can be done much more compactly in C++17, but I'd guess that you are using Arduino IDE, which still sticks to C++11.

---

Also, make them `const`, if appropriate.

Looking at the documentation at IoT DevKit web site you linked I see that it contains a number of ridiculous typos making it almost unusable. It is quite possible that you will run into problems with their library if you properly use const-correctness in your code.


message:
LCD Display 128x64 weird pin, C86 (input)

I got some LCD display from my friend. Base on the model number (TopWay LM6023) printed on product, I found the data sheet from google. According to the [datasheet][1], it is a 128*64 LCD display, but I am confusing the pin out does not same/similar to the famous one. I read the datasheet, there are C86 pin. I have no idea what’s that, and how to make it work. I created a [github repo][2], I am wonder if someone could help to write an example code and wiring to Arduino UNO.

Moreover, I also would like to know what is 6800 & 8080 interface, is it Arduino UNO can simulate ? If yes, any reference?
[![Terminal Functions][3]][3]

  [1]: https://github.com/allenchak/LM6023/blob/master/Datasheet/SP-MCU-20110107-01_LM6023A-Manual-Rev0.3.pdf
  [2]: https://github.com/allenchak/LM6023
  [3]: https://i.stack.imgur.com/kUQif.png

body:
Unfortunately driving a graphic LCD is not as easy as driving one of the most popular type HD44780 LCD's.
Back to the subject:
If the state on this pin is HIGH then you shall use  Motorola's 6800 interface, when state on C86 is LOW, use Intel's 8080 interface.
Depending on your selection you would have to keep the communication standard. For 8080 interface refer to point 3.3.1 of you datasheet, for 6800 see point 3.3.2.
Note: If you are struggling, try to search for the libraries using controller's name: LM6023A or one of the S1D15300 or S1D16700
Also, consider number of pins available on your Arduino. It may be that you can drive this LCD with Arduino Uno using serial interface only. (See this [link][1])

  [1]: https://electronics.stackexchange.com/questions/84841/which-interface-is-better-for-my-oled-display


message:
Is new without a delete acceptable?

I know it is not a good practice to use the `new` command to dynamically create data, however, if I would never use the `delete`, would it result in memory gaps/other problems?

**Background**

The reason I need to create instances dynamically, is that I want to test my application first on a PC. And I want for several classes to have more properties for the PC version than for the Arduino version (for example, to store names, or information for the PC GUI to display). The PC version classes will be inherited from the Arduino (real) classes, but with added properties.

In some classes I need to build up a list, and I cannot use a type with hardcoded values to fill an array.

Example:

I have a LightSetup class that has a list of Pars (which are LED lights):

    class LightSetup
    {
    protected:
     Par* _pars[NR_OF_PARS];

Par is the Arduino/real version, to fill in these I need:

    LightSetup::LightSetup()
    {
     for (int n = 0; n < NR_OF_PARS; n++)
     {
      _pars[n] = new Par(1 + 8 * n);
     }
    }

In the PC version, instead of new Par, I use new TestPar.
And in the header I cannot define it without a pointer like this:

     Par _pars[NR_OF_PARS];

Otherwise it cannot contain TestPar instances.

body:
Sure. Using `new` or `malloc` to set things up initially is really no different to static allocations. There is nothing inherently bad with using `malloc` or `new`, only in using it repeatedly with `free` or `delete`.

Allocating a block of heap memory and keeping it allocated for the rest of eternity does not cause heap fragmentation. It's only repeated allocation and deallocation of variable sizes (such as `String` causes) that start to create problems. Allocating at the start of your program and leaving it allocated, as long as you don't allocate *too much*, of course, is not a problem.


body:
In the destructor you would need

    LightSetup::~LightSetup()
    {
        for (int n = 0; n < NR_OF_PARS; n++)
        {
            delete _pars[n];
        }
    }

and every time you replace a _pars you need to delete the old one. This can be done automatically by using unique_ptr.

However for your purpose it sounds like a `#if` is better suited to differentiate at compile time which type you actually store inside that array.

    #if ON_ARDUINO
        Par _pars[NR_OF_PARS];
    #else
        TestPar _pars[NR_OF_PARS];
    #endif


message:
Morse Interpreter-Microphone Problem

I am working on a morse interpreter. I can now use light-sensor and a regular key as input device and want to add a mic to the system. I recieve the input convert it to text and show it on nokia 5110 lcd. And also whilst input, an led and a buzzer turns on and off simultaneously. When I use mic the led works just as it should but I do not get any correct input to the lcd. I attached Out and Gnd pins of mic just as I would attach the key and vcc to 5v.

The following is the code which I use

    #define RST 12
    #define CE  11
    #define DC  10
    #define DIN  9
    #define CLK  8

    #include "font.h";

    unsigned long signal_len,t1,t2; //time for which button is pressed
    int inputPin=2; //input pin for push button
    int ledPin=4; //output pin for LED
    String code=""; //string in which one alphabet is stored

    void LcdWriteString(char *characters){
      while(*characters) LcdWriteCharacter(*characters++);
    }

    void LcdWriteCharacter(char character){
    for(int i=0;i<5;i++) LcdWriteData(ASCII[character-0x20][i]);
    LcdWriteData(0x00);
    }
    void LcdWriteData(byte dat)
    {
      digitalWrite(DC, HIGH); //DC pin is low for commands
      digitalWrite(CE, LOW);
      shiftOut(DIN, CLK, MSBFIRST, dat); //transmit serial data
      digitalWrite(CE, HIGH);
    }
    void LcdWriteCmd(byte cmd)
    {
      digitalWrite(DC, LOW); //DC pin is low for commands
      digitalWrite(CE, LOW);
      shiftOut(DIN, CLK, MSBFIRST, cmd); //transmit serial data
      digitalWrite(CE, HIGH);

    }
    void setup()

    {
      Serial.begin(9600);
      pinMode(inputPin, INPUT_PULLUP); //internal pullup resistor is used to simplify the circuit
      pinMode(ledPin,OUTPUT);

        pinMode(RST, OUTPUT);
      pinMode(CE, OUTPUT);
      pinMode(DC, OUTPUT);
      pinMode(DIN, OUTPUT);
      pinMode(CLK, OUTPUT);
      digitalWrite(RST, LOW);
      digitalWrite(RST, HIGH);

      LcdWriteCmd(0x21);  // LCD extended commands
      LcdWriteCmd(0xA9);  // set LCD Vop (contrast)
      LcdWriteCmd(0x04);  // set temp coefficent
      LcdWriteCmd(0x14);  // LCD bias mode 1:40
      LcdWriteCmd(0x20);  // LCD basic commands
      LcdWriteCmd(0x0C);  // LCD normal video

      for(int i=0;i<504;i++)LcdWriteData(0x00);
    }

    void loop()
    {
    NextDotDash:
      while (digitalRead(inputPin) == HIGH) {}
      t1 = millis();                            //time at button press
      digitalWrite(ledPin, HIGH);               //LED on while button pressed
      while (digitalRead(inputPin) == LOW) {}
      t2 = millis();                            //time at button release
      digitalWrite(ledPin, LOW);                //LED off on button release
      signal_len = t2 - t1;                     //time for which button is pressed
      if (signal_len > 50)                      //to account for switch debouncing
      {
        code += readio();                       //function to read dot or dash
      }
      while ((millis() - t2) < 500)           //if time between button press greater than 0.5sec, skip loop and go to next alphabet
      {
        if (digitalRead(inputPin) == LOW)
        {
          goto NextDotDash;
        }
      }
      convertor();                          //function to decipher code into alphabet
    }
    char readio()
    {
      if (signal_len < 150 && signal_len > 20)
      {
        return '.';                        //if button press less than 0.6sec, it is a dot
      }
      else if (signal_len > 150)
      {
        return '-';                        //if button press more than 0.6sec, it is a dash
      }
    }
    void convertor()
    {
      static String letters[] = {".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-",
                                 ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", "E"
                                };
      int i = 0;
      if (code == ".-.-.-")
      {
        Serial.print(".");        //for break
        LcdWriteCharacter(".");
      }
      else
      {
        while (letters[i] != "E")  //loop for comparing input code with letters array
        {
          if (letters[i] == code)
          {
            Serial.print(char('A' + i));
            LcdWriteCharacter(char('A' + i));
            break;
          }
          i++;
        }
        if (letters[i] == "E")
        {
          Serial.println("");  //if input code doesn't match any letter, error
          LcdWriteCharacter("");
        }
      }
      code = "";                            //reset code to blank string
    }

body:
> I attached Out and Gnd pins of mic just as I would attach the key and
> vcc to 5v.

This can't work. Unlike the key, the microphone is an analog device that
will output a continuously varying analog signal. If you expose it to a
pure tone it will output a sine wave. If you sing a note in front of it,
it will pick not only the sine but also a lot of harmonics. In any case,
it will also pick the ambient noise.

What you need to do is somehow determine the amplitude of the sound
signal, then compare that to some threshold in order to decide whether
the amplitude is high enough to be considered “on”. You could use a
diode-based peak detector and a comparator. Doing all this in code is
kind of tricky. You may want to take a look at this [sound-level meter
sketch][sound-meter], but note that a software peak detection could be
simpler than the true-RMS intensity detection implemented in that
sketch.

[sound-meter]: https://gist.github.com/edgar-bonet/e693799f58a545ca89a2


message:
I want my arduino mega to read from all 4 serial ports at the same time, running sequentially through each one

I currently have the code running through Serial1, which works exactly as I want it to:

    int RFIDResetPin = 13;

    void setup()
    {
      Serial.begin(9600);
      Serial1.begin(9600);
      Serial2.begin(9600);
      pinMode(RFIDResetPin, OUTPUT);
      digitalWrite(RFIDResetPin, HIGH);
      Serial.println("Arduino is ready");
    }

    void loop(){

      char tagString1[13];
      int index = 0;
      boolean reading1 = false;
      ///////////////////////////////////////
      //this reads from the reader installed
      //on serial1, which is pin 19
      //////////////////////////////////////
      while (Serial1.available() > 0) {

        int readByte1 = Serial1.read(); //read next available byte

        if (readByte1 == 2) reading1 = true;
        if (readByte1 == 3) reading1 = false;

        if (reading1 && readByte1 != 2 && readByte1 != 10 && readByte1 != 13) {
          tagString1[index] = readByte1;
          index++;
        }
      }
      Serial.print("Reader 1: "); //read out any unknown tag
      Serial.println(tagString1);

      clearTag(tagString1); //Clear the char of all value
      resetReader(); //reset the RFID reader
    }

    void resetReader() {
      ///////////////////////////////////
      //Reset the RFID reader to read again.
      ///////////////////////////////////
      digitalWrite(RFIDResetPin, LOW);
      digitalWrite(RFIDResetPin, HIGH);
      delay(150);
    }

    void clearTag(char one[]) {
      ///////////////////////////////////
      //clear the char array by filling with null – ASCII 0
      //Will think same tag has been read otherwise
      ///////////////////////////////////
      for (int i = 0; i < strlen(one); i++) {
        one[i] = 0;
      }
    }

However, I want to add serial0, 2, and 3 as well. there are 2 main questions I have
1) is it possible to have copy paste this section of the code:

        while (Serial1.available() > 0) {

        int readByte1 = Serial1.read(); //read next available byte

        if (readByte1 == 2) reading1 = true;
        if (readByte1 == 3) reading1 = false;

        if (reading1 && readByte1 != 2 && readByte1 != 10 && readByte1 != 13) {
          tagString1[index] = readByte1;
          index++;
        }
      }
      Serial.print("Reader 1: "); //read out any unknown tag
      Serial.println(tagString1);

      clearTag(tagString1); //Clear the char of all value
      resetReader(); //reset the RFID reader
    }

while changing some of the variable names to connect the other serial ports? I saw something [here](https://forum.arduino.cc/index.php?topic=472055.0), but don't know how to implement it, or if it even would work for me.

and
2) since I am routing the incoming data through serial0, Is it possible to have this code working on it as well?

body:
The Arduino already reads from the 4 serial ports at the same time. Or
at least as close to “at the same time” as possible with a single CPU:
every time a byte is received at one port, an interrupt is triggered
that reads the byte from the UART and puts it into a buffer. You can
then get it from the buffer using `Serial.read()`.

What you now have to do is move the bytes from these buffers (which
belong to the Arduino hardware serial library) into you own buffers for
further processing. You can do this by checking the ports sequentially
and processing each one in turn. Everything will be fine as long as you
do not have blocking code in there. If you do block, then you run the
risk of having one of the library buffers overflow. The code you posted
is non-blocking, so you are fine.

> is it possible to have copy paste

You should avoid programming by copy-and-paste. It's not that it won't
work (it will), but you would be creating a maintenance nightmare.
Instead, put the code you would want to copy-paste into a function, and
call that function as many times as required. For example:

<!-- language-all: lang-c++ -->

    void handlePort(Stream &port, const char *readerName, char *tagString)
    {
        boolean reading1 = false;
        while (port.available() > 0) {
            int readByte1 = port.read(); //read next available byte

            if (readByte1 == 2) reading1 = true;
            if (readByte1 == 3) reading1 = false;
            if (reading1 && readByte1 != 2 && readByte1 != 10 && readByte1 != 13) {
                tagString[index] = readByte1;
                index++;
            }
        }
        Serial.print(readerName); //read out any unknown tag
        Serial.print(": ");
        Serial.println(tagString);

        clearTag(tagString); //Clear the char of all value
        resetReader(); //reset the RFID reader
        }
    }

And you call it in `loop()`:

    handlePort(Serial1, "Reader 1", tagString1);
    handlePort(Serial2, "Reader 2", tagString2);
    ...


message:
Is code in a class repeated for each instance?

I haven't needed classes before in programming for Arduino, but I now have a good use case. I'm not sure I grasp how this will affect code space, though.

Currently I have a struct that holds the properties of an object, and common code that iterates over an array of 12 of that struct. It's fairly compact.

It would be cleaner to wrap the operations on the struct in a class and act on an array of 12 of that class. Essentially the current struct would become private data of the class.

Will all the code in the class be repeated in each instance, or is the compiler clever enough to avoid such repetition?

Any clarifications welcome. C++ is not my main language.

body:
No, the code is not repeated for each instance. Instance methods are like functions. There is only one copy of the code.

There's a dispatch table that maps method calls to their implementations. (Actually, that's standard C++. I don't know for sure how it's implemented in the Arduino C++ compiler)


body:
No, it is not repeated. Unless you are using templates, each method of
each class is stored only once in the compiled program. Or even not
stored at all if the optimizer notices it is not used.

Just to demystify the classes a bit, you can consider them as a kind of
“syntactic sugar” over an “object oriented” programming pattern. The
following C++ code:

<!-- language: lang-c++ -->

    class MyClass {
    public:
        int aMember;
        long anotherMember;
        int aMethod(short);
    };

    int MyClass::aMethod(short theParameter)
    {
        return aMember + theParameter;
    }

    void some_function()
    {
        MyClass objects[2];
        objects[1].aMethod(42);
    }

is interpreted by the compiler as being roughly equivalent to this C
code:

<!-- language: lang-c -->

    typedef struct {
        int aMember;
        long anotherMember;
    } MyClass;

    int MyClass_aMethod(MyClass *this, short theParameter)
    {
        return this->aMember + theParameter;
    }

    void some_function()
    {
        MyClass objects[2];
        MyClass_aMethod(&objects[1], 42);
    }

Can you spot the differences and the similarities?


message:
AnalogWrite problem

I have connected DRV8835 with 2 DC motors with 11 power supply. Arduino nano.

When I for loop like i from 0 to 1024 for analogWrite(i,Motor1) for the DC Motor1 it's accelerating from 0 to 200 and it's stopping. When I becomes 250 it's starting at higher speed. When it becomes 500 it's stopping again. And 550 we have our power again.

Now I tried to run analogWrite(1000, ***) but it's not working. When I change the value from 1000 to 1005 it's not working again. But at 1024 we have the maximum speed and it is working?
<!-- language-all: lang-cpp -->

     #define LEFT_PWM 9
     #define RIGHT_PWM 10
     #define LEFT_DIR 5
     #define RIGHT_DIR 6

    void setup() {
      pinMode(5, OUTPUT);
      pinMode(6, OUTPUT);
    }

    void loop() {
      digitalWrite(LEFT_DIR, HIGH);
      analogWrite(LEFT_PWM, 1000);
    }

body:
`analogWrite` has the following prototype

    void analogWrite(uint8_t, int);

which means that its first parameter has `[0, 256)` range and follows the rules of modulo arithmetic, with `256` as the modulo. If you supply arguments outside of `[0, 256)` range, they will be interpreted `% 256`. `1000` is the same as `232` (`1000 % 256 == 232`), `500` is the same as `244`, `550` is the same as `38` and so on.

This is not fully consistent with the symptoms you describe (if your description is accurate), which might imply that something else is a factor here. Are sure you are using your DRV8835 in `PHASE/ENABLE` mode (pin 11 pulled high)?


message:
NRF24L01+ (TMRH20 library): Receiver gets blank data

I am working on sample Arduino project for communication over NRF24L01+ (TMRH20 library), everything is working fine with my example except one issue my Receiver gets message but that message is blank. Now i am not sure how do i debug as per serial monitor data is getting transmitted, as per receiver serial monitor it receives data but its blank.

Transmitter code -
<!-- language-all: lang-cpp -->

    // SimpleTx - the master or the transmitter

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

    #define CE_PIN   9
    #define CSN_PIN 10

    const byte slaveAddress[5] = {'R','x','A','A','A'};

    RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

    char dataToSend[12] = "Msg AKSHAY";
    //int dataToSend = 1;
    char txNum = '0';

    unsigned long currentMillis;
    unsigned long prevMillis;
    unsigned long txIntervalMillis = 1000; // send once per second

    void setup() {

        Serial.begin(9600);

        Serial.println("SimpleTx Starting");

        radio.begin();
        radio.setDataRate( RF24_250KBPS );
        radio.setRetries(3,5); // delay, count
        radio.openWritingPipe(slaveAddress);
    }

    //====================

    void loop() {
        currentMillis = millis();
        if (currentMillis - prevMillis >= txIntervalMillis) {
            send();
            prevMillis = millis();
        }
    }

    //====================

    void send() {

        bool rslt;
        rslt = radio.write( &dataToSend, sizeof(dataToSend) );
            // Always use sizeof() as it gives the size as the number of bytes.
            // For example if dataToSend was an int sizeof() would correctly return 2

        Serial.print("Data Sent ");
        Serial.print(dataToSend);
        if (rslt) {
            Serial.println("  Acknowledge received");
            updateMessage();
        }
        else {
            Serial.println("  Tx failed");
        }
    }

    //================

    void updateMessage() {
            // so you can see that new data is being sent
        txNum += 1;
        if (txNum > '9') {
            txNum = '0';
        }
        dataToSend[10] = txNum;
    }

Receiver code -

    // SimpleRx - the slave or the receiver

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

    #define CE_PIN   9
    #define CSN_PIN 10

    const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

    RF24 radio(CE_PIN, CSN_PIN);

    char dataReceived[10]; // this must match dataToSend in the TX
    bool newData = false;

    //===========

    void setup() {

        Serial.begin(9600);

        Serial.println("SimpleRx Starting");
        radio.begin();
        radio.setDataRate( RF24_250KBPS );
        radio.openReadingPipe(1, thisSlaveAddress);
        radio.startListening();
    }

    //=============

    void loop() {
        getData();
        showData();
    }

    //==============

    void getData() {
      if ( radio.available() ) {

           radio.read( &dataReceived, sizeof(dataReceived) );
          Serial.println(dataReceived);
           newData = true;
       } else {
           Serial.println("No radio available");
       }
       delay(100);
    }

    void showData() {
        if (newData == true) {
            Serial.print("Data received ");
            Serial.println(dataReceived);
            newData = false;
        }
    }

Below is the output TX1 (Transmitter ) and RX1 is Receiver. You can see that Transmitter even gets acknowledgment also..

[![enter image description here][1]][1]

Both of my devices are arduino nano and below is wiring diagram between arduino and nrf24l01.
[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/723hy.png
  [2]: https://i.stack.imgur.com/GisSt.png

I also saw few post where people suggested using 100uf capacitor in NRF24L01 (GND & VCC), this helped me with accuracy in connection but data is still missing.

body:
I have tested your code. There appears to be defective clones of the nRF24L01 around that exhibit an issue I show in post https://arduino.stackexchange.com/questions/85874/nrf24l01-continuously-reading-closed-pipe
You can work around this issue by changing your code as follows (although your process still has to read all those nulls):
```
void getData() {
  uint8_t pipeNum;
  if ( radio.available(&pipeNum) ) {

       radio.read( &dataReceived, sizeof(dataReceived) );
      //Serial.println(dataReceived);
      if (pipeNum < 2) {
       newData = true;
      }
   } else {
       Serial.println("No radio available");
   }
   // delay(100);
}
```


message:
How can I tell which fuses are set on an ATtiny?

Following on from this question, https://arduino.stackexchange.com/questions/24502/problem-with-programming-an-attiny85-error-avrdude-yikes-invalid-device-sig,
if the response from `avrdude` is `0x000000` then the internal oscillator is probably not being used and an external one (be that crystal or clock signal) is required.

However, as this menu, from [Engbedded Atmel AVR® Fuse Calculator][1], shows, there are a *lot* of options:

[![ATtiny85 oscillator selection][2]][2]

So, instead of having to configure circuits for *each* of the options, in turn, until the ATtiny responds, is there any way that I can read which of the `CKSEL` and `SUT` fuses are set?1

---

### Background

I am using a Nano/Uno as an ISP programmer, and the ATtiny is on a dev board like this (although it would be the same issue if I were to use a breadboard):

[![ATtiny development board][3]][3]

I know for sure that the connections are fine as I have checked them from pin to pin of the two ICs (ATmega328PU to ATtiny85), using a DMM.

 I am receiving `0x000000` as in:

         avrdude: Device signature = 0x000000
         avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

because the ISP programmer can't read the ATtiny, because an external clock source has been set via the fuses. However, I wish to know how to read *which* clock source has been specified, without having to manually try *all* of the circuit permutations.

I don't think that just connecting a crystal (and two ceramic capacitors) will work if the exact setting, i.e. external clock, has been selected. However, if a 16MHz crystal works for all, or any, of the external clock settings then that would be great, but I'm sure it doesn't work like that, as you can have a crystal attached but the it might not be used, see [Does device signature 0x000000 mean the atmega is bad](https://www.avrfreaks.net/forum/does-device-signature-0x000000-mean-atmega-bad):

> Even though you have a crystal connected, that does not mean it is oscillating. For example, IF you set fuses for "External Oscillator", that will turn the crystal oscillator off.

When I move the ATtiny85 to a breadboard and add a crystal (16 MHz) and two 22 pF capacitors, the error has changed for the better (at least now it sees that a ATtiny is connected)

    avrdude: Device signature = 0xff0000
    avrdude: Expected signature for ATtiny85 is 1E 93 0B
             Double check chip, or use -F to override this check.

Interestingly the signature varies:

 - `0xff0000`
 - `0x00ffff`
 - `0xff00ff`

When I add an external power supply to the ATtiny on the breadboard, following advice from [Atmega (any chip) Device Signature issues and stk500_getsync()(resolutions)][4], then unfortunately the device signature in the response returned by `avrdude` reverts back to `0x000000`

         avrdude: Device signature = 0x000000
         avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

[![ATtiny85 on breadboard and Nano as ISP][5]][5]

---

1 This is, admittedly, a bit chicken-and-egg, as if I can't communicate with the ATtiny, due to the incorrect clock setting, then how can I read which fuses have been set..?
 It's a bit like saying "If I don't have petrol in my car, then how can I drive to the petrol station to fill up?" - but I was hoping that there might be some sort of time saving measure

  [1]: http://www.engbedded.com/fusecalc/
  [2]: https://i.stack.imgur.com/xZka6.png "ATtiny85 oscillator selection"
  [3]: https://i.stack.imgur.com/tyPdr.png "ATtiny development board"
  [4]: https://forum.arduino.cc/index.php/topic,51819.0.html?utm_source=rb-community&utm_medium=forum&utm_campaign=device-signature-0x000000-while-burning-bootloader
  [5]: https://i.stack.imgur.com/r7TtT.jpg "ATtiny85 on breadboard and Nano as ISP"

body:
You need a Programmer that connects to the ISP pins

http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf

The programmer will hold Reset low, then communicate via the SCK/MOSI/MISO pins to read/update the fuses, read/program memory, and optionally read/program the EEPROM.

Section 20.2 discusses the 3 fuse bytes.

I use an older Atmel AVR-ISP MKii. Atmel stopped making them, there seem to be plenty of replacement choices available, and Atmel Studio 7 when I struggle with Atmega328P, '1284P, and 2560. I haven't used an Attiny in a project yet.

https://www.microchip.com/mplab/avr-support/atmel-studio-7


body:
This seems to be an X -> Y problem, with X being the missing clock source on your ATTiny, which prevents communication.

If you have a second Uno or other AVR device, you can use that to generate a clock signal on any of the digital pins:

    void setup() {
      DDRB = 0b00100000;
    }

    void loop() {
      PINB = 0b00100000;
    }
This creates a square(~ish) signal on Pin 13 with a frequency of 1.6 MHz.
Depending on the IDEs optimization level (platform.txt), a frequency of 4 MHz is also achievable (at `-O3` instead of `-Os`).

Connecting this to the `XTAL1` pin of your ATTiny85 should allow you to communicate with the board.
Make sure to interconnect all grounds.


message:
Arduino will not read three successive packets in the serial connection

I have written a small program to send serial commands from Python to the Arduino Micro.  This is my code for both:

Python

    import serial

    ser = serial.Serial('COM5', 9600)

    ser.write(b'0')
    ser.write(b'1')
    # ser.write(b'2')

    print('done')

Arduino

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

    void loop()
    {

      while (!Serial.available()){}
      Serial.println(Serial.read()-48);

    }

If I keep the `ser.write(b'2')` line in the Python code commented out, the code executes nearly instantly, and I am able to see both transmissions in the serial monitor. If I uncomment it, the Python code takes about 5-7 seconds to execute, and none of the data comes through the serial monitor.

I've tried different baud rates but that hasn't helped. I've also tried sending an integer rather than `b'#'`, and the same thing happens, no data is transmitted if I have all three serial commands active.

What is happening in my code? Is the serial buffer overloaded by the three successive writes and the buffer ends up flushing?

body:
The problem is that your code works but you substract 48 from what you received.
<br>Which if python sends a ``char`` with values: ``'0'`` ``'1'`` ``'2'`` it will result in the serially outputted values of ``NUL`` ``SOH`` ``STX`` which are invisible.

If python transmits the raw byte value (aka ``0x00`` ``0x01`` ``0x02``) this would result in ``0x00 - 48 = undefined behaviour`` with a underflow (same goes for ``0x01`` and ``0x02``)


message:
What is wrong with my code? RGB potentiometer

Arduino programming has been a huge learning curve for me and I am trying to create a project with an rgb that's color is determined by a potentiometer. To where the further I turn it, the further across the rainbow spectrum it goes. I can't figure out how to do all values in between because I am not educated enough but I came up with this basic code...
```
int redpin = 6;
int greenpin = 3;
int bluepin = 5;
int potPin = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(redpin, OUTPUT);
  pinMode(bluepin, OUTPUT);
  pinMode(greenpin, OUTPUT);
  pinMode(potPin, INPUT);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  int wavecolor = analogRead(potPin);
  Serial.print(wavecolor);
  {
    if (wavecolor = 0) {
      setColor(255, 0, 0);  // red
    }
    if (wavecolor > 0 or wavecolor < 333) {
      setColor(0, 255, 0);  // green
    }
    if (wavecolor > 333 or wavecolor < 667) {
      setColor(0, 0, 255);  // blue
    }
    if (wavecolor > 667 or wavecolor < 1022) {
      setColor(255, 255, 0);  // yellow
    }
    if (wavecolor = 1023) {
      setColor(80, 0, 80);  // purple
    }
  }
}

void setColor(int red, int green, int blue)
{
#ifdef COMMON_ANODE
  red = 255 - red;
  green = 255 - green;
  blue = 255 - blue;
#endif
  analogWrite(redpin, red);
  analogWrite(greenpin, green);
  analogWrite(bluepin, blue);
}
```

And for some reason, where the light should change colors once the potentiometer goes past a certain number, the light just flickers and only changes colors to white when it is all the way up or down. Also, it has a weird flickery yellow color.
Since I am new to this, can one of you better educated people be willing to assist me?

body:
* Equality comparison in C and C++ is expressed by `==` operator. `==`, not `=`. This

        if (wavecolor = 0) {

 actually *assigns* zero to your `wavecolor` variable, thus destroying the value you just read.

* The common sense says that you actually need `and` in your conditions, not `or`

        if (wavecolor > 0 and wavecolor < 333) {

 The `or` conditions that you curently use are simply *always true*, which makes them nonsensical.

* This is valid syntax

        wavecolor > 0 or wavecolor < 333
        wavecolor > 0 and wavecolor < 333

 but you might want to try using more "canonical" forms

        wavecolor > 0 || wavecolor < 333
        wavecolor > 0 && wavecolor < 333

 `or` and `and` are "alternative" forms of `||` and `&&` operators, introduced a long time ago for reasons that are all but obsolete today.

* Assuming that you meant `and` instead of `or`, in your conditions you managed to "exclude" such values as `333`, `667` and `1022` - they wouldn't match any of `and` conditions. Changing some strict comparisons to non-strict ones might be in order.

* As a side note, in a single-file program all file-scope variables should be either `const` or `static`. In your case

        const int redpin = 6;
        const int greenpin = 3;
        const int bluepin = 5;
        const int potPin = 0;


body:
Try this code below. This will give you the desired output!

    int redpin = 6;
    int greenpin = 3;
    int bluepin = 5;
    int potPin = 0;

    void setup() {
      // put your setup code here, to run once:
      pinMode(redpin, OUTPUT);
      pinMode(bluepin, OUTPUT);
      pinMode(greenpin, OUTPUT);
      pinMode(potPin, INPUT);
      Serial.begin(9600);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      int wavecolor = analogRead(potPin);
      Serial.print(wavecolor);
      {
        if (wavecolor == 0) {
          setColor(255, 0, 0);  // red
        }
        else if (wavecolor > 0 && wavecolor < 333) {
          setColor(0, 255, 0);  // green
        }
        else if (wavecolor >= 333 && wavecolor < 667) {
          setColor(0, 0, 255);  // blue
        }
        else if (wavecolor >= 667 && wavecolor < 1022) {
          setColor(255, 255, 0);  // yellow
        }
        else if (wavecolor >= 1022) {
          setColor(80, 0, 80);  // purple
        }
      }
    }

    void setColor(int red, int green, int blue)
    {
    #ifdef COMMON_ANODE
      red = 255 - red;
      green = 255 - green;
      blue = 255 - blue;
    #endif
      analogWrite(redpin, red);
      analogWrite(greenpin, green);
      analogWrite(bluepin, blue);
    }

Read up on logical and relational operators in Arduino (`||`, `&&`, `>`, `<`, `==`, `>=`, `<=`) etc.
<br> I will leave the logic development to you as it is what develops your coding ability and trust me logic is the most important and fun part of writing a code!


message:
Why does a variable size struct not compile in the Arduino IDE?

This sketch does not compile in the Arduino IDE

    void setup() {
      // put your setup code here, to run once:

    }

    struct test {
      int i;
      char variable[];
    };

    typedef struct test test;

    test t = {
      0, "hi"
    };

    void loop() {
      // put your main code here, to run repeatedly:

    }

Arduino throws

    sketch_may09a:16: error: initializer-string for array of chars is too long [-fpermissive]

     };

     ^

    exit status 1
    initializer-string for array of chars is too long [-fpermissive]

However compiling with g++ works just fine. How can I fix it? Or is there a principle reason why flexible array members are not supported?

body:
Maybe you've compiled it in g++ without any warnings enabled (or maybe it yeld warnings but was compiled). The arduino uses flags to consider all warnings as an error, so it won't compile. It may wary for different platforms, I've got -fpermissive used (and I don't like it at all).

That's because size of struct must be known compile time and if you provide `char variable[];` you'll get zero sized array. Therefore anything biiger than nothing you'll try to initialize for is too long.

Maybe you're looking for something like this:

    struct test {
      int a;
      const char * ptr;
    };

    test paramx {1, "some string"};
    test paramy {2, "another string"};

    test array[] = {{3,"three"}, {4, "four"}, {5,"five"}};


body:
*Flexible array member* is a C feature. It does not exist in C++. On top of that, the way you use it to declare and initialize a static struct of flexible size is non-standard even for C.

**However**, GNU-C language supports it as an extension. Also, newer versions of GCC (6 and higher) allow this in GNU-C++ code as an extension as well. But GCC 5.4.0 used by Arduino IDE doesn't support this non-standard feature in C++ code.

If you flip through different GCC versions on Godbolt (https://godbolt.org/z/Iul7hD) you'll see that support for this feature has always been present in C code, but for C++ code it first appeared in GCC 6.

This is why you were able to compile it with your standalone `g++` compiler (which is apparently a much later version), but were unable to compile it in Arduino IDE.

It means that if you really want this non-standard code to compile in the current version of Arduino IDE, you have to place it into a `.c` file. Or just specify the array size explicitly.


message:
How to use PROGMEM in a .h/.cpp file instead of a .ino file?

I want to use a lot of `.h`/`.cpp` files to be used by my `ino` sketch.
In one of these .cpp files (and later more) I want to use constant arrays (like lookup tables). To save SRAM I want to use `PROGMEM`.

What worked before in the Ino sketch is:

    const uint8_t _red[]   PROGMEM = { 0, 9, 10, 220, 230, 240, 255 };

But when I put the line above in a `.h` or `.cpp` file I get the error:

    Par.h:13:25: error: expected initializer before 'PROGMEM'

Should I include something or can't I use `PROGMEM` in a `.h`/`.cpp` file?

body:
I already found the answer.

Include:

    #include <avr/pgmspace.h>

**Update**

See also remark of AnT, which is a more generic (and in most cases better solution):

    #include "Arduino.h"

(just to help others with the same problem).


message:
Cannot connect through /dev/ttyACM0 (Ubuntu 18.04)

I am using an Arduino UNO which worked fine until today. My system: Ubuntu 18.04

Now, the IDE can no longer connect to it:

 - Cannot do any sketch upload
 - Cannot ask for board info
 - No USB ports shown in tools --> port (only 2 serial ports shown)
 - `ttyyACM0` not showing up in `/dev`

However, both `lsusb` and `dmesg` show that the board is recognized somehow.

`lsusb` output:

`Bus 001 Device 012: ID 03eb:2fef Atmel Corp.`

`dmesg` output:

    [ 2922.171042] usb 1-1.3: new full-speed USB device number 12 using ehci-pci
    [ 2922.282047] usb 1-1.3: New USB device found, idVendor=03eb, idProduct=2fef
    [ 2922.282052] usb 1-1.3: New USB device strings: Mfr=0, Product=1, SerialNumber=0

The problem is the same on 2 different computers, which leads me to suspect that there is something wrong with the board. Is it possible that a board be shown by both `dmesg` and `lsusb` and still be malfunctioning ?

body:
The board was bad. I just replaced it and it now works.

So, to answer my own question, an Arduino board can show up on `lsusb` and `dmesg` and yet be faulty. This is what the `dmesg` output is for a healthy board:

    [10492.388028] usb 1-1.4: new full-speed USB device number 13 using ehci-pci
    [10492.500520] usb 1-1.4: New USB device found, idVendor=2341, idProduct=0043
    [10492.500526] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=220
    [10492.500529] usb 1-1.4: Manufacturer: Arduino (www.arduino.cc)
    [10492.500533] usb 1-1.4: SerialNumber: 55736323739351010292
    [10492.520354] cdc_acm 1-1.4:1.0: ttyACM0: USB ACM device
    [10492.520832] usbcore: registered new interface driver cdc_acm
    [10492.520835] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters

And here is the `lsusb` output:

    Bus 001 Device 013: ID 2341:0043 Arduino SA Uno R3 (CDC ACM)

Judging on the difference with the previous outputs from both commands (when the faulty board was connected), it seems that my board had reverted to the basic Atmel USB interface and that the Arduino specific USB handshake was not working. Can anyone confirm ?


message:
NRF24L01+ Getting Started Acknowledge Failed

I have followed numerous guides and tutorials for getting the NRF24L01+ modules working with an Arduino Uno. I have swapped to a genuine Arduino and tried 4 different NRF modules. All without luck.

I am trying to get the most basic example from [Simple nRF24L01+ 2.4GHz transceiver demo][1] to work.

Hardware Connections:
[![Hardware Connections][2]][2]

Simple TX Test Code:

    // SimpleTx - the master or the transmitter

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

    #define CE_PIN   9
    #define CSN_PIN 10

    const byte slaveAddress[5] = {'R','x','A','A','A'};

    RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

    char dataToSend[10] = "Message 0";
    char txNum = '0';

    unsigned long currentMillis;
    unsigned long prevMillis;
    unsigned long txIntervalMillis = 1000; // send once per second

    void setup() {

        Serial.begin(9600);

        Serial.println("SimpleTx Starting");

        radio.begin();
        radio.setDataRate( RF24_250KBPS );
        radio.setRetries(3,5); // delay, count
        radio.openWritingPipe(slaveAddress);
    }

    //====================

    void loop() {
        currentMillis = millis();
        if (currentMillis - prevMillis >= txIntervalMillis) {
            send();
            prevMillis = millis();
        }
    }

    //====================

    void send() {

        bool rslt;
        radio.stopListening();
        rslt = radio.write( &dataToSend, sizeof(dataToSend) );
            // Always use sizeof() as it gives the size as the number of bytes.
            // For example if dataToSend was an int sizeof() would correctly return 2

        Serial.print("Data Sent ");
        Serial.print(dataToSend);

        if (rslt) {
            Serial.println("  Acknowledge received");
            updateMessage();
        }
        else {
            Serial.println("  Tx failed");
        }
    }

    //================

    void updateMessage() {
            // so you can see that new data is being sent
        txNum += 1;
        if (txNum > '9') {
            txNum = '0';
        }
        dataToSend[8] = txNum;
    }

Serial monitor:

[![enter image description here][3]][3]

Using `radio.printDetails( );` returns:

[![enter image description here][4]][4]

Please let me know what I'm missing.

  [1]: https://forum.arduino.cc/index.php?topic=421081.0
  [2]: https://i.stack.imgur.com/6nt1C.png
  [3]: https://i.stack.imgur.com/iAvZ8.png
  [4]: https://i.stack.imgur.com/JT2Oj.png

body:
The Arduinos 3V3 does not privide enough current. To eliminate this as a source of your problem you can use a ceramic capacitor of 100µF across VCC and GND pins of the nRF24L01+ module or buy a [5V to 3V3 step down converter specially made for nRF24L01][1].

  [1]: https://www.aliexpress.com/item/New-Socket-Adapter-plate-Board-for-8Pin-NRF24L01-Wireless-Transceive-module-51/32825890092.html


message:
Proteus - How to Debug Invalid Opcode?

While running a program compiled in the Arduino IDE 1.8.5 and then using the `.ELF` file inside *LabCenter Proteus 8.0*, for an *Arduino Nano* *ATMEL Mega 328P*, for a code involving the use of the `SoftwareSerial.h` Library, hence involving several loops, without user interaction, I am getting the following error:

    Invalid opcode 0x0024 at PC=0x0096

Now I am completely lost. According the [AVR Instruction Set Manual][1] such opcode should (not sure about this?) be *RETI - Return From Interrupt* at the Program Line (?) no.150 = 0x096. The full code has 779 lines plus several library calls, and the line 150 happens to fall just before the `loop()` function (?), which should never repeat, being just a declaration.

So, how should I debug this error? Evidently I am not asking to solve the problem for me but, how should I proceed for debugging it and find the real error?

I have been unable to find in Proteus a tool for "Debug Stop if Error"

I have been unable to isolate the error in a simple way to share. It should be related someway with interruptions used by the library `SoftwareSerial.h`, because at some modifications of the program, the code freezes at an interruption return. I am working on that, but advancing really slowly actually.

[![enter image description here][2]][2]
[![enter image description here][3]][3]
[![enter image description here][4]][4]
[![enter image description here][5]][5]

Related question [No.1][6].

  [1]: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-0856-AVR-Instruction-Set-Manual.pdf
  [2]: https://i.stack.imgur.com/Ctx6N.png
  [3]: https://i.stack.imgur.com/UeXmh.png
  [4]: https://i.stack.imgur.com/Fowci.png
  [5]: https://i.stack.imgur.com/Y0b0g.png
  [6]: https://electronics.stackexchange.com/questions/65271/how-to-get-rid-of-invalid-opcode-0x002a-at-pc-0x004-in-isis-proteus

body:
First: Use the ino.hex file instead of the  .ELF file
Second: this error is showing because you are compiling your code with a different board. Make sure you are using the correct board over at the Arduino IDE. My advice is: switch your board to Arduino Uno both in proteus and over at the Arduino IDE and see if it works. Later on, you can try different boards.


body: Guys if you are facing the error of invalid opcode 0xffff at pc = 0x3e402 in proteus using Arduino, the GO to Arduino IDE software, and from the top menu, click on 'tool' and change the board type, e.g., Arduino UNO to Arduino Mega 2560.


message:
Project wont compile when I place functions below function calls

I use VSCode, not the Arduino IDE. I saw and tried to use a lot of code snippets which are provided for Arduino projects...

So when I copy/paste these examples into my VSCode and try to compile it fails. (I won't believe that people offer non-working examples.)

When I place the functions above the function calls it compiles.

Is this normal behavior or do I have to add some settings to get this working as provided?

**Fails in VSCode** (works in Arduino IDE):

    #include "Arduino.h"
    void setup() {
    }
    int zero = 0;

    void loop() {
      zero = myfunction();
    }

    int myfunction(){
      return 0;
    }

**Works in VSCode** (Works in Arduino IDE):

    #include "Arduino.h"

    void setup() {
    }
    int zero = 0;

    int myfunction(){
      return 0;
    }

    void loop() {
      zero = myfunction();
    }

body:
You need to declare your function before you use it.  So either the whole function body needs to be before the usage, or you must add a [function prototype][1] declaration.

    void myfunction();

    myfunction();

    void myfunction(){
      return 0;
    }

  [1]: http://www.cplusplus.com/articles/yAqpX9L8/


body:
Just make the the abstract method declaration before writing your code after the header files.

    #include<Arduino.h>
    void myfunction();
    void setup();
    void loop();

After this you write your code in any order


message:
The Ultrasonic sensor just detects the same distance

int tPin = 11;
    int ePin = 12;
    long duration, inches, cm;

    void setup()
    {
        Serial.begin(9600);
        pinMode(tPin, OUTPUT);
        pinMode(ePin, INPUT);
        pinMode(2, OUTPUT);
    }

    void loop()
    {
        digitalWrite(tPin, LOW);
        delayMicroseconds(5);
        digitalWrite(tPin, HIGH);
        delayMicroseconds(10);
        digitalWrite(tPin, LOW);
        duration = pulseIn(ePin, HIGH);
        cm = (duration / 2) / 29.1;
        inches = (duration / 2) / 74;
        Serial.print(inches);
        Serial.print("in, ");
        Serial.print(cm);
        Serial.print("cm");
        Serial.println();
        delay(100);

        if (inches <= 10) {
            digitalWrite(2, HIGH);
            delay(50);
            digitalWrite(2, LOW);
            delay(50);
        }
        else {
            digitalWrite(2, HIGH);
            delay(500);
            digitalWrite(2, LOW);
            delay(500);
        }
    }

The serial print displays the same distance that it first detects. How can I fix this?

body:
 First of all you need to make cm, inches and duration float to be more precise. Second, you need to make the delay 2 and 10 microseconds between triggers. Overall, if I'm not wrong you can use the code below without changing your circuit.

    int tPin = 11;
    int ePin = 12;
    float duration, inches, cm; //floating numbers to make the result more precise

    void setup()
    {
        Serial.begin(9600);
        pinMode(tPin, OUTPUT);
        pinMode(ePin, INPUT);
        pinMode(2, OUTPUT);
    }

    void loop()
    {
        digitalWrite(tPin, LOW);
        delayMicroseconds(2);         //Delay 2 microseconds
        digitalWrite(tPin, HIGH);
        delayMicroseconds(10);        //Delay 10 microseconds
        digitalWrite(tPin, LOW);
        duration = pulseIn(ePin, HIGH);
        cm = duration / 58.2;          //Instead of duration/2/28.1
        inches = cm / 2.54;            //You can use cm that was created before for conversion
        Serial.print(inches);
        Serial.print("in, ");
        Serial.print(cm);
        Serial.print("cm");
        Serial.println();
        delay(100);

        if (inches <= 10) {
            digitalWrite(2, HIGH);
            delay(50);
            digitalWrite(2, LOW);
            delay(50);
        }
        else {
            digitalWrite(2, HIGH);
            delay(500);
            digitalWrite(2, LOW);
            delay(500);
        }
    }


message:
Battery charger board with status interface

There are of course a lot of different battery charging boards, which can be used with the Arduino, most being TP4056 based. There are also a few battery charged boards with an on-board display showing the charge status and there are of course also a lot of programmable battery charger controllers (ICs) with status and control interfaces.

But is there any board available, not just the 'raw' IC, using a charging controller with a status interface, which allows access to the status interface from pins on the board? I can't seem to find anything.

For a battery powered Arduino project I am planning, it could at least be very convenient if I could query the battery charging status from software.

body:
I know it's been asked quite long time ago, but still.  This is how would have I done the same, with the existing TP4056:

1) use an electric key in a form of mosfet transistor, controlled by digital output pin to disconnect your battery from the charging board once in a while (like every 5-10 minutes or so, depending on your project power drain) for a very short period of time to do the measurement below.

2) while the battery is disconnected, use an analog input pin of arduino with resistor-based voltage divider to see what's your battery voltage. Google for "measure voltage with arduino alone" for schemas and code, it's pretty straightforward.

For obvious reasons, you cannot do this measurement while having your charging board connected to battery, because you'll be getting voltage from the charger, and not from your battery. This is why we disconnected battery from the charging circuit in step 1.

3) Knowing
- current voltage you just get from your battery
- what is the voltage should be on your battery when it's fully charged
- the voltage you allow it to discharge to
... you can calculate percentages

4) digitalWrite to that pin to enable mosfet to connect your battery back to charging circuit


body: You might consider a coulomb counter IC, it is designed to give you the state of charge of the battery. There is a module labeled "LTC4150 Coulomb Counter" that will do exactly what you want.


message:
Arduino Strings concatenation

I am working on an arduino mega 2560 sketch.
I have to parse http query strings.

My program is concatenating strings for each http request.
And i have an http request every second during all day.

I have read that this kind of work may cause ram memory fragmentation. I am very upset about this because my program will randomly crash if there are no free ram memory.

Do you know if there is a way to initialise a string with a given memory length ?

I do not want to work with char arrays because i need indexof, substring functions and comparison with ==

Thanks

body:
There is a way to initialize an Arduino `String` with a given memory length: see `reserve()` method. It will generally greatly reduce or entirely eliminate memory fragmentation, if you can afford reserving a sufficient amount of memory in advance.

Just keep in mind that this is a "soft" boundary: once your string gets longer than the reserved amount, `String` will quietly resume reallocating memory with all those typical consequences.

It is not clear what you plan to do if the pre-reserved amount of memory proves to be insufficient. Fall back to "memory fragmentation"? Anything more elaborate than that will be pretty much as complex as performing manual management of a `char[]` array.

All the functionalities you requested are present for `char[]` arrays as well, might just require a few more lines of code. And it is not clear why one might "need" comparisons to be `==` specifically.

This might also be an XY problem. Why are you trying to concatenate all these requests in memory? What are you planning to do with them once you are done "concatenating"?


message:
Return constant string

Look at this code :

char * function1()
{
    return « hello »
}

Where is stored hello string ?
Is there a copy ?

What i want to avoid is to have a memory leak or accessing to another string instead of hello

Thanks

body:
    const char* function1() { return "hello"; }

> Where is stored hello string ? Is there a copy ?

The string is compiled into the program memory. Before setup() is called the constant values are copied to the data memory (aka SRAM).

The function will return the pointer to the same string (memory location).

To save data memory the string literal can be access directly in program memory.

    __FlashStringHelper* function1() { return F("hello"); }

Cheers!

Ref.

 1. https://en.cppreference.com/w/cpp/language/string_literal
 2. https://www.nongnu.org/avr-libc/user-manual/pgmspace.html


body:
String literals in C and C++ are stored in static memory, which in case of Arduino platform is ordinary data memory.

If we overlook the typos, your code is essentially equivalent to

    char *function1()
    {
      static char literal[6] = { 'h', 'e', 'l', 'l', 'o', '\0' };
      return literal;
    }

with a remark that in C and C++ you are not allowed to modify string literals. (Some nuances also depend on the specific language - C vs. C++ - which you failed to specify). Regardless of the language, it is always a better idea to use `const char *` pointers (as opposed to `char *`) to point to string literals.

There's no dynamic memory allocation here, and therefore no memory leaks possible. What you mean by "accessing another string" is not clear.


message:
Unresolved reference to public function from library

I have three libraries that I've written and I'm trying to use. They're stored as follows

<!-- language: lang-none -->

    Documents
    ├── Some/Path/To/Folder
    │   └── firmware.ino
    └── Arduino
        └── libraries
            ├── error
            │   ├── error.h
            │   └── error.cpp
            ├── lmp91000
            │   ├── lmp91000.h
            │   └── lmp91000.cpp
            └── tps7a7100
                ├── tps7a7100.h
                └── tps7a7100.cpp

Both lmp91000.h and tps7a7100.h have `#include "../error/error.h"` and are able to access variables and functions declared in error.h and error.cpp just fine.

firmware.ino includes all three libraries as you would expect them to be included and it is able to create instances of classes defined in both lmp91000 and tps7a7100 and use their methods (which depend on error). I am also able to create instances of a struct (`ERROR`) defined in error.h from firmware.ino, however I am not able to access functions from error.h and error.cpp. Error recived is
```
firmware.ino:19: undefined reference to `LOG_E(ERROR)'
```

However when I remove the guards in error.h that error no longer appears (implying that `LOG_E` can be resolved) but I get the expected errors of multiple definitions as there are multiple `#include error.h`.

My thoughts are that because of the guards error is not being included in a location where the sketch has access to the functions, but I may be completely off on that. I know there must be a way around this, as I'm able to access Wire.h for example from firmware.ino even though that is included in lmp91000.h - how do I solve this?

firmware.ino
```
#include <error.h>
#include <lmp91000.h>
#include <tps7a7100.h>
#include <Wire.h>

lmp91000 pot(12);
tpsa7100 vreg(10,9,8,7,6,5,4);

void setup() {
    Wire.begin();
    Serial.begin(115200);
    while(!Serial);
    vreg.enable();
    pot.enable();
    ERROR misc;
    misc.errorCode = 0x50;
    LOG_E(misc);
}

void loop() {
}
```

error.h
```
#ifndef error_h_included
#define error_h_included

#include "Arduino.h"

// Error Structure
typedef struct{
    int errorCode;
    char const *errorName;
    char const *errorDesc;
    bool isFatalError;
    bool shouldRetry;
}ERROR;

// Global error types
const ERROR E_SUCCESS = {0x00, "E_SUCCESS", "Success", false, false};
const ERROR E_INVALID_ARG = {0x10, "E_INVALID_ARG", "Invalid argument passed", true, false};
const ERROR E_I2C_NACK_ADDR = {0x20, "E_I2C_NACK_ADDR", "NACK on I2C address byte", false, true};
const ERROR E_I2C_NACK_DATA = {0x21, "E_I2C_NACK_DATA", "NACK on I2C data byte", false, true};
const ERROR E_I2C_BUFF_LEN = {0x22, "E_I2C_BUFF_LEN", "Transmit Data too long for I2C buffer", true, false};
const ERROR E_I2C_ERROR = {0x23, "E_I2C_ERROR", "Undefined I2C Error", true, false};
const ERROR E_I2C_TARGET_DISABLED = {0x24, "E_I2C_TARGET_DISABLED", "Target device for I2C comms disabled", false, false};
const ERROR E_I2C_READ_ERROR = {0x25, "E_I2C_READ_ERROR", "I2C Data could not be read", false, false};
const ERROR E_I2C_WRITE_ERROR = {0x26, "E_I2C_WRITE_ERROR", "Attempting to write zero bytes to I2C bus", false, false};

// Function Definitions
bool E(ERROR error_struct);
void LOG_E(ERROR error_struct);
ERROR WireErrorDecode(int code);

#endif
```

error.cpp
```
#include "error.h"

// Error Handling Functions

// E(ERROR)
// Evaluate the successfullness of the error
// Return 0 if error is a success error
// Return >0 if error is not success error
bool E(ERROR error_struct) {
    return (int)(error_struct.errorCode & 0xF0);
}

// LOG(ERROR)
// Log the error
void LOG_E(ERROR error_struct) {
    Serial.print(error_struct.errorCode);
    Serial.print("\t");
    Serial.print(error_struct.errorName);
    Serial.print("\t");
    Serial.println(error_struct.errorDesc);
}

// WireErrorDecode(code)
// Decode Wire.EndTransmission error codes
ERROR WireErrorDecode(int code) {
    switch(code) {
        case 0:
            return E_SUCCESS;
        case 1:
            return E_I2C_BUFF_LEN;
        case 2:
            return E_I2C_NACK_ADDR;
        case 3:
            return E_I2C_NACK_DATA;
        case 4:
            return E_I2C_ERROR;
        default:
            return E_INVALID_ARG;
    }
}
```

**Update:** These errors seem to be board specific - see question [here][1]

  [1]: https://arduino.stackexchange.com/questions/65398/code-comilation-erros-for-101-no-errors-with-uno

body:
The filename `error.h` is not a good name for a library. Some compilers and cores (such as the ESP32 and Curie cores) have a file `error.h` of their own which will be used in preference to yours.

Instead, name your library something more sensible.


message:
Leonardo soft bricked

I was uploading a sketch to my Arduino Leonardo and I pressed the reset button accidentally while it was still uploading. Now the board does not get recognized by my computer. Is there something that can be done to save it or should I get a new one?

body:
You'll need to program it trough the ISP port with an AVR programmer if you can't program it through a reset or double reset anymore. This can be done using another arduino. A tutorial is on the [arduino.cc website][1].

  [1]: https://www.arduino.cc/en/Tutorial/ArduinoISP


message:
Send Strings via SPI both ways using two Arduino UNOs(Master to Slave & Slave to Master)

I need to create a two way String exchanger via SPI with two Arduino UNOs. Strings and their lengths are independent variables of the main loop and they can change with every iteration. I need both of the Arduinos to communicate with each other regardless of what the strings contain. I want to see basically the same screen with the serial monitor.

It is kind of working. I am not sure how to explain it, I'll just show it below.

Basically the main idea for both of the Arduino's is like this:

    Master: hey
    Slave: hi

----------
Instead I get this on the master:

    Slave:
    Slave:
    Master: hey
    Slave: y
    Slave:
    Slave:
    .
    .
    .
    Slave: i
    Slave:
    Slave:
    .
    .

And the slave displays only itself:

    Slave: hi

I have created for loops to transfer every char of the string seperatly and respectively but this is still the case. I couldn't find any sample code online for independent string transfering via SPI. I know I probably have many mistakes but how can I fix them to work just as I intend to?

----------

**Connections:**

Arduino1.pin13 --- Arduino2.pin13

Arduino1.pin12 --- Arduino2.pin12

Arduino1.pin11 --- Arduino2.pin11

Arduino1.pin10 --- Arduino2.pin10

----------
**Master Code**

    //MASTER

    #include<SPI.h>

    String textSend="", textReceive="";

    void setup(){

      Serial.begin(115200);

      SPI.begin();
      SPI.setClockDivider(SPI_CLOCK_DIV8);    //Sets clock for SPI communication at 8 (16/8=2Mhz)
      digitalWrite(SS,LOW);
    }

    void loop(){

      textSend=""; textReceive="";
      textSend = Serial.readString();
      if(textSend != ""){
        for(int i = 0; i < textSend.length(); i++){
          delayMicroseconds (20);
          SPI.transfer(textSend[i]);
        }

        Serial.print ("Master: ");
        Serial.println (textSend);
      }else{
        int i = 0;
        char c;
        do{
          delayMicroseconds (20);
          c = SPI.transfer(1);
          textReceive += c;
          i++;
        }while(textReceive[i] != 0);

        if(textReceive[i] == 0){
          Serial.print ("Slave: ");
          Serial.println (textReceive);
          textReceive = "";
        }
      }
    }

----------
**Slave Code**

    //SLAVE

    #include<SPI.h>

    String textSend="";
    String textReceive="";

    void setup (void){
      Serial.begin(115200);
      pinMode(MISO, OUTPUT);
      SPCR |= _BV(SPE);
      SPCR |= _BV(SPIE);
      SPI.attachInterrupt();

    }

    ISR (SPI_STC_vect){ //Interrupt Service Routine

      byte c = SPDR;

      if(c != 1){ //Slave receives
        for(int i = 0; i < textReceive.length(); i++){
          textReceive += SPDR;
        }
        if(textReceive.length() > 0){
          Serial.print("Master: ");
          Serial.println(textReceive);
          textReceive = "";
        }
      }else{
        for(int i = 0; i < textSend.length(); i++){
          delayMicroseconds(20);
          SPDR = textSend[i];
        }
        if(textSend != ""){
          Serial.print("Slave: ");
          Serial.println(textSend);
          textSend = "";
        }
      }
    }

    void loop() {
      if(textSend == "")
        textSend = Serial.readString();

    }

body:
It's not trivial to have both arduinos communicating "with each other" as SPI is a master-slave bus. That means the slave cannot start a transmission, communication must always be initiated by the master instead. Another thing with SPI is that you can't read the slave without writing to it. SPI works like a shifting register: on every clock cycle both devices transmit the byte in their SPDR to each other. So, to read a long string from the slave the master has to transmit the exact same number of dummy-bytes and simultaniously read the incoming stream. This is great if only a specific number of bytes need to be transmitted (e.g. exchanging variables which always consist of the same number of bytes), but becomes complicate when the number of bytes varies. You will then need to implement some protocol that is able to read a variable amount of bytes from the slave (e.g. you will have to tell the master the number of bytes that have to be read).

I think serial communication like UART is perfect for your purpose as communication is real full-duplex, it's no master-slave-system and the common protocol uses a terminating character to end a data stream which makes it ideal to transmit strings. Also the arduino can run several serial interfaces (you might need another for debug output).