text:
Can't use enum as function argument
I declared my enum and called it Dir. I wanted to use value of that type in my function Move(). Here's the code:
enum Dir
{
  forward = 1,
  backward = 2,
  left = 3,
  right = 4
};

void Move ( Dir direction , int distance )
{
     direction = forward;
}

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

}

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

}

Unfortunately i get the following errors:
V2.ino:23:13: error: variable or field 'Move' declared void
V2.ino:23:13: error: 'Dir' was not declared in this scope
V2.ino:23:29: error: expected primary-expression before 'int'

What's wrong?

Please post a Minimal, Complete, and Verifiable example

Compiled OK for me, when I supplied (empty) setup() and loop() functions. There being fewer than 23 lines (the line # of the cited errors), I assume we're seeing an excerpt. Can you reduce your code to the minimum necessary to demonstrate the problem and show that, entirely?

@JRobert I also did just like you: I created a new sketch and copied the code from my post (I didn't put anything into setup() or loop()). I got the same errors. Why do i get them?

I second JRobert: compiled OK for me with void setup(){} void loop(){}, save for a couple of warnings about the function parameters not being used.

I'm using Arduino IDE 1.7.10. I'll check this code on my second PC

So I tried to compile the same code on my laptop (Arduino IDE 1.7.7) and the result is the same. I literally have: empty void setup(), empty void loop() and the code from my post above (which I put above setup() function). Actually I updated my post to show the whole thing I have in my .ino file.

You're suffering from the IDE's preprocessor being thick and doing things wrong.

So what can I do about it?

I am working on that... Just waiting for 1.7.10 to download.

Ok, thanks. Same thing happends on 1.7.7

The Arduino 1.7.x series from Arduino.org uses the old build system that is severely broken when you try and do anything more complex than simple types.
It adds prototypes to your functions to the top of the program so you don't have to get the order right, but it puts them in completely the wrong place.  The result is a C++ file that looks like this:
#include <Arduino.h>
void Move ( Dir direction , int distance );
void setup();
void loop();

enum Dir
{
  forward = 1,
  backward = 2,
  left = 3,
  right = 4
};

void Move ( Dir direction , int distance )
{
     direction = forward;
}

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

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

As you can see the prototype involving Dir has been placed before the definition of Dir, and so it fails miserably.
There are some hacks you can do to force it to place the prototypes after your definition, but I can't recall what they are off hand.
The simple answer is to ditch Arduino 1.7.10 and switch to Arduino 1.6.10 from Arduino.cc instead. This uses the Arduino Builder system which does things much better, including placing the prototypes in the right place.
Despite the numbering 1.7.10 is not a newer version than 1.6.10 - it is an older version renumbered. It's all part of the schism between the two halves of Arduino.
Even better is to ditch the awful Arduino IDE entirely and use one of the many far better IDEs that exist.

Thank you very much. What other IDE do you recommend? To be honest, I can't stand Arduino IDE, the code is really hard to read, personally I write programs in Visual Studio Code. I wish it was possible to upload to Arduino from there.

Well, I have to recommend UECIDE, but then I am biased since I wrote it ;)

I'll check it out

I wouldn't recommend Arduino at all, use C/C++ directly instead. There is a plethora of IDE for C/C++ out there. If you get a real programming pod you can even single step and inspect hardware registers.

I did not experience the problem because I usually use a Makefile instead of
the Arduino IDE. I now tried with the IDE version 1.0.5 and I had the same
problem as you. The fix is to explicitly declare the function before
defining it:
void Move(Dir direction, int distance);
void Move(Dir direction, int distance)
{
     direction = forward;
}

As Majenko points out, this seems to be a problem with the parsing of the preprocessor.
You have two options:

Use Edgar Bonets solution and declare the function before defining it

Create a separate header file for your enum in a new tab and import it with #include "[myEnumsHeaderFilename].h"

#include "myEnums.h"

void Move(Dir direction, int distance)
{
   direction = forward;
}

void setup() {}

void loop() {}

Or just use a different IDE. Thanks for your input

You have to define a new enum type:
typedef enum
{
  forward = 1,
  backward = 2,
  left = 3,
  right = 4
} Dir;

void Move ( Dir direction , int distance )
{
     direction = forward;
}

without typedef your Dir is just static enum variable, it can't be used to define other vars.

C++ creates typedefs of all enums and structs by default without you needing to do it manually.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Serial monitor can't display float and double values with absolute greater than 4294967040=2^32-2^8
I have the following sketch:
void setup() {}

void loop() {
  float af = 4294967040.0;
  float bf = 4294967240.0;
  double ad = 4294967040.0;
  double bd = 4294967040.00001;
  Serial.println(af);
  Serial.println(bf);
  Serial.println(ad);
  Serial.println(bd);
}

The values of af, bf, ad and bd are way smaller than 3.402823466e38 which is the maximum for float values. The values can still be correctly operated with, but the result on the serial monitor however is ovf for bf and bd.
Why is that?

Also note that on Unos etc there's no difference between doubles and floats: https://www.arduino.cc/reference/en/language/variables/data-types/double/

Related: Answer on StackOverflow.

It's not the data type, it's the printing routine that sets that limit.  In Print.cpp:
227   if (isnan(number)) return print("nan");
228   if (isinf(number)) return print("inf");
229   if (number > 4294967040.0) return print ("ovf");  // constant determined empirically
230   if (number <-4294967040.0) return print ("ovf");  // constant determined empirically

Don't ask why...

That's bizarre, it's not even the (quite) max unsigned int value. Might try a version w/o that and see what happens.

@DaveNewton I know. It was a surprise to me too...

print does not produce an exponent format, so there must be a reasonable limit somewhere. Maybe they took the mantissa size ? surprise, yes indeed. Thanks for bringing this to our attention,

4294967040.0 (float)  is 0x4f7fffff  => (Sign) 0  (Exponent) 10011110 (Mantissa) 11111111111111111111111

Looks like it's a guard for unsigned long int_part = (unsigned long)number;.  Since number can be larger than an unsigned long can hold, the explicit-cast, (unsigned long)number, probably threw an error or something, around that value.  Since the value was "determined empirically", it may've been a bit stricter than necessary.  Guessing it could've been as high as 2^32-1 (whereas it's actually just 2^32-256).

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Int64_t aka long long acts as int32_t and overflows at 2^31
I have an int64_t variable. When I add another int64_t variable
and convert it to a double to print it on the serial monitor, it acts as if it was a int32_t variable. This is the program:
int64_t a = 1 << 31;
double b = static_cast<double>(a);
Serial.println(b);

The output on the serial monitor is -2147483648.00.
What is going on?

1 << 31 is interpreted by the compiler as (int)1 << (int)32.
See the implicit types of integer literals. The
rules of usual arithmetic conversions state that no implicit conversion
is performed in this case. The result is then computed as an int, and
it overflows. Note that this is undefined behavior. The assignment
int64_t a = ... converts the (already overflowed) result to the wider
type, without changing its value.
You probably want to write something like:
int64_t a = 1LL << 31;

even  uint32_t a = 1UL << 31; would do the trick to interpret 0x80000000 as a positive number.  BTW, on a real arduino, where the native int is an int16_t you get 1<<31 == 0

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Set and extract individual bytes of a number (lowByte() and highByte())
You can extract

the low-order (rightmost) byte of a variable

or

the high-order (leftmost) byte of a word

with the functions lowByte() and highByte() respectively (the quotes are from the Arduino Reference).
Does Arduino provide a way to extract any byte from a number with a similar function?
And does it provide a way to set any individual bytes of a number (which would be the counterparts to these functions, if they exist)?

Any more sophisticated byte exchange can be done with binary operators.
Extracting information
You'll need some constants like
MASK         SHIFT
0xFF000000   24       (first byte, most significant)
0x00FF0000   16       (second byte)
0x0000FF00    8       (third byte)
0x000000FF    0       (last byte, least significant)

You would binary AND the original value with MASK
     0x12345678
AND  0x00FF0000
 =   0x00340000

and then bit shift it left, e.g.
   0x00340000
>> 16
 = 0x00000034

So from the original value 0x12345678 you have gotten 0x34.
Setting information
The opposite direction is also possible with the same constants but opposite operators and in opposite order:
   0x00000034
<< 16
 = 0x00340000

and then
   0x12005678
OR 0x00340000
 = 0x12345678

Note that the OR operation only works reliably if the corresponding positions are 0x00. That's fine with a starting value of 0x00000000.
If you don't know that or you want to process an arbitrary number, you can introduce a step in between
    0x12??5678   (?? could be anything)
AND 0xFF00FFFF   (which is the inverse of 0x00FF0000 and can be expressed as ~0x00FF0000)
 =  0x12005678   (whatever ?? was, it'll be cleared out)

Actual Code
Tested on Arduino Uno. The long data type is 32 bits or 4 bytes.
The code here may not be the most efficient. Advanced developers would likely not use MASK and SHIFT as arrays like this. This answer focuses more on the educational point.
long MASK[]  = {0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF};
byte SHIFT[] = {24        , 16        , 8         , 0};

// Extracts a byte from a larger data type
// value: larger data type to extract a byte from
// position: 0 based number, 0 = MSB, 3 = LSB
byte getByteAt(long value, byte position)
{
  long result = value & MASK[position];  // binary AND
  result = result >> SHIFT[position];    // Shift right, moving all bits
  byte resultAsByte = (byte) result;     // Convert to an actual byte
  return resultAsByte;
}

// Sets a byte in a larger data type
// value: larger data type where to set the byte
// position: 0 based number, 0 = MSB, 3 = LSB
// newPartialValue: the byte to be inserted
long setByteAt(long value, byte position, byte newPartialValue)
{
  long result = value & ~MASK[position];                       // clear the affected byte so that it is 0x00
  long valueToSet = (long) newPartialValue << SHIFT[position]; // Shift left, moving all bits
  result = result | valueToSet;                                // binary OR
  return result;
}

void setup() {
  Serial.begin(9600);
  Serial.println(getByteAt(0x12345678, 1));       // Prints 52, which is 0x34
  Serial.println(setByteAt(0x87654321, 1, 0xBB)); // Prints -2017770719 which is 0x87BB4321
}

void loop() {

}

Worth mentioning that the value you AND the number with to clear the bits prior to OR-ing is the inverse of the mask. You can use ~MASK to create it.

@Majenko: used and added in the example

Thanks for the extensive explanation, but I already knew about this possibility. So there is no inherent way to do this with built in functions?

You don't need to load MASK and SHIFT from an array!  shift = position * 8 = position << 3 (convert a bit offset to a byte offset.  Also, mask after shifting so it's just return (uint8_t)(value >> shift);.  e.g. on Godbolt for AVR and ARM cortex-M0 get and set byte functions: https://godbolt.org/z/2uFXN5  Also included are versions that store/reload and use a byte index, avoiding shift loops on AVR which can only shift 1 byte at a time.  (Will post an answer if I get back to this.)

@PeterCordes: my primary concern was to explain it thoroughly and in an understandable, visible way. I am also participating in code golf, so yeah, it's definitely not the shortest form :-) In general I am not optimizing for speed as long as there is no speed requirement.

Yeah, it's a good explanation, but writing over-complicated code makes it harder for future readers of the code.  Also, I just noticed a flaw: your arrays are backwards!  Most people would consider "byte 0" of an integer to be the least-significant byte.  Your code gives the most significant, opposite of value >> bitpos.  (And opposite of memory order: AVR and ARM are little-endian).  I think the code in my Godbolt link is very readable, like bitpos = position * 8.

And as far as efficiency, sure small differences usually don't matter, but for a compile-time-constant position your GetByteAt version still compiles to ~50 AVR instructions instead of 1 because you forgot to make your arrays const and/or static.  So the compiler can't do constant-propagation through the array indexing.  (see the test_... callers: https://godbolt.org/z/chtKzJ)  That's a pretty significant difference in static code footprint for something you'd expect to be cheap.

There are two alternative methods, and they can both be easily used "in reverse" as well:
Unions
union byte_extract {
    uint32_t ival;
    struct {
        uint8_t byte_0; // least significant byte
        uint8_t byte_1;
        uint8_t byte_2;
        uint8_t byte_3; // most significant byte
    } bval;
};

... later ...

union byte_extract x;

x.ival = 65536 * 99; // change to whatever you want
Serial.println(x.bval.byte_2); //3rd byte

Unions are a way to define multiple possible ways to interpret a piece of memory, usually to save memory when you know something can't be 2 things at once. Strictly speaking it is not recommended to use them in this way but it works.
Pointer arithmetic
uint32_t *xaddr;
uint8_t *xbyteaddr;

uint32_t x = 65536 * 99; // change to whatever you want
xaddr = &x;
xbyteaddr = (uint8_t *) xaddr;

Serial.println(xbyteaddr[2]); //3rd byte

Memory addresses (on Arduino as well as on PCs) refer to the first byte of a variable.  If you have an (uint32_t *) you will read 4 bytes starting at that address. But if you have a (uint8_t *) or a (char *) you will only read 1 byte. You can shift this pointer-to-uint8_t forwards by as many bytes as you want.
Apologies if this doesn't quite work on Arduino, I have only tested it on PC.

This use of unions is well-defined by C99.  An array of uint8_t bytes[4] would be more readable and allow runtime indexing, though.  Your pointer-arithmetic version is only safe because uint8_t is going to be unsigned char, and unsigned char* is allowed to alias anything without violating strict-aliasing.  Note that both of these are endianness-dependent.

The header Arduino.h defines the macro word(high_byte, low_byte). The
resulting value is an uint16_t.

Thank you, that answers the question about the counterpart of lowByte() and highByte(). Are there any functions for the rest of my question though?

@LukasFun: I couldn't find any. But note that on the AVR-based Arduinos an int is only two bytes.

You should simply treat those definitions as samples, learn enough C/C++ to understand them, and extend them to whatever you need. If uint16_t is not what you need, why should exactly uint32_t be your solution?


text:
Unable to declare variable in a library that doesn't have a class: multiple definition of the variable
I have created a library Lib that doesn't have a class. I want this library to have a variable that can be accessed from outside. The way I would go about this is to just declare them in the header file.
However, if I do this like so:
int myVariable = 1;

with the .cpp-file containing only
#include "Lib.h"

I get this error message when compiling an empty sketch that includes this library:

multiple definition of `myVariable'

and for some weird reason

Multiple libraries were found for "Lib.h"

on top of that (although, this is something I have encountered before - when there is some error during the compilation, this error may come alongside it, even though there are no multiple libraries; it goes away when the other compilation errors are resolved aswell).
What is causing that error and how to resolve it?

Do you have include guards around your library code, so that it cannot be included multiple times?

No, I don't. Would that matter if the library is only included once in an empty sketch with nothing else?

I don't know, this was just a wild guess. You can try it with include guards. If you defined the variable only in the header file, then I think the only way, that it can be defined multiple times is by multiple inclusions of the header file. Maybe because you included it in your cpp file and in your main sketch

const int myVariable = 1; if it is a constant

In Lib.h you should declare an
extern int myVariable;

In Lib.cpp you can define it once
#include "Lib.h"
int myVariable=123;
...

What is the problem assigning it in the C file instead of the header file (since the C file includes the header file, everything is available at compile time)?

I can't use it for purposes that need the variables value known at compile time. -- Then you shouldn't be using a variable. If it's wanted at compile time then you need a constant, not a variable. Variables change. If it's wanted at compile time then you really don't want it to change. It should be a constant or a #define.

If you want a "variable" that is used at compile time, for instance to set the size of an array, then a variable is not what you want.
Variables change. That's what "variable" means. If you are using it for something at compile time then it can't be variable, since it must never change.
Ergo, you want either a constant or a #define macro which is replaced with a literal.  Both of these can be done in the header, since they both by default have local TU scope:
const int myVariable = 123;

Or to use a macro:
#define SAMPLE_ARRAY_SIZE 123


text:
got a compiling error while programming node mcu
i was programming my node mcu i modified the code and got a complination error but when i compiled the original code i got no error
modified code
#include "arduino_secrets.h"
#include "thingProperties.h"

// define the GPIO connected with Relays and switches
#define RelayPin1 5  //D1
#define RelayPin2 4  //D2
#define RelayPin3 14 //D5
#define RelayPin4 12 //D6

#define RelayPin5 2  //d4
#define RelayPin6 0   //D3
#define RelayPin7 13  //D7
#define RelayPin8 15   //d8

#define wifiLed   16   //D0

int toggleState_1 = 0; //Define integer to remember the toggle state for relay 1
int toggleState_2 = 0; //Define integer to remember the toggle state for relay 2
int toggleState_3 = 0; //Define integer to remember the toggle state for relay 3
int toggleState_4 = 0; //Define integer to remember the toggle state for relay 4
int toggleState_5 = 0; //Define integer to remember the toggle state for relay 5
int toggleState_6 = 0; //Define integer to remember the toggle state for relay 6
int toggleState_7 = 0; //Define integer to remember the toggle state for relay 7
int toggleState_8 = 0; //Define integer to remember the toggle state for relay 8

void relayOnOff(int relay) {

  switch (relay) {
    case 1:
      if (toggleState_1 == 0) {
        digitalWrite(RelayPin1, HIGH); // turn on relay 1
        toggleState_1 = 1;
        Serial.println("Device1 ON");
      }
      else {
        digitalWrite(RelayPin1, LOW); // turn off relay 1
        toggleState_1 = 0;
        Serial.println("Device1 OFF");
      }
      delay(100);
      break;
    case 2:
      if (toggleState_2 == 0) {
        digitalWrite(RelayPin2, HIGH); // turn on relay 2
        toggleState_2 = 1;
        Serial.println("Device2 ON");
      }
      else {
        digitalWrite(RelayPin2, LOW); // turn off relay 2
        toggleState_2 = 0;
        Serial.println("Device2 OFF");
      }
      delay(100);
      break;
    case 3:
      if (toggleState_3 == 0) {
        digitalWrite(RelayPin3, HIGH); // turn on relay 3
        toggleState_3 = 1;
        Serial.println("Device3 ON");
      } else {
        digitalWrite(RelayPin3, LOW); // turn off relay 3
        toggleState_3 = 0;
        Serial.println("Device3 OFF");
      }
      delay(100);
      break;
     case 4:
      if (toggleState_4 == 0) {
        digitalWrite(RelayPin4, HIGH); // turn on relay 3
        toggleState_4 = 1;
        Serial.println("Device4 ON");
      } else {
        digitalWrite(RelayPin4, LOW); // turn off relay 3
        toggleState_4 = 0;
        Serial.println("Device4 OFF");
      }
      delay(100);
      break;
     case 5:
      if (toggleState_5 == 0) {
        digitalWrite(RelayPin5, HIGH); // turn on relay 3
        toggleState_5 = 1;
        Serial.println("Device5 ON");
      } else {
        digitalWrite(RelayPin5, LOW); // turn off relay 3
        toggleState_5 = 0;
        Serial.println("Device5 OFF");
      }
      delay(100);
      break;
     case 6:
      if (toggleState_6 == 0) {
        digitalWrite(RelayPin6, HIGH); // turn on relay 3
        toggleState_6 = 1;
        Serial.println("Device6 ON");
      } else {
        digitalWrite(RelayPin6, LOW); // turn off relay 3
        toggleState_6 = 0;
        Serial.println("Device6 OFF");
      }
      delay(100);
      break;
     case 7:
      if (toggleState_7 == 0) {
        digitalWrite(RelayPin7, HIGH); // turn on relay 3
        toggleState_7 = 1;
        Serial.println("Device7 ON");
      } else {
        digitalWrite(RelayPin7, LOW); // turn off relay 3
        toggleState_7 = 0;
        Serial.println("Device7 OFF");
      }
      delay(100);
      break;
    case 8:
      if (toggleState_8 == 0) {
        digitalWrite(RelayPin8, HIGH); // turn on relay 4
        toggleState_8 = 1;
        Serial.println("Device8 ON");
      }
      else {
        digitalWrite(RelayPin8, LOW); // turn off relay 4
        toggleState_8 = 0;
        Serial.println("Device8 OFF");
      }
      delay(100);
      break;
    default : break;
  }
}

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500);

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  pinMode(RelayPin1, OUTPUT);
  pinMode(RelayPin2, OUTPUT);
  pinMode(RelayPin3, OUTPUT);
  pinMode(RelayPin4, OUTPUT);
  pinMode(RelayPin5, OUTPUT);
  pinMode(RelayPin6, OUTPUT);
  pinMode(RelayPin7, OUTPUT);
  pinMode(RelayPin8, OUTPUT);

  pinMode(wifiLed, OUTPUT);

  digitalWrite(RelayPin1, LOW);
  digitalWrite(RelayPin2, LOW);
  digitalWrite(RelayPin3, LOW);
  digitalWrite(RelayPin4, LOW);
  digitalWrite(RelayPin5, LOW);
  digitalWrite(RelayPin6, LOW);
  digitalWrite(RelayPin7, LOW);
  digitalWrite(RelayPin8, LOW);

  digitalWrite(wifiLed, HIGH);  //Turn ON WiFi LED
}

void loop() {
  ArduinoCloud.update();

  if (WiFi.status() != WL_CONNECTED)
  {
    digitalWrite(wifiLed, HIGH); //Turn ON WiFi LED
  }
  else{
    digitalWrite(wifiLed, LOW); //Turn OFF WiFi LED
  }
}

the original code
#include "arduino_secrets.h"
#include "thingProperties.h"

// define the GPIO connected with Relays and switches
#define RelayPin1 5  //D1
#define RelayPin2 4  //D2
#define RelayPin3 14 //D5
#define RelayPin4 12 //D6

#define SwitchPin1 10  //SD3
#define SwitchPin2 0   //D3
#define SwitchPin3 13  //D7
#define SwitchPin4 3   //RX

#define wifiLed   16   //D0

int toggleState_1 = 0; //Define integer to remember the toggle state for relay 1
int toggleState_2 = 0; //Define integer to remember the toggle state for relay 2
int toggleState_3 = 0; //Define integer to remember the toggle state for relay 3
int toggleState_4 = 0; //Define integer to remember the toggle state for relay 4

void relayOnOff(int relay) {

  switch (relay) {
    case 1:
      if (toggleState_1 == 0) {
        digitalWrite(RelayPin1, HIGH); // turn on relay 1
        toggleState_1 = 1;
        Serial.println("Device1 ON");
      }
      else {
        digitalWrite(RelayPin1, LOW); // turn off relay 1
        toggleState_1 = 0;
        Serial.println("Device1 OFF");
      }
      delay(100);
      break;
    case 2:
      if (toggleState_2 == 0) {
        digitalWrite(RelayPin2, HIGH); // turn on relay 2
        toggleState_2 = 1;
        Serial.println("Device2 ON");
      }
      else {
        digitalWrite(RelayPin2, LOW); // turn off relay 2
        toggleState_2 = 0;
        Serial.println("Device2 OFF");
      }
      delay(100);
      break;
    case 3:
      if (toggleState_3 == 0) {
        digitalWrite(RelayPin3, HIGH); // turn on relay 3
        toggleState_3 = 1;
        Serial.println("Device3 ON");
      } else {
        digitalWrite(RelayPin3, LOW); // turn off relay 3
        toggleState_3 = 0;
        Serial.println("Device3 OFF");
      }
      delay(100);
      break;
    case 4:
      if (toggleState_4 == 0) {
        digitalWrite(RelayPin4, HIGH); // turn on relay 4
        toggleState_4 = 1;
        Serial.println("Device4 ON");
      }
      else {
        digitalWrite(RelayPin4, LOW); // turn off relay 4
        toggleState_4 = 0;
        Serial.println("Device4 OFF");
      }
      delay(100);
      break;
    default : break;
  }
}

void manual_control() {
  //Manual Switch Control
  if (digitalRead(SwitchPin1) == LOW) {
    delay(200);
    relayOnOff(1);
  }
  else if (digitalRead(SwitchPin2) == LOW) {
    delay(200);
    relayOnOff(2);
  }
  else if (digitalRead(SwitchPin3) == LOW) {
    delay(200);
    relayOnOff(3);
  }
  else if (digitalRead(SwitchPin4) == LOW) {
    delay(200);
    relayOnOff(4);
  }
}

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500);

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

  pinMode(RelayPin1, OUTPUT);
  pinMode(RelayPin2, OUTPUT);
  pinMode(RelayPin3, OUTPUT);
  pinMode(RelayPin4, OUTPUT);

  pinMode(wifiLed, OUTPUT);

  pinMode(SwitchPin1, INPUT_PULLUP);
  pinMode(SwitchPin2, INPUT_PULLUP);
  pinMode(SwitchPin3, INPUT_PULLUP);
  pinMode(SwitchPin4, INPUT_PULLUP);

  //During Starting all Relays should TURN OFF
  digitalWrite(RelayPin1, HIGH);
  digitalWrite(RelayPin2, HIGH);
  digitalWrite(RelayPin3, HIGH);
  digitalWrite(RelayPin4, HIGH);

  digitalWrite(wifiLed, HIGH);  //Turn OFF WiFi LED
}

void loop() {
  ArduinoCloud.update();

  manual_control(); //Control relays manually

  if (WiFi.status() != WL_CONNECTED)
  {
    digitalWrite(wifiLed, HIGH); //Turn OFF WiFi LED
  }
  else{
    digitalWrite(wifiLed, LOW); //Turn ON WiFi LED
  }
}

void onSwitch1Change() {
  if (switch1 == 1)
  {
    digitalWrite(RelayPin1, HIGH);
    Serial.println("Device1 ON");
    toggleState_1 = 1;
  }
  else
  {
    digitalWrite(RelayPin1, LOW);
    Serial.println("Device1 OFF");
    toggleState_1 = 0;
  }
}

void onSwitch2Change() {
  if (switch2 == 1)
  {
    digitalWrite(RelayPin2, HIGH);
    Serial.println("Device2 ON");
    toggleState_2 = 1;
  }
  else
  {
    digitalWrite(RelayPin2, LOW);
    Serial.println("Device2 OFF");
    toggleState_2 = 0;
  }
}

void onSwitch3Change() {
  if (switch3 == 1)
  {
    digitalWrite(RelayPin3, HIGH);
    Serial.println("Device2 ON");
    toggleState_3 = 1;
  }
  else
  {
    digitalWrite(RelayPin3, LOW);
    Serial.println("Device3 OFF");
    toggleState_3 = 0;
  }
}

void onSwitch4Change() {
  if (switch4 == 1)
  {
    digitalWrite(RelayPin4, HIGH);
    Serial.println("Device4 ON");
    toggleState_4 = 1;
  }
  else
  {
    digitalWrite(RelayPin4, LOW);
    Serial.println("Device4 OFF");
    toggleState_4 = 0;
  }
}

i have included the arduino_secrets and thingproperties in my both pieces of code the difference is that i wanted 8 relay pins to be configured instead of 4 pins
please ask if any thing is needed from me
this was the exact error
C:\Users\akki kisu\Documents\Arduino\libraries\ArduinoIoTCloud\src\property\Property.cpp:25:19: note: '#pragma message: No RTC available on this architecture - ArduinoIoTCloud will not keep track of local change timestamps .'
   25 |   #pragma message "No RTC available on this architecture - ArduinoIoTCloud will not keep track of local change timestamps ."
      |                   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
c:/users/akki kisu/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\Code_NodeMCU_Alexa_ArduinoIotCloud_4Relays.ino.cpp.o:(.text._Z14initPropertiesv+0x1c): undefined reference to `_Z15onSwitch1Changev'
c:/users/akki kisu/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\Code_NodeMCU_Alexa_ArduinoIotCloud_4Relays.ino.cpp.o:(.text._Z14initPropertiesv+0x34): undefined reference to `_Z15onSwitch2Changev'
c:/users/akki kisu/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\Code_NodeMCU_Alexa_ArduinoIotCloud_4Relays.ino.cpp.o:(.text._Z14initPropertiesv+0x40): undefined reference to `_Z15onSwitch3Changev'
c:/users/akki kisu/appdata/local/arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/3.0.4-gcc10.3-1757bed/bin/../lib/gcc/xtensa-lx106-elf/10.3.0/../../../../xtensa-lx106-elf/bin/ld.exe: sketch\Code_NodeMCU_Alexa_ArduinoIotCloud_4Relays.ino.cpp.o:(.text._Z14initPropertiesv+0x4c): undefined reference to `_Z15onSwitch4Changev'
collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

And... what is the "error" you got?

you can reduce the code by almost 90% if you use arrays to hold pin numbers and pin state ... if (toggleState[relay] == 0) { digitalWrite(RelayPin[relay], HIGH);

"Hey please help me with this error. Though I won't tell you what error it is." We are not magical. Please provide the full error output including the line where the error happened

did you remove the variables in the thing definition on Arduino IoT cloud? or you get error "Undefined reference to onSwitch1Change"?

What is the difference between your modified code and the original code? Look at it, and you are at least one step nearer to the reason.

i got an error that error compiling for nodemcu board and for no particular line

you get linker error "Undefined reference to onSwitch1Change"?

In Arduino IoT cloud the variables synced between the Cloud and the sketch are defined in the definition of the (IoT) thing. The variables are reflected into the thingProperties.h file which is maintained by the Cloud editor. The on<variable_name> functions in the sketch handle the synchronization of these variables. They are declared in the thingProperties.h
You removed the onSwitchChange functions, but you didn't remove the switchChange variables in the definition of the Thing. The thingProperties.h still contains declarations of onSwitchChange functions, but the linker can't find the definition of the function because you removed it from the sketch.
The errors are like this one:
undefined reference to `_Z15onSwitch1Changev'

To solve this, remove the switchChange variables from the thing in the Cloud UI.


text:
Help reducing dynamic memory usage with LoRa library
I have combined code that reads heart rate and SPO2 then sends the data using LoRaWAN. Using these 2 libraries that work well by themselves LoraWAN lib | MAX30102 lib. My board is an Arduino Pro or Pro Mini with ATmega 328P (3.3V, 8 MHz) processor.

Global variables use 2098 bytes (102%) of dynamic memory, leaving -50 bytes for local variables. Maximum is 2048 bytes

I've tried reducing char array size to 8, removing some Serial.print stuff, and the best I can get is exactly 2048 bytes and getting uploaded but it won't run. Here's my Arduino code:
#include <DFRobot_MAX30102.h>
#include <lorawan.h>
DFRobot_MAX30102 particleSensor;

//ABP Credentials
const char *devAddr = "27FD.....";
const char *nwkSKey = "9E74A99C9FE480........................";
const char *appSKey = "E2A779DC190B343.......................";

const unsigned long interval = 20000; // 10 s interval to send message
unsigned long previousMillis = 0; // will store last time message sent

char myStr[50];

const sRFM_pins RFM_pins = {
  .CS = 10,
  .RST = 9,
  .DIO0 = 2,
  .DIO1 = 6,
};

void setup() {
  //Init serial
  Serial.begin(115200);
  lora.init();
  particleSensor.begin();

  particleSensor.sensorConfiguration(/*ledBrightness=*/50, /*sampleAverage=*/SAMPLEAVG_4, \
                        /*ledMode=*/MODE_MULTILED, /*sampleRate=*/SAMPLERATE_100, \
                        /*pulseWidth=*/PULSEWIDTH_411, /*adcRange=*/ADCRANGE_16384);

  // Set LoRaWAN Class change CLASS_A or CLASS_C
  lora.setDeviceClass(CLASS_C);

  // Set Data Rate
  lora.setDataRate(SF12BW125);

  // set channel to random
  lora.setChannel(MULTI);

  // Put ABP Key and DevAddress here
  lora.setNwkSKey(nwkSKey);
  lora.setAppSKey(appSKey);
  lora.setDevAddr(devAddr);
}

int32_t SPO2; //SPO2
int8_t SPO2Valid; //Flag to display if SPO2 calculation is valid
int32_t heartRate; //Heart-rate
int8_t heartRateValid; //Flag to display if heart-rate calculation is valid

void loop() {
  if(millis() - previousMillis > interval) {
    previousMillis = millis();
    particleSensor.heartrateAndOxygenSaturation(/**SPO2=*/&SPO2, /**SPO2Valid=*/&SPO2Valid, /**heartRate=*/&heartRate, /**heartRateValid=*/&heartRateValid);
    //Print result
    Serial.print(heartRate, DEC);
    Serial.println(SPO2, DEC);

    sprintf(myStr, "%d,%d", heartRate,SPO2);

    Serial.print(F("Send: "));
    Serial.println(myStr);

    lora.sendUplink(myStr, strlen(myStr), 0);
  }
  lora.update();
}

A replacement for sprintf() would be a step in the right direction.

i did try removing sprintf, still too much memory

Surely you don't need an int32 to store someone's heart rate.  And you don't need 50 char buffer to write two integers.

Why even store that in a buffer at all?  Just print heartRate, a space, and SPO2 in three separate prints and get rid of sprintf AND the buffer.

Also at forum.arduino.cc and getting attention there.

I’m voting to close this question because it's getting attention on another forum.

@Delta_G that is not a valid reason to close a question here

Then don't vote that way.

Find another Max30102 library, hidden in the library there are two buffers that took up 800 bytes memory.

Judging from the source code, your sketch does not look RAM-heavy at
all. The high RAM usage almost certainly comes from the libraries you
are using. Other than using different libraries, or a different board,
you don't have much leverage here.
On the sketch itself, the only thing that sticks out is the myStr
array, which you could make much smaller. Other than that, I suggest
moving the constant strings devAddr, nwkSKey and appSKey to
PROGMEM, and copying them to RAM only when needed:
const char devAddr[] PROGMEM = "27FD.....";
// and so on for nwkSKey and appSKey

void setup() {
    // ...
    char buffer[39];  // RAM buffer for nwkSKey, appSKey and devAddr
    memcpy_P(buffer, nwkSKey, sizeof nwkSKey);
    lora.setNwkSKey(nwkSKey);
    memcpy_P(buffer, appSKey, sizeof appSKey);
    lora.setAppSKey(appSKey);
    memcpy_P(buffer, devAddr, sizeof devAddr);
    lora.setDevAddr(devAddr);
}

This way the three strings share the same RAM space, which is freed as
soon as setup() returns.
Other than that, you may try sending the data in binary instead of
ASCII. I am not sure this would save much RAM though:
void loop() {
    // ...
    struct {
        int32_t heartRate;
        int32_t SPO2;
    } loraPacket;
    char dummy;
    particleSensor.heartrateAndOxygenSaturation(
            /** SPO2 = */         &loraPacket.SPO2,
            /** SPO2Valid = */    &dummy,
            /** heartRate = */    &loraPacket.heartRate,
            /** heartRateValid=*/ &dummy);
    lora.sendUplink(loraPacket, strlen(loraPacket), 0);
}

This would let you remove the myStr variable, at the cost of having to
change the receiver's code, and making the communication protocol harder
to read.
Edit: If you don't mind modifying the DFRobot_MAX30102 library, you
may save 184 bytes of RAM by storing uch_spo2_table in PROGMEM:
// In src/SPO2/algorithm.h, add PROGMEM:
const uint8_t uch_spo2_table[184] PROGMEM = {/* ... */ };

// In src/SPO2/algorithm.h, line 199, add pgm_read_byte():
n_spo2_calc = pgm_read_byte(&uch_spo2_table[n_ratio_average]);


text:
Limit of EthernetClient connections
I'm working on a project on which I need to have multiple EthernetClient connections to different servers. All of these connections must be kept alive simultaneously and by this I mean I cannot stop or close one of these clients before starting the other.
Currently I can keep 2 simultaneous successful EthernetClient connections. After this, any subsequent client fails to connect to any server. The following code is running on an ESP32-S3 with a W5500 Ethernet module.
#include <Arduino.h>
#include <EthernetLarge.h>
#include <SPI.h>

#define     SPI_MOSI    35
#define     SPI_MISO    37
#define     SPI_SCK     36
#define     ETHERNET_CS 38

SPIClass SPI_Ethernet;
EthernetClient ethCli1;
EthernetClient ethCli2;
EthernetClient ethCli3;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

void setup()
{
  Serial0.begin(115200);
  SPI_Ethernet.begin(SPI_SCK, SPI_MISO, SPI_MOSI, ETHERNET_CS);

  pinMode(39, OUTPUT);
  pinMode(47, OUTPUT);
  digitalWrite(47, HIGH);
  digitalWrite(39, LOW);
  delay(500);
  digitalWrite(39, HIGH);

  Ethernet.init(ETHERNET_CS);
  Ethernet.begin(mac);
  Serial0.println(Ethernet.localIP());

  if( !(ethCli1.connect("httpbin.org", 80)) )
      Serial0.println("connection > 1 < failed");
  else
    Serial0.println("connection > 1 < succeeded");

  if( !(ethCli2.connect("httpbin.org", 80)) )
    Serial0.println("connection > 2 < failed");
  else
    Serial0.println("connection > 2 < succeeded");

  if( !(ethCli3.connect("httpbin.org", 80)) )
    Serial0.println("connection > 3 < failed");
  else
    Serial0.println("connection > 3 < succeeded");
}

void loop()
{
}

Which outputs:
connection > 1 < succeeded
connection > 2 < succeeded
connection > 3 < failed

In this code I'm using the OPEnSLab-OSU/EthernetLarge Ethernet library. But I also tried to run it with the Ethernet.h with the same output. In the W5500 documentation I was able to find the information that it can keep up to 8 connections open, but I wasn't able to find if the ESP32 has any restrictions like a max of simultaneous connections. Is it possible to keep more than 2 connections alive simultaneously?
In short:

I'm using an ESP32-S3 with a W5500 Ethernet Module.
I can keep 2 simultaneous connections and closing previous connections before opening a new one works, but in my project I need to keep at least 3 simultaneous connections.
Changing from OPEnSLab-OSU/EthernetLarge Ethernet library to Ethernet.h produced the same output.
Adding a delay between the connections didn't work.
In the example code all the connections are being established to the same server, but in my official project these connections are established to different servers. Either way the output is the same.
The W5500 documentation says that it can keep up to 8 simultaneous connections. I wasn't able to find if ESP32 has any restrictions on the limit of simultaneous connections.

The OPEnSLab-OSU/EthernetLarge library by default defines MAX_SOCK_NUM to 2. Increasing this value allowed me to keep more simultaneous connections.
Regarding the Ethernet.h library, I also checked it and it was already setting MAX_SOCK_NUM to 8. Testing the code again with it also allowed me to keep more simultaneous connections. Why I wasn't able to keep them before when using Ethernet.h it is still a mystery to me.


text:
Error 101 Server Did Not Report Size from OTA Upgrade framework via git hub
I have tried this video:
ESP8266 Self Update OTA from GitHub
Instruction and made this GitHub repo:
And changed the main code to this type, but I get this error:
HTTP_UPDATE_FAILD Error (-101): Server Did Not Report Size

when the    FirmwareUpdate(); code is running.
So I don't know why GitHub don't answer to the esp8266, as said here:

The error has nothing to do with your sketch. Also, the error code is
not a HTTP 101 error. The problem is that your server does not send
the response header 'Content-Length'

I have some dupt about the bin URL file address which have many dot on the end of it (https://github.com/soheilpaper/ota_github_blink/blob/main/BlinkWithoutDelay.ino.esp8285.bin) on it, could it be the reason for none answering and giving the 101 code form GitHub server!
Any suggestion would be good help to fix this bug.
Update 1:

I have changed the bin file name to this kind :
 BlinkWithoutDelay.ino.esp8285.bin  ---->      BlinkWithoutDelay_ino_esp8285.bin

But I have again the same GitHub 101 error.

Update 2:
Based on the timemage answer, I have changed the address of bin and TXT file by finding the download link of those files form the GitHub. And it has been working by changing the blob part of address to raw, so the bin address changed form https://github.com/soheilpaper/ota_github_blink/blob/main/BlinkWithoutDelay_ino_esp8285.bin to https://github.com/soheilpaper/ota_github_blink/raw/main/BlinkWithoutDelay_ino_esp8285.bin And the https://github.com/soheilpaper/ota_github_blink/blob/main/version.txtto  https://raw.githubusercontent.com/soheilpaper/ota_github_blink/main/version.txt
And now that error has been fixed as you can see below:

Although I gave some dupt about upgrading the main code by getting this output via serial port:
Device already on latest firmware version

And I would check it after some resting!.
Thanks.

Your question seems to contain its own answer, so I'm confused.  Do you understand what the Content-Length header is?

please, no picture of text ... it is unreadable ... post the actual text

@timemage, I don't know how can I get this information via the main code!

@jsotola, there is not s information via serial port output, the main part of it is the 101 error type by this output : HTTP_UPDATE_FAILD Error (-101): Server Did Not Report Size

If Device already on latest firmware version is a problem, and it's not clear that it is, it is probably the subject of a new question.

The ESP8266httpUpdate library wants to know in advance how large the file is before it starts downloading it.  It wants to know this so it can tell, before trying to download (and program), whether or not there's enough space for it. If the size of the file isn't provided by the server it will report the error that you are seeing.
The size of the file is provided by the web server by means of the Content-Length HTTP response header read by HTTPClient.  This header is received in advance of the file content.
Your main code appears to contain a correct link to raw .bin file,
#define URL_fw_Bin "https://raw.githubusercontent.com/programmer131/otaFiles/master/firmware.bin", and reports the following headers:
cache-control: max-age=300
content-security-policy: default-src 'none'; style-src 'unsafe-inline'; sandbox
content-type: application/octet-stream
etag: "b2ecfb5dc91587c089acdaace446b0d7b00863c9f42dffb36c7983c103d3a98a"
strict-transport-security: max-age=31536000
x-content-type-options: nosniff
x-frame-options: deny
x-xss-protection: 1; mode=block
via: 1.1 varnish (Varnish/6.0), 1.1 varnish
x-github-request-id: 8728:2B67:9AFD3:AD0EC:6008FCFF
accept-ranges: bytes
date: Thu, 21 Jan 2021 04:03:32 GMT
x-served-by: cache-bos4651-BOS
x-cache: MISS, HIT
x-cache-hits: 0, 1
x-timer: S1611201812.154162,VS0,VE1
vary: Authorization,Accept-Encoding
access-control-allow-origin: *
x-fastly-request-id: bfc9702929b91be55d7aa040465a230436918e01
expires: Thu, 21 Jan 2021 04:08:32 GMT
source-age: 20
content-length: 270016

The content-length: 270016 at the bottom shows that this should work.  But your changed code that uses #define URL_fw_Bin "https://github.com/soheilpaper/ota_github_blink/blob/main/BlinkWithoutDelay_ino_esp8285.bin is to the HTML page for downloading the file, which does not report Content-length, for me anyway, but then it's the wrong URL anyway.
Regarding the "101 error", it's -101 (negative) defined here, and like they said, it is not an HTTP status code,  it is just a value used by the ESP8266httpUpdate library.

Thanks, I have changed the address of bin and TXT file by finding the download link of those files form the GitHub. And it has been working by changing the blob part of address to raw, so the bin address changed form https://github.com/soheilpaper/ota_github_blink/blob/main/BlinkWithoutDelay_ino_esp8285.bin to https://github.com/soheilpaper/ota_github_blink/raw/main/BlinkWithoutDelay_ino_esp8285.bin, also I have updated the question and add more details.


text:
Battery life calculation using Nano, NRF24L01+ and window magnetic reed switch
I'm trying to make my own home wireless security system.  I will be using probably 3 AA batteries to power these devices.  My problem is that I need to know if the batteries will be enough to power the devices for at least 6 months.
Below are the details of all the devices I will be using:

Mini Nano V3.0 ATmega328P Microcontroller Board w/USB Cable For Arduino
Makerfire Arduino NRF24L01+ 2.4GHz Wireless RF Transceiver Module
uxcell MC 38 Mount Wired Door Window Sensor Magnetic Reed Switch Recessed

Below are some project requirements that might be useful:

For the Nano, I want to put it to sleep using delay(2000) in the loop() function.  The Nano will be the one checking the window sensor.
I will be using a project enclosure of about 4X4 inches.

If this will not be possible maybe someone knows of other devices that use less power that will be more suitable for this project? I would prefer something easy to use like Arduino Nano with USB so I can easily program it.
EDIT: sorry but I just like to add that from the main HUB component, I would like to check the status of the window sensor if it is open/closed.  This will be useful if there is an open window/door around the house when going to sleep. Probably the Nano will broadcast its current window sensor status to the main HUB program. Thanks.

how will you make sure than nobody can jam the radio signal?

@jsotola I addressed this in my answer. Even with "still alive" functionality the sensor should last for many months if programmed properly.

I'm just trying to build my own home security system.  My electronics knowledge is very limited, so for now I don't want to worry about jamming the radio signal.

@Marquinio In that case why not just have just a magnetic reed switch connected to a buzzer? Standby would be next to nothing then.

I want to make a web GUI for the system where I can see the state of all the    door/window sensors.  I also want to be able to armed/disarm the system.  When its armed and triggered then the buzzer will be triggered.

Most alarm reed switches are NC (normally closed). So it will continuously pull the pin low. So you might need to get a higher value pull-up resistor, to lower the current going through the pull-up resistor. Or use an active-high topology.

You should use interrupts for the reed switch and then put the microcontrolller into sleep for a keep alive interval. Your master device should check that the sensor is still active and set off the alarm if its not. You would also want to allow for a battery low condition that might disable the alarm for convince. This still should keep the power consumption low.
The nano is roughly 1mA @ 3.3v while the CPU is running and 72uA when its in sleep. Discounting power consumption in the alarm condition triggered by the interrupt using an interval of 9 seconds using delay or interrupt timers then average consumption then about a second to wake up and send a keep alive over the RF. (0.000072 * 9 + 0.001 * 1) / 10 = 0.0001648 amps. (average over 10 second duty cycle)
My guesstimate of your RF power consumption without knowing what kind of protocol would be somewhere around 128 bytes per transmission taking about 90ms. (0.0001 * 9910 + 0.015 * 90) / 10,000 = 0.0002341 amps.
Total of their averages is: 0.0003989 or 398.9uA.
Alkaline AA cells vary widely. So instead based on some Ni-MH with 2400mAh per cell and 1.2v
3 cells would be 3.6v so you'll "get" most of the mAhs out of the batteries.
2400mAh = 2400000uAh
2400000uAh / 398.9uA ~= 6016.54 hours or 250 days or 8 months.
Power consumption were intentional overestimates. You should be able to make it last a lot longer.
https://www.avrprogrammers.com/howto/atmega328-power
http://harizanov.com/2013/05/nrf24l01-power-consumption-footprint/

Based on your calculations It gives me hope that this will work.  Now what you mean by "put the microcontroller into sleep"? Is this as simple as something like delay(2000) or something more complicated?  If more complicated can you please provide a link so I can follow those steps? Thanks.

It is a bit more complicated. https://playground.arduino.cc/Learning/ArduinoSleepCode and https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

I'll have to read and understand how interrupts work, no easy way around that.  I can now move forward with my project.  Thanks for your help!

It only seems to do one thing: activate an alarm if the reed switch changes.  Power the system through the reed switch. It will have zero standby current and the battery will last the shelf life. That said, you might be able to use an RF module w/o even a MCU, though not that particular one...

Thats pointless because if you jam the RF the sensor is useless. That would make a silly security system.

this is for a home security system. one theoretical attack doesn't make it pointless any more than the existence of locksmiths makes locking your door "pointless". If someone breaking into OP's house is jamming RF signals, they are going to get in one way or the other... Still you could for example, add a 110db alarm to the build and still get "infinite" standby, maybe even with a microphone sensor as an RF backup. Main point: in my experience, analog still beats digital for long-term reliability.

@jdwolf: what's to stop someone from spoofing the RF signal? If you authenticate, that's a ton of complexity to avoid replay attacks, schedule keys, not burn eeprom, etc. Try using a simple spark gap transmitter and a dollar-store AM radio as a detector: you can't jam a spark gap w/o setting off the receiver ;)

Nothing about my answer indicates that encryption wouldn't be used. Signal jamming includes intentionally blocking the signal or destroying the device between its broadcast intervals (which would be easily detectable on the cheapest of hardware) so even spark gap can't help you there. In any case "I'm still alive" style security is how professional security systems actually work.

This will be a basic home security system.  Once I can make the power last a long time I will beef it up and maybe add jamming protection, but for now I will probably have the Nano send an "I'm still alive" to the main HUB like jdwolf mentioned.

You should use a reed switch that is both NC and NO. Then power only the disconnected part of the switch and listen to pin changes and put everything into sleep. This can improve your power consumption. See the answers postet here: Low Power Pin Change Detection

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
How to remove the 5 second boot delay on Digispark PRO (Attiny167)
I know there’s already a solution for removing the 5 seconds boot delay on Digispark (Attiny85), by writing a new bootloader someone already did to the Digispark. And to write code to it, you need to ground one pin.
This delay exists so the Attiny85, when powered on, waits for USB programming. Only after 5 seconds it will run the code written to it..
But I can’t find information on how to remove this 5 second delay on the Attiny167 - Digispark PRO.
Could the same modified bootloader of the Attiny85 be burned on the 167?
Or is there any other way to do it?
Thanks a lot!

I don't see the delay in the code, only in the command line util. What bootloader are you using?

@DaveNewton I’m using the stock bootloader. The firmware of the Digispark Pro is 2.2. Everytime it powers on the internal led flashes for 5-6 seconds and only then any code written to it is executed. I’d like to power up the Digispark PRO and any code be executed imediatelly. Every Digispark PRO behaves this way, as far as I know. I don’t know if the correct name is delay, but when powered on, the board waits for this 5 seconds to check if any code is about to be written through the USB port. If not, it executes de code that was already uploaded to it.


text:
Is extra hardware and components needed to connect the bare MCU directly to a PCB, without a shield?
As a hobbyist I code in a variety of arduino's and in Digispark's (Attiny 85 and 167).
But I'm doing a project with space contraints, so I'd need to use just the MCU directly over my pcb.
Apart from a voltage regulator (to get the VIn to 5V or 3.3V) do I need extra components to mount the MCU to my PCB?
DO I need crystals, capacitors, etc? Or the MCUs (mostly AtMega 32u4 and Attiny85 and Attiny167) have it all what's needed inside them?
I'll program the MCU before soldering on to the PCB, so there's no need for USB or programming stuff or leds.
Thanks!

Why do you need the voltage regulator? All the MCUs you listed run at 5V, as far as I know. I'd suggest going to SMD components, as those are quite a bit smaller. Hand soldering them isn't that much harder than through-hole.

@Gerben I'll use a 7.4V battery as a power supply! Smd is the way I wan to go indeed

See the datasheet for the regulator you are going to use, to see what capacitors (values and types) it recommends. Then a 0.1µF capacitor right next to each Vcc pin on the MCU. I'd recommend at least putting test pads on the PCB for the programming pins, so when you do have to reprogram them, you can solder some wires to the test pads. Or get a SOIC Clip, if you are using the 8 pin ATTiny MCUs (but make sure there is enough clearance on the PCB for the clip to fit).

@Gerben. I´m planning on using an Attiny85. I liked your idea about the clip as a programmer in a soldered SOP8 Attiny. So, apart from having space around for the clip to be able to "attach" the clip to reprogram it, what else should I need besides the bare chip soldered to the PCB? Is that pull-up to the reset pin needed also? Thanks!

The external pull-up resistor on the reset pin isn't needed per see, but could cause issues in electrically noise environments. Some of my early boards didn't have one, but more recently I've been adding to my PCB. A single 0805 resistor doesn't take that much space. I'd advice to just add it, though I can really find any good rational for this, other than "everybody is doing it".

@gerber Understood! But what if I´m going to use all pins of the Attiny, inlcuding the PB5, would I still be able to use this pin normally as an Input/Output?

Yes, but I the reset pin has a internal pull-up resistor that you can't disable (AFAIK). So it's best to use it as an OUTPUT or INPUT that already requires an pull-up. But I feel like you are making it very difficult for yourself by selecting the ATTiny85, instead of an AVR with more pins.

@Gerben yes.... I know... it’s just because space constraints in my tiny pcb... and the ease of using arduino IDE to code for it..  but I’m still deciding which AVR to use...

DO I need crystals, capacitors, etc? Or the MCUs (mostly AtMega 32u4 and Attiny85 and Attiny167) have it all what's needed inside them?

You don't need a crystal if you use the internal clock of the MCU (which means setting the fuses right and compiling your code to expect the right clock frequency). However if you are using a direct USB interface (such as for the ATMega32U4) then you will need a crystal as the precise timing is required for USB to operate.
You will need capacitors. Decoupling capacitors on all the power pins are not optional and must be included.
You will need a pullup resistor on the RESET pin unless you have set the fuse to disable the RESET pin (not advisable since it will prevent ICSP programming in the future - but can be useful for low pin-count chips).

So, If I'm never going back to changing code after soldering, all I need is a decoupling capacitor on the 5V PIN of the MCU? Are there any other places I should use the capacitors? (I'll use a 7.4V Li battery as a power source, and a voltage regulator (which uses already two capacitors on Vin and Vout.)

You should be fine with that. You'd normally have a 10uF capacitor for a group of chips or where the power enters the board, but the regulator's capacitors will take care of that.

If you're doing ADC reading a capacitor on the AREF pin can help increase reading stability, but it's not required.


text:
Arduino ESP8266 communication
I saw two peculiar things while googling this subjects.

Sometimes Tx and Rx are connected directly despite the fact, that it works on different voltages, sometimes resistor dividor is used, sometimes it goes through resistor. Why no consensus? What are differences?
Why contributors are so stubborn to use software UART? Is there any reason I can't understand, that should stop me from using built in UART?

Sometimes Tx and Rx are connected directly despite the fact, that it works on different voltages, sometimes resistor dividor is used, sometimes it goes through resistor. Why no consensus? What are differences?

There is some uncertainty as to whether the ESP8266 has 5V tolerant inputs or not.  This uncertainty stems from differences in an early Chinese datasheet translated by the community, and the current English datasheet.  It's better to err on the side of caution though and translate your 5V signal from the Arduino to a 3.3V one with either a proper logic level translator or a resistive divider (note that the latter can limit the maximum baud rate you can use).
You can read more here:

https://hackaday.com/2016/07/28/ask-hackaday-is-the-esp8266-5v-tolerant/

Why contributors are so stubborn to use software UART? Is there any reason I can't understand, that should stop me from using built in UART?

Bad information begets bad information. People copy poor quality examples and tutorials and pass that bad knowledge on to others1.
Many Arduino boards only have one hardware UART port, and that is shared with the USB connection to the PC.  It is hard to reliably use that UART for other serial communication, since doing so will break your ability to upload code while your hardware is connected.  So it's simpler in that case to use SoftwareSerial (or one of the better implementations).
However, I would never advocate using SoftwareSerial unless you absolutely have to.  It barely functions at 115200 baud (one of the common default ESP8266 baud rates).  If you have a convenient hardware UART then really you must use it, for the sake of your sanity if nothing else.

1: Even worse though are the examples where people use SoftwareSerial to communicate over the pins of a hardware UART... that's just plain stupid...


text:
Initialization of function pointer array
I have an array of function pointers:
unsigned int dimension = 8;
void (* myFunctions [dimension])();

This array is a member of a class:
class myClass {

    static const unsigned int dimension;

    void (* myFunctions [dimension])();
}

and in a cpp file:
const unsigned int dimension = 8;

It's size is known at compile time, but it's values will be added through a public method in unknown parts of the code. I need to be able to find out at any time whether there is a valid pointer at some index in that array at any time, and my idea was to do that by comparing the pointer against nullptr: if it doesn't equals it then I'll assume that it holds a valid function pointer.
I was wondering if I need to initialize the array before making that kind of speculation. How is this array initialized if I only write the above two lines of code? Can I assume something like myFunctions[x] ==  nullptr is true in that case? Or do I need to do an explicit initialization like the following one?
for(int i = 0; i < dimension; i++)
    myFunctions[i] = nullptr;

Is this a global variable or within a class that is constructed or what? Could you provide a simple example of the source code in which this is used?

see also https://stackoverflow.com/questions/14071378/c-initialize-an-array-of-pointers-to-functions

@RichardChambers of course, I'll edit

You should actively zero-initialize your pointers in the constructor of your class.
The "zero-initialization" of the C++ language only applies in certain cases defined here. In certain configurations, e.g., when the object of the class has an explicit constructor which does not initialize the array, or when the class has no constructor and an object is function-locally created by typing myClass myObject;, the pointers are not initialized to nullptr.
They do get automatically zero-initialized via the C++ standard without you doing anything if an object of this class is declared and defined as a global variable, though. Then you have a "static storage location", and your object is zero-init'ed by zero-init'ing every data member. Your array of function pointers gets then member-wise zero-init'ed to the zero-value of a pointer, i.e., nullptr.
But you should write robust code which is always correct regardless of which kind of method is used to instantiate the object. Thus, the for loop in the constructor as you have it is correct.
See the analogous question I asked here (which I asked because I gave an initially wrong answer and felt responsible).


text:
Why don't these sketches produce a similar output?
I compiled the following two sketches with the compiler used by the Arduino IDE and ran them on an Arduino UNO (smd edition).
I'm using:

Arduino IDE v. 1.8.0
Arduino AVR Boards v. 1.6.20

1.
void setup() {

  Serial.begin(115200);
  unsigned long a, b;
  //unsigned long c, d;

  a = micros();
  for (unsigned long i = 0; i != 1000000; i++) digitalRead(13);
  b = micros();
  Serial.println(b - a);

  //c = micros();
  //for (unsigned long i = 0; i != 1000000; i++) digitalRead(13);
  //d = micros();
  //Serial.println(d - c);

}

void loop () {}

2.
void setup() {

  Serial.begin(115200);
  unsigned long a, b;
  unsigned long c, d;

  a = micros();
  for (unsigned long i = 0; i != 1000000; i++) digitalRead(13);
  b = micros();
  Serial.println(b - a);

  c = micros();
  for (unsigned long i = 0; i != 1000000; i++) digitalRead(13);
  d = micros();
  Serial.println(d - c);

}

void loop () {}

These were the outputs on the serial monitor:

2452320
3332640
 3332704

Why did each of the two for loops in the second sketch take roughly 33% more time to execute than the loop in the first one?

If you retry both tests, you get the same numbers as above?

@MichelKeijzers yes, I always get exactly the same numbers.

It would be helpful if you edited your question to state which version of the Arduino IDE you're using and which version of Arduino AVR Boards (shown in Tools > Board > Boards Manager).

@per1234 Arduino IDE 1.8.0, Arduino AVR Boards 1.6.20. I've just edited the question.

The different time implies different (number of) instructions being executed.  This is most probably due to the crappy GCC compiler optimizations.
In the former sketch, probably the compiler manages to use only registers, which are very fast. In the second one, the compiler THINKS it needs 8 more bytes, and there are no registers left, so it uses the stack (internal RAM) to store some variables, which is slower. (still, the optimizer should realize that in fact it don't need more bytes, because a and b are not used after the first println()). To access to a SRAM location, you need a LOAD/STORE operation, which takes a longer time, with respect to an operation between registers (beside having to load the memory address to X, Y o Z).
Probably, the compiler is even crappier, because, instead of putting the rarely-used variables a,b,c,d on the stack, it puts i (which is always incremented) or other variables used in digitalRead().
Still, to explain where is the trouble (i.e. where compiler fails in optimizing the register allocation/usage), you should disassemble the object code. Use for instance Atmel Studio, which still uses GCC, but has a good debugger, disassembler and cycle-exact analysis.
Still, this is very strange, perhaps optimizations were not enabled the platform.txt of your arduino?
EDIT:
Using Arduino 1.8.0, I tested the two sketches and analyzed the lss (generated using avr-objdump). The compiler optimizes a lot more the first code. Instead of making a CALL to digitalRead() (as it happens in the second sketch) it probably recognizes that such function is called only once on the code. Therefore it makes a rjmp to it. At the end of that function, there won't be a RET but a branch to the point where i is computerd and checked (actually i is not incremented, actually gets decremented and checked against 0).
In other words, even if the two codes are equal (except that the second sketch runs the same code twice), they are compiled (optimized) differently.

Are you sure you are using the same setup of the OP?

Finally I did a test. Actually I was wrong. It's not that GCC does not optimize the second sketch. Instead, it optimize a lot the first one (in my case, I'm using Arduino 1.8.0). Instead of making a CALL to digitalRead, it probably recognizes that digitalRead is called only once in the code, therefore it makes a rjmp to digital read, then from digitalRead goes back to the for loop, where it computes and checks i. (I'll edit the question. Edits will be visible for on the edit history, so the comments will still make sense).

@LookAlterno and next-hack: first of all, thanks for your interest in my question. But how do you look at the compiled program? I'd like to have a look myself to what you call the "generated code" and - if it can be useful - to provide the one produced by my compiler, but I actually don't know how to get it.

The Arduino IDE does not, by default, produce .lss files. You can produce them, by calling avr-objdump from the command prompt: avr-objdump -S -h yourElfFile.elf >destination.txt. You find avr-objdump in the following path: Arduino\hardware\tools\avr\bin (Where Arduino is the directory where you installed the IDE).
By the way, I also achieve exact common codes with Atmel Studio 7, but different codes with Arduino 1.8.0 (see answer). This is probably due to the different settings or different GCC version.

UECIDE's compilation methodology is somewhat different to Arduino's. It probably doesn't optimize in the same way because it compiles the different portions separately and archives them. Makes it harder for functions to be inlined or munged with rjmp instead of call. Also the compiler may be a different version (I haven't updated it in a while, maybe I'll check for a newer version today).


text:
How to use C++ user defined modules in Arduino
Does Arduino support C++ module import functionality i.e. what would it require to implement something like this in Arduino: import std;?

Modules are a C++20 feature. The configuration files (platform.txt) of
the cores provided by Arduino all ask the compiler to use one of the
standards gnu++11, gnu++14 or gnu++17. These are C++11, C++14 and C++17
with some GNU extensions.
You will not be able to use C++ modules with standard Arduino cores. You
will use the traditional header files instead. Optionally, you may build
“Arduino libraries” by following the corresponding specification.

@Edgar Bonet Understood. Thank you for your comment. AOB: It appears someone gave my question a down vote. Could this have anything to do with my question itself or with the way it was framed? Feedback could help improve my future posts.

BTW, as per libraries, what's your thoughts on using third party vector container libraries? I saw one of such libraries which the author claimed could function like (but slightly different from) native std::vector<T> library. However, from your personal experience, could this pose potential drawbacks? Thank you in advance.

@beebee: I have no experience with those. I tend to use statically allocated plain C arrays, in order to avoid memory issues with dynamically-allocated memory.

Thank you so much. I appreciate your response


text:
Arduino unable to read 0x41 and 0x42 (reads others just fine (ICT bill acceptor)
Here is my issue:
My code successfully recognizes and accepts $1 (0x40) and $20 bills (0x43), but it fails to recognize, display, process, anything for the $5 bill (0x41), and $10 bills (0x42). Also, when I say "Arduino", I mean TTGO btw...
I have verified that the bill acceptor is indeed sending the correct value (0x41) for the $5, and $10 (0x42) bills using an external monitoring tool like Docklight, and I used an oscilloscope too! All signals from all bill types were near identical and valid. However, the Arduino code does not seem to receive those two values (and ONLY those two values) at all... Meanwhile, it will display every other little thing there is... I have my code setup where it displays all incoming bytes, be it B.A. (bill acceptor) idle signals, rejection signals, everything, but it goes 100% blank, MIA, for 0x41 and 0x42... WHY?!?! So frick'n random...
===================================================
Just so you all know, this is how the bill acceptor (B.A.) works:

Insert a bill into BA
BA sends the corresponding HEX value (ex. 0x40) of the bill to my Arduino (Using RS232 cables and an RS232 to TTL converter (the converters are confirmed to be 100% operational BTW))
Once the Arduino "sees" the HEX value for a bill of N value, it will then send 0x02 to the BA to accept the bill.
If 0x02 is NOT sent to the BA within 5 seconds, then it will reject the bill and spit it back out the front.
Code then adds that value to "total count"

OFC, my code is setup where the only way an accept (0x02) signal is sent is IF 0x4N is received... So, the fact that 0x41 and 0x42 disappear into thin air means 0x02 is never sent so those two values are always rejected... Very, very, simple stuff, so the fact that it consistently is unable to ONLY NOT read 0x41 and 0x42 while clearly displaying all other sent HEX values is causing me unlimited headaches and conniptions... Programming... YAY! -_-
So, anyone... please, do you know what's going on? The signal is 100% being generated, and my code, below, is setup to display all incoming bytes, but it acts like 0x41 and 0x42 do not exist at all! Nothing. Nada. Zilch. WTF? It literally handles everything I can throw at it... except 0x41 and 0x42!!! FUUUUUUUUUUUU!!! So mad...
HERE IS THE ICT RS232 PROTOCL FOR MY BILL ACCEPTOR - http://tdmegalit.ru/upload/iblock/401/ict_protocol.pdf
ALSO, I HAVE ALL DIP SWITCHES CORRECTLY SET, POWER SUPPLY IS PERFECT, ALL WIRES ARE TESTED AND PERFECT, RS232 TO TTL CONVERTERS ARE PERFECT. I GUESS IT IS SOFTWARE SERIAL, OR THE TTGO
So with all that said, below is my code. It is a part of a much great whole of a program, so to remove the possibilities of the rest of the code causing the error, I reduced it to what you see below, but the problem persist... bruh
Also, I have included the Serial Monitor LOG. The LOG below shows startup, and then a 1, 5, 10, and 20 dollar bill being inserted...
SERIAL MONITOR LOG:
PLZ NOTE, I ADDED SPACES TO SHOW WHATS GOING ON...
====================================================================

... Received: 0x80       //IDLE SIGNALS (BA POWERED ON BEFORE "SETUP" SENT)
... Received: 0x8F
... Received: 0x80
... Received: 0x8F
... Received: 0x80
... Received: 0x8F

SETUP - ...Sent: STX     //SETUP TO INITALIZE BA
SETUP - ...Sent: DLE
SETUP - ...Sent: ETX
=======================
                         //INSERTED $1 (0x40) SUCCESS!!!
... Received: 0x40
$1 accepted
... Sent: 0x02
... Received: 0x10
                         //INSERTED $5 and 5 seconds later 0x29>>0x29>>0x2F = Rejection
... Received: 0x29
Bill rejected
... Received: 0x29
Bill rejected
... Received: 0x2F
                         //INSERTED $10 and 5 seconds later 0x29>>0x29>>0x2F = Rejection
... Received: 0x29
Bill rejected
... Received: 0x29
Bill rejected
... Received: 0x2F
                         //INSERTED $20 (0x43) SUCCESS!!!
... Received: 0x43
$20 accepted
... Sent: 0x02
... Received: 0x10

BILL ACCEPTOR CODE:
#include <SoftwareSerial.h>

SoftwareSerial BA(32, 33);  // RX, TX

int billCounter = 0;

void setup() {
  Serial.begin(9600);
  BA.begin(9600);
  delay(3000); //WAIT BC TRESH

  BA.write(0x02); // Send the initialization command (STX)
  Serial.println("SETUP - ...Sent: STX");
  BA.write(0x10); // Send the command to enable the bill acceptor
  Serial.println("SETUP - ...Sent: DLE");
  BA.write(0x03); // Send the end of text character (ETX)
  Serial.println("SETUP - ...Sent: ETX");
  Serial.println("=======================");
}

void loop() {
  if (BA.available()) {
    byte receivedByte = BA.read();
    Serial.print("... Received: 0x");
    Serial.println(receivedByte, HEX);

    if (receivedByte == 0x29) {
      delay(200);
      Serial.println("Bill rejected");
      // Handle bill rejection here (e.g., display message or perform necessary actions)

    } else if (receivedByte == 0x40) {
      delay(200);
      Serial.println("$1 accepted");
      BA.write(0x02); // Send the HEX value 0x02 to accept the bill
      Serial.println("... Sent: 0x02");

      // Increment the counter by $1
      billCounter += 1;

    } else if (receivedByte == 0x41) {
      delay(200);
      Serial.println("$5 accepted");
      BA.write(0x02); // Send the HEX value 0x02 to accept the bill
      Serial.println("... Sent: 0x02");

      // Increment the counter by $5
      billCounter += 5;

    } else if (receivedByte == 0x42) {
      delay(200);
      Serial.println("$10 accepted");
      BA.write(0x02); // Send the HEX value 0x02 to accept the bill
      Serial.println("... Sent: 0x02");

      // Increment the counter by $10
      billCounter += 10;

    } else if (receivedByte == 0x43) {
      delay(200);
      Serial.println("$20 accepted");
      BA.write(0x02); // Send the HEX value 0x02 to accept the bill
      Serial.println("... Sent: 0x02");

      // Increment the counter by $20
      billCounter += 20;

    } else if (receivedByte == 0x44) {
      delay(200);
      Serial.println("$50 accepted");
      BA.write(0x02); // Send the HEX value 0x02 to accept the bill
      Serial.println("... Sent: 0x02");

      // Increment the counter by $50
      billCounter += 50;

    } else if (receivedByte == 0x45) {
      delay(200);
      Serial.println("$100 accepted");
      BA.write(0x02); // Send the HEX value 0x02 to accept the bill
      Serial.println("... Sent: 0x02");

      // Increment the counter by $100
      billCounter += 100;
    }
  }
}

looks like the bill validator is rejecting the 10 and the 5

@jsotola It is not though. As you can see, for 1 and 20, it shows 0x40 and 0x43 when the bill is inserted. Meanwhile, absolutely nothing appears for 5 and 10 and it is automatically rejected after 5 seconds... Again, I have confirmed that 5 and 10 dollar bills do indeed send a hex value but my code shows nothing for only 5 and 10 dollar bills fuuuuu

The default for Arduino Serial  is 8 data bits, no parity, one stop bit. The first page of your linked documents says:
Start bit 1, Data bit 8, Parity bit Even, Stop bit 1. The mismatched parity parameter could explain a partial failure of this. Look at (Software) Serial begin() method to change this.

@6v6gt, you should make it an answer.

The default for Arduino Serial is 8 data bits, no parity, one stop
bit. The first page of your linked documents says: Start bit 1, Data
bit 8, Parity bit Even, Stop bit 1. The mismatched parity parameter
could explain a partial failure of this communication. The
documentation for the Serial begin() method describes the various
configuration options.
However, see also this thread:
https://forum.arduino.cc/t/altsoftserial-how-to-change-parity-solved/668535
It appears that the various software serial libraries do not support
EVEN parity settings. Use a hardware serial port on your TTGO Arduino
instead. This may mean using SoftwareSerial for the debug printing
(maybe with a USB/UART adapter) and dedicating the hardware serial
port to your bank note reader.

Thank you 6v6gt! Using HardwareSerial was the answer and setting the parity bit to EVEN was the answer too :D Here is what I did to fix it if anyone ever needs to see this answer in the future...
Also note, here is the logic:
The default for hardware serial is SERIAL_8N1, but I needed to use SERIAL_8E1 for the even parity because:
SERIAL_8N1 means "8" bits, "N"o parity, and "1" stop bit (hence 8N1)
SERIAL_8E1 means "8" bits, "E"ven parity, and "1" stop bit (hence 8E1)
Here is the chart I used to get the protocol format I needed:
/* Baud-rates available: 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 115200, 256000, 512000, 962100
 *
 *  Protocols available:
 * SERIAL_5N1   5-bit No parity 1 stop bit
 * SERIAL_6N1   6-bit No parity 1 stop bit
 * SERIAL_7N1   7-bit No parity 1 stop bit
 * SERIAL_8N1 (the default) 8-bit No parity 1 stop bit
 * SERIAL_5N2   5-bit No parity 2 stop bits
 * SERIAL_6N2   6-bit No parity 2 stop bits
 * SERIAL_7N2   7-bit No parity 2 stop bits
 * SERIAL_8N2   8-bit No parity 2 stop bits
 * SERIAL_5E1   5-bit Even parity 1 stop bit
 * SERIAL_6E1   6-bit Even parity 1 stop bit
 * SERIAL_7E1   7-bit Even parity 1 stop bit
 * SERIAL_8E1   8-bit Even parity 1 stop bit
 * SERIAL_5E2   5-bit Even parity 2 stop bit
 * SERIAL_6E2   6-bit Even parity 2 stop bit
 * SERIAL_7E2   7-bit Even parity 2 stop bit
 * SERIAL_8E2   8-bit Even parity 2 stop bit
 * SERIAL_5O1   5-bit Odd  parity 1 stop bit
 * SERIAL_6O1   6-bit Odd  parity 1 stop bit
 * SERIAL_7O1   7-bit Odd  parity 1 stop bit
 * SERIAL_8O1   8-bit Odd  parity 1 stop bit
 * SERIAL_5O2   5-bit Odd  parity 2 stop bit
 * SERIAL_6O2   6-bit Odd  parity 2 stop bit
 * SERIAL_7O2   7-bit Odd  parity 2 stop bit
 * SERIAL_

CODE SOLUTION:
#include <HardwareSerial.h>

HardwareSerial BA(1);  // Use Hardware Serial on TTGO

void setup() {
  Serial.begin(9600);
  BA.begin(9600, SERIAL_8E1, 32, 33);  // (Baud rate, Protocol, RX, TX)
  ...  //rest of my code

The default for Arduino Serial is 8 data bits, no parity, one stop bit. The first page of your linked documents says: Start bit 1, Data bit 8, Parity bit Even, Stop bit 1. The mismatched parity parameter could explain a partial failure of this communication. The documentation for the Serial begin() method describes the various configuration options.
However, see also this thread: https://forum.arduino.cc/t/altsoftserial-how-to-change-parity-solved/668535
It appears that the various software serial libraries do not support EVEN parity settings. Use a hardware serial port on your TTGO Arduino instead. This may mean using SoftwareSerial for the debug printing (maybe with a USB/UART adapter) and dedicating the hardware serial port to your bank note reader.


text:
Parent class callback from child class
I want the Parent class to pass a pointer to a callback function to the child class when the child class is created. I got this working when the parent was the sketch thanks to this post:
In this example, the parent was the .ino file, i.e. not a class but a collection of functions. This code worked fine.
However, I need to be able to make the call to the child constructor from a within a class as shown in the code below. I get I get an "invalid use of non-static member function on the line child = new Child ( handlerDispatcher );
Here is the complete code:
class Child {
public:
    typedef void ( *callback_t ) ( uint8_t, uint8_t );

    callback_t callback;

    //  Constructor
    Child ( callback_t _callback ): callback ( _callback ) {}

    void doCallback ( uint8_t id, uint8_t index ) {
        callback ( id, index );
    }

    void makeCallbacks () {
        doCallback ( 1, 0 );
        doCallback ( 2, 1 );
        doCallback ( 3, 2 );
    }
};

class Parent {
public:
    Child *child;

    Parent () {}

    void handlerDispatcher ( uint8_t id, uint8_t index ) {
        ( this->*callbackHandlers [ index ] ) ( id );
    }

    typedef void ( Parent:: *handlerPointer ) ( uint8_t );
    handlerPointer callbackHandlers [ 3 ] = {
        &Parent::handler1,
        &Parent::handler2,
        &Parent::handler3,
    };

    void handler1 ( uint8_t index ) { echo ( index ); }
    void handler2 ( uint8_t index ) { echo ( index ); }
    void handler3 ( uint8_t index ) { echo ( index ); }
    void echo ( uint8_t value ) {
        Serial.print ( "Got: " );
        Serial.println ( value );
    }

    void configure () {
        child = new Child ( handlerDispatcher );

    }
    void test () {
        child->makeCallbacks ();
    }
};

Parent parent;
void setup () {
    Serial.begin ( 115200 );
    parent.configure ();
    parent.test ();
}

void loop() {}

Use virtual functions. On object of type Child, fnc2 defined in Parent will call fnc1 of class Child:
class Parent {
public:

  virtual void fnc1() {
  }

  void fnc2 {
    ...
    fnc1();
    ...
  }
}

class Child : public Parent {
public:
  virtual void fnc1() {
    ...
  }
}

For the child drop the virtual and append a final - unless you want to have grandchildren.  Also you could make the parent's fnc1() pure virtual.

@Majenko, and then I would have to explain it :-)

I have expanded my answer to do just that.

It is because
void Parent::handlerDispatcher ( uint8_t id, uint8_t index )

is not
void ( *callback_t ) ( uint8_t, uint8_t )

The closest equivalent would be:
void ( *callback_t ) (Parent *, uint8_t, uint8_t )

Though I am not sure off hand if that is even possible.
But it seems you are trying to do something insanely convoluted and complex which would be made far simpler if you just used object inheritance and forget about callbacks.
With object inheritance a child object can implement the functions that a parent object defines. That way you end up with a single object instance which is a combination of the parent functions and the child functions, one overlaid on the other.
To build on Juraj's excellent answer and add a bit of explanation, if you take the following parent object:
class Parent {
public:

  virtual void fnc1() = 0;

  void fnc2 {
    fnc1();
  }
};

What we have here are two functions in the parent.  fnc2() simply calls fnc1() as an example.  However fnc1() isn't a normal function - it's a pure virtual function. That is akin to an interface in Java. It's a placeholder in the parent that says "This function will exist, but the child will implement it, not me".  If you try and instantiate a Parent object the compiler will complain that certain functions are pure virtual and the object can't be created.
So then you create a child class which takes the parent class and extends it with the body of any pure virtual functions that are needed, and can also add more.  For example:
class Child : public Parent {
public:
  void fnc1() final {
    ...
  }
};

Here we only have one function - fnc1(), which is marked as final.  The final keyword is kind of the opposite of the virtual keyword.  virtual means "This function will be overridden by the child". final means "I have overridden this, and nothing else can now override it". It's not essential, but it does help with the compiler's optimiser somewhat, since it no longer needs to worry about further inheritance of that function.
So now you can create a Child instance, and you will have access to all the parent functions and data, as well as all the child functions and data.  Simply calling fnc2() on this child instance will call that function on the parent, which then itself calls fnc1() which is implemented by the child.
And thanks to something called polymorphism, the child can be seen as a parent for all intents and purposes (though if you look at it as a parent you won't see any of the child's own functions).
To wrap it all up, here's a full example that uses two different child classes and stores pointers to them in an array of parents (so the children are seen as if they are objects of class Parent), iterates through them, and calls the parent's fnc2() function:
class Parent {
    public:
        virtual void fnc1() = 0;
        void fnc2() {
            fnc1();
        }
};

class Child1 : public Parent {
    public:
        void fnc1() final {
            Serial.println("I am child 1");
        }
};

class Child2 : public Parent {
    public:
        void fnc1() final {
            Serial.println("I am child 2");
        }
};

Child1 c1;
Child2 c2;

Parent *objects[2] = {
    &c1, &c2
};

void setup() {
    Serial.begin(115200);
    for (int i = 0; i < 2; i++) {
        objects[i]->fnc2();
    }
}

void loop() { }

The serial output from that program is:
I am child 1
I am child 2

Which I think is the end effect that you are looking for.


text:
ESP-WROOM-02 with on-board 18650 battery. How to charge it?
I have a ESP-WROOM-02 module with on-board 18650 battery. V+ and GND are exposed on the board.
Can I directly charge the battery using an USB-C connector with the two cables (red and black) directly soldered to the battery poles on the board?

The lithium battery must be charged by a specialized CC/CV control chip. The module in question already has one, namely a TP5400, sitting between the mounted micro-USB connector and the 18650 battery holder. You should use the same USB connector for both programming the MCU and charging the battery.

thanks for your answer! :)
i was suppousing that wasn't possible to charge in that way!
Thanks again!


text:
Arduino Uno "Keyboard Not Found"
This is my first script written with Arduino. I wrote a simple Hello World program but I'm getting the following error.
Test:18: error: 'Keyboard' not found. Does your sketch include the line '#include <Keyboard.h>'?
   Keyboard.begin();
   ^
exit status 1
'Keyboard' not found. Does your sketch include the line '#include <Keyboard.h>'?

Here is the code:
#include "Keyboard.h"

void typeKey(int key)
{
  Keyboard.press(key);
  delay(50);
  Keyboard.release(key);
}

void setup()
{
  // Begining the Keyboard stream
  Keyboard.begin();

  // Wait 500ms
  delay(500);

  delay(400);

  Keyboard.print("Hello World!");

  // Ending stream
  Keyboard.end();
}

void loop() {}

I have Arduino/Genuino UNO selected as my board on the IDE. Any suggestions on how I can fix this? Thanks

Are there tutorials with the same board? Have you tried code that is verified to be working on other boards (from other tutorials)?

Based on the documentation :

These core libraries allow a 32u4 based boards or Due and Zero board to appear as a native Mouse and/or Keyboard to a connected computer.

Core libraries (such as Keyboard.h) are not availabe if your board doesn't mentioned.
I don't know which one is right, since your question title mentioned "Arduino Micro" while at the end of your question, the board is "Arduino Uno".
Just for further information, Arduino Uno is based on - ATmega328P, and Arduino Micro is based on - ATmega32U4. So sure, that "hello world" program will works on Arduino Micro, but not on Arduino Uno.

On the Arduino Get Started Page it says for the Arduino Micro in order to program it I need to select Arduino/Genuino UNO as my board thats why I added it at the end. My actual device is the Arduino Micro

Well, how about look at this "Get Started Page" instead : https://www.arduino.cc/en/Guide/ArduinoLeonardoMicro go to Select your board parts, and have fun


text:
Reading RAM from SH1106 OLED Controller through I2C
Summary: I'm having trouble with writing a program to get RAM data from an SH1106 OLED controller via i2c. In the first part of the question I've written the assumptions I've made to get informations I couldn't find in the datasheet, in the second part I've posted a program which should read that data but doesn't (obviously, since I'm writing here...).

I'm working on a program to control an SH1106 OLED display. I read the datasheet to find out how to send commands to it and it works, I can write to my display.
Now in the datasheet there is one thing I don't understand: how can I read the RAM?
Consider the picture below, taken from the command table at pages 30 and 31 of the SH1106 datasheet; the last line is the one about reading RAM.
This chip can be connected to a microcontroller through different interfaces: 6800 and 8800 8-bit parallel, 3 and 4 wire SPI and i2c. Since I'm using SPI I don't have any A0, RD or WR pin, and I didn't found anywhere in the datasheet a "translation" of the boolean value given to those signals in the command table to some i2c signal. I assume that WR corresponds with the lsb of the i2c address, since it is 0 for writing and 1 for reading. And my assumption seems to be true since I can read the status (line 25).
Then I assumed that A0 should match DC (Data/Command, see second screenshot), a bit of the Control byte. The control byte is a byte that has to be sent before each byte or group of bytes to tell the chip how to interpret it (command or data). But I tried to send it before an i2c reading with different values and I always get the status byte (never the RAM data).
How could I read the memory of an SH1106 chip through i2c? The datasheet doesn't states that it is impossible (neither that it is possible...), maybe I simply can't?
Command table

(I removed lines 1-16, which contain commands like those at lines 17-23)

Control byte

EDIT
Here is the shortest working program I could write which shows the problem (i.e. which contains my implementation errors). I tested it on an Arduino UNO.
#define ADDR  0x78

void i2c_start() {
  TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));
}

void i2c_stop() {
  TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
}

void i2c_send(uint8_t data) {
  TWDR = data;
  TWCR = (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));

}

uint8_t i2c_read(bool isLastByte) {

  if (isLastByte) TWCR = (1 << TWINT) | (1 << TWEN);
  else TWCR = (1 << TWEA) | (1 << TWINT) | (1 << TWEN);
  while (!(TWCR & (1 << TWINT)));
  return TWDR;
}

void display_init() {
  i2c_start();
  i2c_send(ADDR);
  i2c_send(0x00); //................ control byte
  i2c_send(0xAE); //................ displayOff
  i2c_send(0x8D); //................   *
  i2c_send(0xD5); i2c_send(0x80); // clockFrequency
  i2c_send(0x32); //................ pumpVoltage0123
  i2c_send(0xA1); //................ segmentRemap
  i2c_send(0xC8); //................ flipVertically
  i2c_send(0xDA); i2c_send(0x12); // comConfiguration
  i2c_send(0xA8); i2c_send(0x3F); // multiplex
  i2c_send(0xD3); i2c_send(0x3F); // displayOffest
  i2c_send(0x10); i2c_send(0x00); // columnAddr
  i2c_send(0x40); //................ startLine
  i2c_send(0xB0); //................ pageAddr
  i2c_send(0xAF); //................ displayOn
  i2c_stop();
}

void setup() {

  // Initialization
  Serial.begin(115200);
  display_init();

  // Request RAM data
  i2c_start();
  i2c_send(ADDR);
  i2c_send(0x80); //   control byte
  i2c_send(0xB0); // page address
  i2c_send(0x80); //   control byte
  i2c_send(0x10); // column address high
  i2c_send(0x80); //   control byte
  i2c_send(0x00); // column address low
  i2c_send(0x40); //   control byte
  i2c_send(0xE3); // nop
  i2c_stop();

  // get RAM data
  uint8_t a[10];
  i2c_start();
  i2c_send(ADDR + 1);
  for (int i = 0; i < 9; i++) a[i] = i2c_read(false);
  a[9] = i2c_read(false);
  i2c_stop();

  // print results
  for (int i = 0; i < 10; i++) {
    Serial.print("0x");
    Serial.println(a[i], HEX);
  }

}

void loop() {}

I've tried as many possibilities as I could imagine in the // Request RAM data section. To avoid confusion I leave only the posted one to your kind analysis, but of course if someone would like to see them just write it in a comment and I'll post all the (unsuccessful) test I have made.
The output on the serial monitor is always a list of 0x3s.
I've not reduced the initialisation routine I use in my code because maybe the issue comes from there. BTW, I have no idea about what the i2c_send(0x8D); //................   * line does, I've added it because all the others SH1106 libraries I found had it, but I didn't found it in my datasheet. Maybe there are multiple versions of the chip or of the datasheet?

My version of the data sheet has a flowchart (Figure 10) for doing a "read-modify-write".  In there is a clue - there has to be a dummy read before the actual read is done.  Here is my function for plotting a pixel, which requires a read-modify-write to add a pixel to the existing data.  It's not clear dummy read is needed before every byte read, or just on the first of a sequence of bytes, but that's easy enough to test.
#define CTRL_LAST_CMD 0x00
#define CTRL_NEXT_CMD 0x80
#define CTRL_LAST_RAM 0x40
#define CTRL_NEXT_RAM 0xC0

void MySH1106_PlotPixel(char x, char y, char on) {
  unsigned char curDisp;
  MySH1106_SetPage(y/8);
  MySH1106_SetCol(x);

  Wire.beginTransmission(SLAVE_ADDR);
  Wire.write(CTRL_LAST_CMD);
  Wire.write(0xE0); //R-M-W enable
  Wire.endTransmission(1);

  Wire.beginTransmission(SLAVE_ADDR);
  Wire.write(CTRL_LAST_RAM);
  Wire.endTransmission(1);

  Wire.requestFrom(SLAVE_ADDR, 2, 1);
  while(Wire.available()<2);
  curDisp = Wire.read(); //dummy read
  curDisp = Wire.read(); //real read.

  Wire.beginTransmission(SLAVE_ADDR);
  Wire.write(CTRL_LAST_RAM);
  if (on) {
    Wire.write((0x1<<(y%8)) | curDisp);
  } else {
    Wire.write(~(0x1<<(y%8)) & curDisp);
  }
  Wire.beginTransmission(SLAVE_ADDR);
  Wire.write(CTRL_LAST_CMD);
  Wire.write(0xEE);//end R-M-W
  Wire.endTransmission(1);

}

This is woefully inefficient for plotting one pixel, but it's a start.
Edit: I've subsequently confirmed that only 1 byte of dummy read is needed, even if the reads are stopped/restarted.  As long as you're only doing RAM reads, no further dummy reads are needed.

It's slightly tricky understanding the protocol with I2C.  The bit to watch is:

If the R/ W bit is set to one in the slave-address, the chip will output data immediately after the slave-address according to the D/C bit, which was sent during the last write access. If no acknowledge is generated by the master after a byte, the driver stops transferring data to the master.

So you have to set the D/C bit in the transaction before you want to access the RAM.
It's unclear from the datasheet if you have to send a data byte after the control byte for it to be accepted, but if you do you can use the NOP command.
So you do a write of NOP with D/C (which, yes, corresponds to A0 in the other interfaces) set to 1 in the control byte (i.e., write the bytes 0x40 0xE3) and then you can do a read which should return the RAM contents at the current page/column address, which will auto-increment for each subsequent byte.
It's quite an unclear datasheet when it comes to explaining how I2C reading works...

Thank you for your answer. I've tested it (in particular I hadn't considered using a NOP after the 0x40 control byte), but I'm still unable to read the data. I've edited my question adding the shortest code I could write which still contains and shows the problem.