text:
Arduino program to scan two different rfid cards in same program ? Im using nodemcu- esp8266 , rc522 reader and Firebase
/*My project is a Library management system using rfid cards. Im trying to generate a code wherein User first scan a book and then the record will be pushed in Issued_Books table in Firebase . Then the user scans his id to ensure that the book will be issued on his/her id.
But in my program is scanning only books id. It fails to scan users Id after that. Im a beginner so can anyone guide me? */
//My loop code is as following:
void loop() {

  if ( !mfrc522.PICC_IsNewCardPresent() ) {
    delay(50);
    return;
  }

  if ( !mfrc522.PICC_ReadCardSerial() ) {
    delay(50);
    return;
  }
String book;

  for ( byte i = 0; i< mfrc522.uid.size; i++ ) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    book.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    book.concat(String(mfrc522.uid.uidByte[i], HEX));}
    book.toUpperCase();

    Firebase.pushString("Issued_Books/Book_rfid",book);

      Serial.println();

  if ( !mfrc522.PICC_IsNewCardPresent() ) {
    delay(50);
    return;
  }

  if ( !mfrc522.PICC_ReadCardSerial() ) {
    delay(50);
    return;
  }
  String user;

  //Serial.print("Scan your id: ");
    for ( byte i = 0; i< mfrc522.uid.size; i++ ) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    user.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    user.concat(String(mfrc522.uid.uidByte[i], HEX));}
    user.toUpperCase();
    //Serial.print(F("Card UID: "));
    Firebase.setString("Issued_Books/Book_rfid/user_rfid",user);

    delay(3000);
}

also look into sprintf to get hex formatting
(I dont have these libraries so I cannot test, this is all written in stackexchange editor, so I might have a typo somewhere)
unsigned long startScanTime;
bool GotBookId = false, GotUserId = false;
void loop() {
GotBookId = false;
GotUserId = false;

  if ( !mfrc522.PICC_IsNewCardPresent() ) {
    delay(50);
    return;
  }

  if ( !mfrc522.PICC_ReadCardSerial() ) {
    delay(50);
    return;
  }
String book;

  for ( byte i = 0; i< mfrc522.uid.size; i++ ) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    book.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    book.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
    book.toUpperCase();
    if(book != "")
       GotBookId = true;

    Serial.println("Got Book");

startScanTime = millis(); //timeout look to get user card
  while( !mfrc522.PICC_IsNewCardPresent() && (millis() - startScanTime < SCAN_TIMEOUT) ) {
   //do nothing but wait
  }

  if(!mfrc522.PICC_IsNewCardPresent())
  { //did not get the user id, return from loop
      return;
  }
  if ( !mfrc522.PICC_ReadCardSerial() ) {
    return; //should never hit this if library works correctly
  }
  String user;

  Serial.print("Scan your id: ");
    for ( byte i = 0; i< mfrc522.uid.size; i++ ) {
    Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
    Serial.print(mfrc522.uid.uidByte[i], HEX);
    user.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    user.concat(String(mfrc522.uid.uidByte[i], HEX));}
    user.toUpperCase();
    //Serial.print(F("Card UID: "));
    GotUserId = true;

   if(GotBookId && GotUserId){
       Firebase.pushString("Issued_Books/Book_rfid",book);
       Firebase.setString("Issued_Books/Book_rfid/user_rfid",user);
   }
}

Thanks for the reply , but actually even this code is encountering the same problem. After first scan the code eventually pushing same rfid as a 'book' and 'user' in the firebase where I want the user to scan a book whose rfid will be stored in firebase then user will scan his id and an user id will be set for that particular book.

Every book will be issued by a particular user ..so user id should be stored each time differently for that particular book . I mean 1 book rfid will have 1 user rfid. but due to setString(); each time it only updates previous id . Any solution for above problems?

I have not worked with Firebase so I am not familiar with their API, but a 10 second google query lead me to here which cites the update method you should be using instead of the set string
https://firebase.google.com/docs/database/admin/save-data

thanks but Im confused how to do it in firebase arduino. I mean through C Programming

have you tried something like Firebase.setString(String("Issued_Books/Book_rfid/") + String(book) + String("/user_rfid"),user);


text:
Why would using the += operator on an unsigned long crash my sketch?
I wrote a simple Timer class that's designed to work even in the face of the 49 day wrap of the millis() counter. I wanted a library that I could easily re-use and I could never remember the right way of dealing with the wrap-around so I thought: do it once, right. However, it has not gone according to the script!
Here's the source code, header first.
class Timer
    {
public:
    Timer();
    void SetDuration(unsigned long duration);
    bool Expired();
    unsigned long Elapsed();
    unsigned long Remaining();
    void Repeat();
    bool Enabled();
    void Stop();
private:
    unsigned long startedAt;
    unsigned long interval;
    };

...and the implementation...
#include "Timer.h"

Timer::Timer()
    {
    startedAt = 0;
    interval = 0;
    }

/*
 * Sets the timer interval and establishes the reference datum as the instant when this method was called.
 */
void Timer::SetDuration(unsigned long duration)
    {
    startedAt = millis();
    interval = duration;
    }

unsigned long Timer::Elapsed()
    {
    if (!Enabled())
        return 0UL;
    unsigned long elapsed = millis() - startedAt;
    return elapsed;
    }

unsigned long Timer::Remaining()
{
    return interval - Elapsed();
}

bool Timer::Expired()
    {
    return Enabled() ? Elapsed() >= interval : false;
    }

/*
 * Repeats the timer interval but does not reset the reference datum.
 * This should be used when repeatedly timing the same interval, and it is
 * intended that the intervals be consistent _on average_.
 */
void Timer::Repeat()
    {
    startedAt += interval;
    }

bool Timer::Enabled()
{
    return interval > 0;
}

void Timer::Stop()
{
    interval = 0;
}

Now my problem is this. My sketch gets to a certain point then crashes (re-runs from the start). The behaviour seems a lot like an odd stack corruption that's causing the code to branch to Oblivion. I've spent several hours doing a binary-chop on the code to narrow down the cause (it's a big sketch) and much to my surprise, the culprit appears to be the Repeat() method in my timer class. I use it in just one place in my code. When I call the Repeat() method, it crashes my sketch; If I don't call Repeat() but instead call SetDuration(n), the program doesn't crash and everything is fine. I've tried this in two different sketches with consistent results.
I've got spots before my eyes from trying to understand what's happening here. I'm a C# programmer most of the time although I'm not completely new to C and C++, but I've made dumb mistakes in Arduino code before. Repeat() could hardly be simpler or safer code - but is it? Is there anything wrong with my code that I'm just not seeing?
UPDATE: Stack Overflow effect (where you see the solution yourself as soon as you post a question) has kicked in and I've solved it. My implementation of Repeat() was moving startedAt ahead of millis() giving a negative amount of elapsed time (which in unsigned math means a very large positive amount of elapsed time). This was causing immediate time-out of the timer and causing the sketch to think the sky was falling in. So not a memory corruption, just some poorly implemented unsigned math.

gets to a certain point what point? how long? Can you provide some code that uses your whatever it is and demonstrates the issue

@JaromandaX Stack Overflow effect (where you see the solution yourself as soon as you post a question) has kicked in and I've solved it. My implementation of Repeat() was moving startedAt ahead of millis() giving a negative amount of elapsed time (which in unsigned math means a very large amount of elapsed time). This was causing immediate time-out of the timer and causing the sketch to think the sky was falling in.

Indeed - I hate it when MCU's think the sky is falling :p I had similar effect after approximately 50 days when millis "overflows"

You can answer your own question and accept it. That helps mark it as answered and may help future visitors find the solution to this issue.

source: Stack Exchange

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

sort: votes


text:
How to access GPS location without internet
I need to provide a basic geolocation service for my clients. I built a location service based on the phone geolocation. It works great, not a problem. My problem is that some of my clients don't have an internet connection.
I know there is a company like Geotab that can provide these types of services.
If I want to build my own (very basic one), how can I make my DIY (Arduino based) GPS communicate with my web servers?

If you want communication with servers you will need internet, what you can do is use some wireless communication protocol take data at the at the gateway and then send the data on the web servers

It is possible to derive approximate locations of users from the WIFI they're currently using, but that requires a big database, such as what google has. Unlikely you can do something similar in an own project. The same applies for locating using IP addresses, which on top of it gives only very broad results.

"some of my clients doesn't have internet connection." - As you want to send data to webservers on the internet, you need to get a connection to the internet. Please explain more about the circumstances. Is the "geolocation service", that you want to provide limited to a specific area?

If you want to send data to a server on the internet, you will need an internet connection, or at least a connection to a internet gateway.
Which type of connection you use, and how you set up that connection, depends on distance, speed, and coverage you need.
Probably the most universal for your application, in the sense that it will work wherever a phone would work, is to use a GSM/GPS module with an Arduino. You can google around for such modules; there are many. Note that you will need a SIM card for every module you use.
The GSM-bit of the module can then be used as a modem to communicate with your server over TCP/IP. There are many examples showing how to do that on the interwebs, so I won't go there.
If this doesn't help you enough, please add more detail to your question and I will edit the answer.

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


text:
RTC DS3231 headache
I've been trying to get an RTC clock to display time. I tried using 3 different RTC modules: standard ds1307, pcf8523 and ds3231.
They all give the same results: wrong time and no incrementing. It does not matter if I manually insert a timestamp or if it gets it at compile time.
I am using using a Feather Adalogger and an MPU6050 accelerometer. The battery is good and the connections have been verified. It's as if there is some value in some memory somewhere that reverts to the timestamp below.
Here's the code:
#include <RTClib.h>
#include <Wire.h>

RTC_DS3231 rtc;

char t[32];

void setup() {
  Serial.begin(9600);
  Wire.begin();
  rtc.begin();
  rtc.adjust(DateTime(F(__DATE__),F(__TIME__)));
  //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop() {
  DateTime now = rtc.now();
  sprintf(t, "%02d:%02d:%02d %02d/%02d/%02d",  now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());
  Serial.print(F("Date/Time: "));
  Serial.println(t);

  delay(1000);
}

Here's the printout:
Date/Time: 00:35:00 04/00/2020
Date/Time: 00:35:01 04/00/2020
Date/Time: 00:35:02 04/00/2020
Date/Time: 00:35:03 04/00/2020
Date/Time: 00:35:00 04/00/2020
Date/Time: 00:35:01 04/00/2020
Date/Time: 00:35:00 04/00/2020
Date/Time: 00:35:01 04/00/2020
Date/Time: 00:35:02 04/00/2020
Date/Time: 00:35:03 04/00/2020
Date/Time: 00:35:00 04/00/2020
Date/Time: 00:35:01 04/00/2020
Date/Time: 00:35:02 04/00/2020
Date/Time: 00:35:03 04/00/2020
Date/Time: 00:35:00 04/00/2020

Ok so its really an I2C issue. How dos I wire multiple I2C devices on feather adalogger?

The output you've shown makes it look like the board is resetting.  It would be more clear if you had something distinct printing in setup().

Are you resetting the board repeatedly? Your setup() function always resets the date/time to the time the sketch was built.

Normally, in a situation like this... you create a sketch that will initialize and SET the current time for the RTC.  After that, you create a new sketch that only initializes and reads the RTC for your actual clock functions thus keeping the two actions  (SET/GET) isolated.

did you run I2C scanner?

How may I2C devices do you have connected? And what are those? It might be an I2C address conflict.


text:
Missed call to GSM
I want to give missed call to GSM module; how to do that? Whenever I call to GSM module, after 3 RINGs, it should be disconnected. How to do this?
#include <SoftwareSerial.h>

String string = "";
int ring=0;
int i;
//Create software serial object to communicate with SIM800L
 SoftwareSerial mySerial(3, 2); //SIM800L Tx & Rx is connected to Arduino #3 & #2

void setup() {
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);

  //Begin serial communication with Arduino and SIM800L
  mySerial.begin(9600);

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

void loop() {
  serialEvent();
  if (ring >= 1) {
    Serial.write("ATH");
  }
}

void serialEvent() {
  while (mySerial.available()) {
    char read_char = Serial.read();
    string += read_char;
    i++;

    if (string[i - 4] == 'R' && string[i - 3] == 'I' && string[i - 2] == 'N' && string[i - 1] == 'G') {
      ring = 1;
    }
  }
}

You're reading from Serial after checking mySerial.available(). Use a better name for the serial connected to the GSM module to avoid confusing yourself.


text:
ESP32 with static IP address acting as client connecting to ESP32 acting as access point
I have an ESP32 board as a client with a static IP address. The client with the static IP address connects to a second ESP32 that is acting as an access point. The connection is established and the access point recognizes the new connected device.
The problem is, with the client having a static IP address the access point displays the client IP as 0.0.0.0. If the client does not have the IP address set as static, the access point displays the correct IP address.
The code for the client:
#include <WiFi.h>

const char* ssid = "ESP32-AP";
const char* password = "123456789";
IPAddress ip(192, 168, 0, 101);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);

  // Configure the static IP address
  WiFi.config(ip, gateway, subnet);

  WiFi.begin(ssid, password);

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

  Serial.println("");
  Serial.println("Connected to WiFi network");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  static long general_t1 = 0;

  if (millis() - general_t1 > 2000) {
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
    general_t1 = millis();
  }
}

The code for the access point:
#include <Arduino.h>
#include <WiFi.h>
#include "esp_wifi.h"
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64

#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const char *ssid = "ESP32-AP";      // SSID Name
const char *password = "123456789"; // SSID Password - Set to NULL to have an open AP
const int channel = 10;             // WiFi Channel number between 1 and 13
const bool hide_SSID = false;       // To disable SSID broadcast -> SSID will not appear in a basic WiFi scan
const int max_connection = 5;       // Maximum simultaneous connected clients on the AP

IPAddress local_ip(192, 168, 0, 1);
IPAddress gateway(192, 168, 0, 1);
IPAddress subnet(255, 255, 255, 0);

//*** void display_connected_devices() **************************************************************
void display_connected_devices() {
  wifi_sta_list_t wifi_sta_list;
  tcpip_adapter_sta_list_t adapter_sta_list;
  esp_wifi_ap_get_sta_list(&wifi_sta_list);
  tcpip_adapter_get_sta_list(&wifi_sta_list, &adapter_sta_list);
  String deviceInfo = "";

  if (adapter_sta_list.num == 0) {
    deviceInfo = "No Device connected";
  }
  else {
    for (int i = 0; i < adapter_sta_list.num; i++) {
      tcpip_adapter_sta_info_t station = adapter_sta_list.sta[i];
      deviceInfo += "Device " + String(i) + " = ";
      deviceInfo += IPAddress((&station.ip)->addr).toString();
      deviceInfo += "\n";
    }
  }

  // Display accumulated device information
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("AP IP: " + WiFi.softAPIP().toString());
  display.setCursor(0, 20);
  display.println(deviceInfo);
  display.display();
  display.clearDisplay();
}

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

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;
  }

  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(25, 10);
  display.println(F("ESP-32"));
  display.setCursor(25, 30);
  display.println(F("Router"));
  display.display();
  delay(2000);

  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(local_ip, gateway, subnet);
  WiFi.softAP(ssid, password, channel, hide_SSID, max_connection);
  Serial.print("[+] AP Created with IP Gateway ");
  Serial.println(WiFi.softAPIP());
}

//***********************************************************************************************
//**                                  void loop()
//***********************************************************************************************
void loop() {
  display_connected_devices();
  delay(5000);
}

there are no IP addresses in WiFi. the SoftAP device can only display the IP from DHCP server records or maybe from ARP table after the client does some TCP/IP communication with the SoftAP device.

Thanks for the reply. Is there any way to get the Ip?

Not digging deep in API, as @Jurai says, it lists IP from DHCP server on AP, which know nothing about static IPs.

As you set static IP to "Client" - just use it (192.168.0.101) (KISS rule)
On AP implement web API which allow client to register itself
Use mDNS (aka Avahi, aka Bonjour) multicast discovery espressif-skd doc arduino-esp32 ESPmDNS library

What is Your goal in using static IP on Client?

There are some testbench who are controlled by esp32. Every testbench has a number and the idea is to have the same correspondent number inside the ip-address. The fourt octets of the ip-address would be the same as the testbench number. I managed this situation with having the client send its IP address to the Access Point upon establishing the connection. Thanks for the help.


text:
Gyro reading of MPU6050 drifts too much on fast changes only
I am trying to write a simple sketch for the MPU6050.
The problem is that the sensor is pretty much solid when stationary or changing the angle steadily at slow to mid angular velocities but if I try to change the angle too fast there's a huge drift in the readings by pretty much tens of degrees in either direction as shown in the below images from the serial plotter.
On slow to mid changes in the pitch angle the gyro is tracking the accelerometer pitch almost identically (it drifts a little over time but it's normal and acceptable for the complementary filter).
On fast changes however the pitch drifts instantly by tens of degrees from the accelerometer. The huge drift makes the complementary filter pretty much useless in correcting the output
It's my first try with the sensor so I don't have any experience with its parameters. But the problem seems to be in the lines of integrating the new angular velocities in roll and pitch.

I got lazy and used the default sensitivity scale factors; does this have anything to do with this behaviour?

The dt measured for the Arduino is 20 ms between readings; is this too slow for the fast changes or something?

The datasheet also mentioned a programmable output range. Does this need to be programmed for more bandwidth and accurate results?

EDIT:
I tried to read a bit about the sensitivity scale factor. It seemed that increasing the angular velocity beyond 250 degrees per second is not measured when selecting the default configuration.
After some testing I realized that 1000 deg/s is a good configuration for me; the drift certainly is much better but still not what I hoped for.
It still drifts by +- 10 degrees in two or three seconds of moving it around.
Slow to Mid changes output:

Fast changes output:

#include <Wire.h>
#define CAL_AVERAGE 2000

const int MPU = 0x68; //I2C address of MPU6050
const float alpha = 0.95;

double ax, ay, az;
double gx, gy, gz;

//float accAngleX, accAngleY, accAngleZ;
//float gyroAgnleX, gyroAngleY, gyroAngleZ;

double accErrorX, accErrorY, accErrorZ;
double gyroErrorx, gyroErrorY, gyroErrorZ;

double accRoll, accPitch;
double gyroRoll, gyroPitch, gyroYaw;

double roll, pitch, yaw;

double dt, currentTime, previousTime;

void setup(){
  previousTime = 0;

  Serial.begin(115200);
  Wire.begin();     //init the communication

  //reset the mpu
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);
  Wire.write(0x00);
  Wire.endTransmission(true);

  //calibrate here
  calculateError();
}

void loop(){
  readAcc();
  readGyro();

  //get roll and pitch of accelerometer
  accRoll = atan2(ay, az) * 180 / PI;
  accPitch = atan2(ax, az) * 180 / PI;

  currentTime = millis();
  //set gyro roll and pitch for accelerometer roll and pitch on first reading only
  if (previousTime != 0) {
    //get roll, pitch and yaw of gyro
    dt = currentTime - previousTime;
    dt /= 1000;
    gyroRoll += gx * dt;
    gyroPitch += -gy * dt;
    gyroYaw += gz * dt;
  } else {
    gyroRoll = accRoll;
    gyroPitch = accPitch;
    gyroYaw = 0;
  }

  previousTime =  currentTime;

  roll = alpha*gyroRoll + (1 - alpha)*accRoll;
  pitch = alpha*gyroPitch + (1 - alpha)*accPitch;
  yaw = gyroYaw;

  //finally print the values collected
  printData();
}

void readAcc(){
  //first read accelerometer data
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true);

  //accelerometer raw data
  ax = ( (Wire.read() << 8) | Wire.read() ) / 16384.0;
  ay = ( (Wire.read() << 8) | Wire.read() ) / 16384.0;
  az = ( (Wire.read() << 8) | Wire.read() ) / 16384.0;

  ax -= accErrorX;
  ay -= accErrorY;
  az -= accErrorZ;
}

void readGyro(){
  //second read gyro
  Wire.beginTransmission(MPU);
  Wire.write(0x43);
  Wire.endTransmission(false);
  Wire.requestFrom(MPU, 6, true);

  //gyro raw data
  gx = ( (Wire.read() << 8) | Wire.read() ) / 131.0;
  gy = ( (Wire.read() << 8) | Wire.read() ) / 131.0;
  gz = ( (Wire.read() << 8) | Wire.read() ) / 131.0;

  gx -= gyroErrorx;
  gy -= gyroErrorY;
  gz -= gyroErrorZ;
}

void calculateError(){
  float axErr = 0, ayErr = 0, azErr = 0;
  float gxErr = 0, gyErr = 0, gzErr = 0;

  for (int i = 0; i < CAL_AVERAGE; i++) {
    readAcc();
    az = az - 1;

    axErr += ax;
    ayErr += ay;
    azErr += az;

    readGyro();

    gxErr += gx;
    gyErr += gy;
    gzErr += gz;
  }

  accErrorX = axErr/CAL_AVERAGE;
  accErrorY = ayErr/CAL_AVERAGE;
  accErrorZ = azErr/CAL_AVERAGE;

  gyroErrorx = gxErr/CAL_AVERAGE;
  gyroErrorY = gyErr/CAL_AVERAGE;
  gyroErrorZ = gzErr/CAL_AVERAGE;
}

void printData() {
  Serial.print(ax);
  Serial.print(",     ");
  Serial.print(ay);
  Serial.print(",     ");
  Serial.print(az);

  Serial.print(",               ");

  Serial.print(gx);
  Serial.print(",     ");
  Serial.print(gy);
  Serial.print(",     ");
  Serial.print(gz);

  Serial.print(",               ");

  Serial.print(accPitch);
  Serial.print(",     ");
  Serial.print(accRoll);

  Serial.print(",               ");

  Serial.print(gyroPitch);
  Serial.print(",     ");
  Serial.print(gyroRoll);
  Serial.print(",     ");
  Serial.print(gyroYaw);

  Serial.print(",               ");

  Serial.print(pitch);
  Serial.print(",     ");
  Serial.print(roll);
  Serial.print(",     ");
  Serial.print(yaw);

  Serial.print(",     ");
  Serial.println(dt);
}

In his answer, st2000 recommends you use quaternions, rather than Euler
angles, for tracking the orientation of your vehicle. I will give the
exact same recommendation, but for a different reason: the formulas you
use, namely
gyroRoll += gx * dt;
gyroPitch += -gy * dt;
gyroYaw += gz * dt;

are just plain wrong. They are correct if rotations only ever happen
along a single axis. They are also “kinda good” (correct as a
first-order approximation) if the angles involved are very small. But in
the general case, they are wrong. A easy way to convince yourself of
this fact is to notice that the final (yaw, pitch, roll) being the sum
of many small contributions, they do not depend on the order in which
these contributions were added. In other words, these formulas imply
that the composition of rotations is commutative, which I hope you know
is not the case.
The only reasonable ways of composing many rotations (which is what this
attitude-tracking code tries to do) are rotation matrices and
quaternions, the latter being more efficient.
Now, a few remarks:

You should not track (gyroRoll, gyroPitch and gyroYaw)
independently from (roll, pitch, yaw), otherwise your
complementary filter becomes inefficient at canceling gyro drift.
You should instead merge those variable into a single triplet.

The line
( (Wire.read() << 8) | Wire.read() ) / 16384.0;

gets you the two bytes from the MPU in an unspecified order. They
may be in the right order with this particular version of this
particular compiler when run with this particular set of options,
but you should not count on this order being reliable. You should
instead read the two bytes in two separate statements.

If you do not care about the yaw, you may just track the gravity
vector instead of the full attitude. This should save you the calls
to atan2() and possibly simplify the math further. You may not
even need the quaternions after all.

Consider what might happen if the code or hardware dead reckoning capabilities were too slow to accurately sample short events. Such as a sudden stop. Robbed of the opportunity to integrate a fast deceleration event, the code and hardware might continue to report motion.
To speed up code execution, consider switching from trigonometry based calculations to quaternion calculations.  In general this replaces time consuming repetitive summation algorithms with simple math calculations more suitable for embedded processors.
To speed up the hardware, consider an Arduino platform with a faster processor.
Also consider more creative solutions suitable for your application:

If angular momentum is more important than linear motion sample the accelerometer only every other time through your main loop.
Or, if motion is totally random, and the device is on Earth, consider zero-calibrating the gyroscope when there is no movement perceived by the accelerometer.  Specifically, when there is a 9.8m/s*s vector sensed by the accelerometer and the pitch, roll and yaw of the accelerometer is not changing.


text:
Configure Trinket M0 as I2C peripheral
I am trying to use I2C to communicate between my XBee3 (controller) and an adafruit trinket m0 (peripheral). I'm pretty confident I have the modules connected properly (trinket SCL/pin 2 to xbee SCL/pin DIO1 & trinket SDA/pin 0 to xbee SDA/pin DIO11, and both grounds are connected). Here is my arduino code on the trinket:
#include <Wire.h>

void setup()
{
Wire.begin(72); // join i2c bus
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600); // start serial for output
Serial.print("Waiting for data...");
}

void loop()
{
delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
(void)howMany; // avoid compiler warning about unused parameter

while(1 < Wire.available()) // loop through all but the last
{
char c = Wire.read(); // receive byte as a character
Serial.print(c); // print the character
}
int x = Wire.read(); // receive byte as an integer
Serial.println(x); // print the integer
}

and here is my code on the XBee:
from machine import I2C

# Instantiate an I2C peripheral.
i2c = I2C(1)
slave_addr = 72
i2c.writeto(slave_addr, b'123', False)

Additionally, when I run an i2c.scan() on the xbee with an ISM330DHCX connected to the xbee's I2C, the address pops right up. But when I use the exact same code with the xbee connected to the trinket m0, the xbee cannot find any devices. (Code pasted below)
from machine import I2C

# Instantiate an I2C peripheral.
i2c = I2C(1)

# Scan for I2C slaves connected to the interface and print their address.
for address in i2c.scan():
    print("- I2C device found at address: %s" % hex(address))

Does anyone have any ideas what I'm doing wrong with configuring the trinket m0 to be an i2c peripheral? Thank you!

Did you solve this problem? I'm trying to communicate with I2C between two Trinket M0 and am facing the same issue.

I never solved it. After some additional research, I figured that the trinket M0 couldn't be configured as a peripheral. I ended up using a different microcontroller.

I have two Adafruit Trinket M0 arduino boards running on my bench right now talking to each other over I2C. The trick is that you need to install a pull-up resistor between SDA and +3V, and another one between SCL and +3V. Typically it is the peripheral boards that come with those but when you talk between two microcontrollers which are often used as the master controller themselves they are open drain or not powerful enough to drive the bus. Any resistor between 4.7k and 10k ohms should do.
see the following reference doc:
https://docs.particle.io/cards/firmware/wire-i2c/pull-up-resistors-i2c/
From the other direction if you have many peripheral boards that all include their own pull up resistors, the combined resistance on the bus may low enough leak enough current to raise "low" state above 0.4v, at which point communication may have errors.
Or if the wires are too long or there are too many devices without enough pull up resistance (thus too much inherent capacitance) it will take too long for the data lines to reach the "high" state, and you will have to slow down the clock rate or add a signal booster like the LTC4311 (e.g. Adafruit product #4756) to get stable results.

This is very helpful! Thanks for posting.  I have moved on in this project, so I'm unable to check to see if it solves the problem.  Nevertheless, this is great information for anyone who may be experiencing similar issues.


text:
Help with ESP32-CAM "AI THINKER" module
I'm trying to make a RC car (with a surveillance camera if possible, using the web-cam code that comes with the ESP library) using a ESP-32 CAM as a wifi module to control the car using my computer. Problem is that I keep getting the "invalid head of packet" error whenever I try uploading anything. I've tried holding the boot button as I upload and I cannot use the capacitor simply because I don't have it and don't want to buy it and spend time getting it. I also have the GPIO0 pin connected to GND during the uploading process. Any other ways to get it working? My car consists of 2 DC motors powering only the back two wheels and a servo that steers the front wheels, and I want to use the ESP32-CAM to connect to wifi to connect to a webserver from my pc to control the car.

I suspect that the power supply you used to power the ESP-32 can't provide the sufficient current.

You don’t need a capacitor and you don’t need to hold any buttons while uploading, just connect GPIO0 to ground, +3.3V power to your ESP32Cam’s +3.3V input, ground from the power supply/USB to Serial to ESP32 ground, Serial TX to ESP32 RX and Serial RX to ESP32 TX. The entire procedure is outlined very clearly here. What kind of USB-to-Serial are you using?

@StarCat, I tried what you said but now I'm getting the "Timed out waiting for packet header" error.


text:
Driving 5V relay with ESP-01
I'm trying to drive a 5V relay with 3.3V ESP-01 with schematic below. I programmed the ESP to start a portal through which I can derive the relay by triggering GPIO-0 & GPIO-2. However when I power on the circuit I encounter the following scenarios:

IF wire is plugged in to GPIO-2

ESP blue led turned on forever
Relay started buzzing sound forever
No WIFI network appears thus not working

IF wire is plugged in to GPIO-0

No WIFI network appears thus not working

IF I only plug the wire after powering on the circuit then it works just fine as intended.

Would you please explain what is happening and how to fix it

#include <ESP8266WiFi.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>

const byte DNS_PORT = 53;
IPAddress apIP(172, 217, 28, 1);
DNSServer dnsServer;
ESP8266WebServer webServer(80);

//int ledPin = 2;
#define ledPin0 0
#define ledPin2 2

int ledStatus0;
int ledStatus2;

void setup() {
//  Serial.begin(9600);         // Start the Serial communication to send messages to the computer
//  delay(10);
//  Serial.println('\n');

  pinMode(ledPin0, OUTPUT);  ledStatus0 = digitalRead(ledPin0);  digitalWrite(ledPin0, HIGH); ledStatus0 = 1;
  pinMode(ledPin2, OUTPUT);  ledStatus2 = digitalRead(ledPin2);  digitalWrite(ledPin2, HIGH); ledStatus2 = 1;

  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP("Toggle Portal");

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);

  // replay to all requests with same HTML
  webServer.onNotFound([]() {

    if (webServer.hasArg("led0")) {
      String status = webServer.arg("led0");
      if (status == "off") { digitalWrite(ledPin0, LOW); ledStatus0 = 1;  switchRelayOff(); }
      else if (status == "on") { digitalWrite(ledPin0, HIGH); ledStatus0 = 0; switchRelayOn(); }
    }
    if (webServer.hasArg("led2")) {
      String status = webServer.arg("led2");
      if (status == "off") { digitalWrite(ledPin2, LOW); ledStatus2 = 1;  switchRelayOff(); }
      else if (status == "on") { digitalWrite(ledPin2, HIGH); ledStatus2 = 0; switchRelayOn(); }
    }

    String content = "<!DOCTYPE HTML>";
    content += "";
    content += "";
    content += "  <title>ESP Web Server</title>";
    content += "  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">";
    content += "  <link rel=\"icon\" href=\"data:,\">";
    content += "  ";
    content += "";
    content += "";
    content += "
ESP Web Server
";

    content += "
Output - GPIO 0
";
    if ( ledStatus0 == 0 ) {      content += "  <input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"0\" >";
    } else {      content += "  <input type=\"checkbox\" checked onchange=\"toggleCheckbox(this)\" id=\"0\" >";    }

    content += "
Output - GPIO 2
";
    if ( ledStatus2 == 0 ) {      content += "  <input type=\"checkbox\" onchange=\"toggleCheckbox2(this)\" id=\"2\" >";
    } else {      content += "  <input type=\"checkbox\" checked onchange=\"toggleCheckbox2(this)\" id=\"2\" >";    }

    content += "";
    content += "";
    content += "";
    webServer.send(200, "text/html", content);
  });
  webServer.begin();
}

void loop() {
  dnsServer.processNextRequest();
  webServer.handleClient();
}

GPIOs 0 and 2 have a special purpose (https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/), I believe it's possible to use at least one of them as outputs. The relay module already has a transistor included, so the 2N2222 might not be required (do you have a datasheet for the module?)...

@SimSon this is the question, how to use them? it is not practical to attach them only after power up.

"Boot fails if pulled LOW" - this applies to both GPIO 0 and 2. The 2N2222 pulls the GPIO down to one diode drop (0.7V) above GND, which actually is LOW. Instead of using a BJT, you need to control the relay module with a mosfet. Its high gate resistance will have negligible effect compared to the internal pullup resistor.
Chances are that the transistor on the relay module itself is a mosfet. If that's the case and if this mosfet works with 3.3V you can get rid of the 2N2222 at all. In general, using two transistors for this task does not make much sense, but in your case a BJT at the GPIO does not work.
You may notice that the onboard led is connected to GPIO 2, which is high at boot. So if you pull down GPIO 0 somehow, booting fails and GPIO 2 gets pulled HIGH (ref) - the onboard led will light up.
"the question, how to use them?" - once the ESP has booted into your sketch you should be fine to use the GPIOs like you would normaly do.


text:
Error compiling for board Arduino Uno SIM7000
I'm using  botletics / SIM7000-LTE-Shield with Arduino Uno, I selected all examples but all end up with the same Error
C:\Users\lenovo\Documents\Arduino\libraries\SIM7000\Adafruit_FONA.cpp: In member function 'boolean Adafruit_FONA::postData(const char*, uint16_t, const char*, const char*, const char*)':
C:\Users\lenovo\Documents\Arduino\libraries\SIM7000\Adafruit_FONA.cpp:2045:3: error: expected ';' before 'readline'
readline(10000);
^~~~~~~~
exit status 1
Error compiling for board Arduino Uno.

do you have some old version of the library? there is no postData function  in current Adafruit_FONA.cpp

There's no "postData" (case sensitive) in any of the files of any of the commits in the Adafruit repo for that library.

I cloned botletics comparatively gigantic repo.  They've modified the Adafruit library without changing the name.
The problem appears to be that you are working out of the current master branch.  Switch to the latest tag, 1.1.0, and the SMS_Response example will compile just fine.  I didn't try all of the others.
Direct link to the zip file for the 1.1.0 tag.


text:
What is the tool to send file to SPIFSS on ESP8266/32?
Is there good tools (IDE, CLI or IDE addon) to send file via USB port to SPIFSS internal espressif ESP hardware SoC ?

Have you read the manual? http://esp8266.github.io/Arduino/versions/2.0.0/doc/filesystem.html

yes, but it's a LOT faster to load it over wifi.

The mkspiffs tool creates bin from file system data (or extracts data from bin).
SPIFFS bin is uploaded with esptool over USB or with espota over WiFi. It can be uploaded with the sketch binary in one command.
Example:
esptool.py -p /dev/ttyUSB0 write_flash 0x0 sketch.bin 0x300000 spiffs.bin

The IDE plugin adds SPIFFS upload to Arduino IDE Tools menu.

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


text:
How to compile Arduino ESP8266/32 on CI/CD (CLI shell cmd) platform?
Like make for not ESP Arduino target, is there a CLI command like esptool.py to upload in the hardware ?
I've seen makeEspArduino but seems to be not trivial ?
What about espressif ESP32 component ?
Is Visual Micro Arduino CLI (Command Line Interface) tool mature ?

Have you looked at https://github.com/arduino/arduino-builder/wiki/Doing-continuous-integration-with-arduino-builder

Thanx Craig. I'll have a deep look...

Easiest answer: Use PlatformIO. (Yes this answer is technically an advertisement, but it is the correct solution here.).
Why not the others?

makeEspArduino is dependent on GNU make, hard to make modification to, hard to get support for when something goes wrong
Visual Micro Arduino is Visual Studio extension, thus native to Windows

Why PlatformIO?
On the other hand, PIO is just a framework written in python2, runs on Windows, Mac & Linux alike and supports tons of boards and frameworks. Not only is it OS-agnostic but it also IDE agnostic. It exports project files for Eclipse, Visual Studio Code, CLion, Visual Studio, Sublime, Atom and other IDEs. The Arduino IDE will always be only a (bad) syntax highlighter.
Support boards (479 of them) range from Arduino Unos to ESP8266/ESP32 over to STM32 and nRF boards. It's also possible to compile one firmware for different environments (board), so with a well-written firmware, PIO can generate firmwares for multiple boards and frameworks alike. Frameworks include Arduino cores, ESP-IDF, STM32HAL and more.
To create a new project, you'd do
user@somefolder/$ pio init --board=nodemcuv2 --ide=vscode

To compile from CLI, you just have to execute the run target:
user@somefolder/$ pio run

To upload you'd just
user@somefolder/$ pio run -t upload

With optional --upload-port=/dev/ttyUSB0 or alike. Updating wirelessly over ArduinoOTA is also supported.
Video: https://www.youtube.com/watch?v=EIkGTwLOD7o
Documentation: http://docs.platformio.org/en/latest/

Thanx a lot Maximilian Gerhardt for this complete answer

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


text:
Is there a equivalent to #define DEBUG 0 declare by VS2017 with VisualMicro (arduino) project?
Especially on ESP32*/8266, when you select debug (debug/release) :  as a target, VisualMicro detect it and start the simple debugger (without JTAG).
Do you know if when target is debug, is there a #define created somewhere by VS that could be use with #ifdef for example?
*ESP32 WROOM not ESP32 WROVER able to debug through USB double chanel

the documentation for visual micro is here. the relevant section is "defines" about halfway down the page.

Ok but strange behaviour, need to be tested...

_DEBUG is define by VMicro in project parameter for each target with Define _DEBUG Constant set to 1 (0 by default)

Visual studio Debug/release compilation target switch has no effect during compilation but affect intellisense #ifdef _DEBUG is grayed or not. So it is not easy to follow the real compile target.
I suggest to set Define _DEBUG Constant to 1 in VS 'debug' compilation target project configuration and compilation will follow intellisense. But:
Another source here

Another advise, clean the compiled file because VS doesn't detect Define _DEBUG Constant like another "standard" #define and your .cpp affected are not recompiled.


text:
Powering USB cable that powers Arduino with regulated 5V
I am having an issue with external loads causing the computer I have my Arduino connected to to momentarily drop out, which causes the Arduino to lose USB power momentarily and the port drops out and won't reconnect unless I physically remove and reconnect the USB cable. Since I need the USB connected in order to send and receive serial data to/from the Arduino, I was wondering if I could physically open the USB cable, cut the 5V line, and supply it via and external regulated 5V supply. I wouldn't cut the ground wire, but would tie it to the external 5V supply. I have read conflicting information on this (something about handshaking) but was wondering if that applied to Arduino's specifically.

You probably could, but why not just get a powered USB hub?

A powered hub would be a more proper solution USB-wise.  However it may be that whatever is causing "dropouts" would break the USB session as well.  You might need to switch to using an actual serial connection (if still logic-level) and use a different serial port on the computer.  Another thing to look at would be galvanic isolators for USB or serial.  It really all depends on the cause and nature of the "dropouts".  If these are being cause by other USB peripherals try putting them on their own powered hub, ideally connected to a different port or internal hub on the PC.

The dropouts are being caused by external loads being powered on and off. The loads have pretty high starting current, which is causing power for the whole computer to fluctuate. I've tried using a UPS but the problem still persists. I'll try getting a powered hub and see if that helps.

USB devices are only slaves. They cannot do anything without the host. When the power of your computer drops, it seems to close the usb sessions. So this is most likely not a problem with the Arduinos USB, but with your computer. It has to reestablish the connections after a voltage drop. Using a powered USB hub will only ensure, that the Arduinos power isn't cut of, but it will not ensure, that the computer reestablishes the connection, that you need for data transer.

I solved this problem by using a laptop instead. It is immune to these power fluctuations

I solved this problem by using a laptop instead. It is immune to these power fluctuations

If you are drawing more than 500mA from your PC then that is why it is happening.
I suggest, rather than butchering a cable, you get yourself a "wallwart" (Mobile phone charger) and use that to power the board.  You really should work out how much current you are pulling before deciding on what PSU to use.
A problem with wall warts is earthing, you need to make sure that your PC and wall wart are connected to the same earth connection, so that they share a common ground.
If the current being drawn us only for a very short time then it might be possible to provide additional power using a capacitor in the power line.  But plugging a charger in is much easier.


text:
How can Arduino's 8 bit Microcontrollers handle C++
I have just started getting into Arduino and c++ programming!
For all the talk on the internet about c++ being incompatible with 8-bit and even 16-bit microcontrollers, how is it that Arduino Microcontrollers can safely handle c++ code, in terms of the ram usage? Is it that Arduino's library does not contain or utilize features such as constructors or objects (of C++) that (I believe) are very ram-usage-intensive?
Cheers!

There are some limitations about what you can do with C++ on an 8-bit Arduino, which come from avr-libc. Note that the linked page states that new and delete are not implemented, but the Arduino core provides an implementation based on malloc() and free().

Huh, it's almost as if  all the talk on the internet wasn't always right.

The width of a processor's instruction word ultimately says nothing about how much memory it has.  There are for example "overgrown" 8051 cores in bluetooth chips with several times more memory than many of the low end 32-bit ARM cortex parts.  That said, classic Arduinos do happen to have quite little RAM, and this makes some expensive patterns severely unwise.

It's a misconception that using constructors or C++ in general requires lots of RAM. Plus, to be clear, the AVR processors like the Micro and Uno have separate RAM and PROGMEM (program memory). So, code for functions does not, in itself, use RAM.
As an example, this small program for the Micro:
int main ()
  {
  }

That uses only 206 bytes of PROGMEM and 0 bytes of RAM (according to the IDE).
Sketch uses 206 bytes (0%) of program storage space. Maximum is 28,672 bytes.
Global variables use 0 bytes (0%) of dynamic memory, leaving 2,560 bytes for local variables. Maximum is 2,560 bytes.

Adding in a class, with a constructor, and using that class, increases the memory a bit:
class foo
  {
  public:
  int bar;  // some class variable

  foo ()  // constructor
    {
    bar = 1;
    }
  };  // end of foo

foo nick;  // a global variable
int main ()
  {
  PORTD = nick.bar;
  }

That uses 2 bytes of RAM, and 278 bytes of PROGMEM. Hardly a lot.
Sketch uses 278 bytes (0%) of program storage space. Maximum is 28,672 bytes.
Global variables use 2 bytes (0%) of dynamic memory, leaving 2,558 bytes for local variables. Maximum is 2,560 bytes.

Of course, the more things you do, the more RAM and PROGMEM it takes, however the compiler generates quite efficient code, and the linker strips out things that are not needed by your code.

Is it that Arduino's library does not contain or utilize features such as constructors or objects (of C++) ...

A lot of libraries use classes and constructors (for example the Serial library, the Print class, and a lot of others). There is nothing inherently RAM-intensive about a constructor. It's just a function that does something, with an implied this pointer to the current instance of the class.

do lambdas work? (from a comment)

Yes you can use lambdas:
// array of function pointers
void (*doActionsArray []) () =
 {
 [] { Serial.println (0); } ,
 [] { Serial.println (1); } ,
 [] { Serial.println (2); } ,
 [] { Serial.println (3); } ,
 [] { Serial.println (4); } ,
 };

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

  doActionsArray [3] ();
  }  // end of setup

void loop () { }

as long as you don't (extensively) use: the standard library, exceptions, templates ... (from a comment)

Templates can certainly simplify doing things like writing to, or reading from EEPROM and similar. For example:
#include <Arduino.h>  // for type definitions
#include <EEPROM.h>

template <typename T> unsigned int EEPROM_writeAnything (int ee, const T& value)
{
    const byte* p = (const byte*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
        EEPROM.write(ee++, *p++);
    return i;
}

template <typename T> unsigned int EEPROM_readAnything (int ee, T& value)
{
    byte* p = (byte*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
        *p++ = EEPROM.read(ee++);
    return i;
}

The standard library? There are implementations for the Arduino. We have to bear in mind that RAM is limited, however if you are going to do something anyway that involves linked lists, etc. then the Standard Template Library will probably do what you want as efficiently as you could if you coded it "by hand".

The bottom line is you need to be aware of what you are coding on. I have seen examples like this:
float foo [1000];  // hold my readings

That blows the available RAM on a Uno straight away. Nothing to do with C++ per se.

The other thing to be aware of is some tricks you can usefully employ. One common one is to replace:
Serial.println ("Program starting.");

With:
Serial.println (F("Program starting."));

The first example causes the compiler to copy the string "Program starting." from PROGMEM into RAM, using some of your valuable RAM. The second example doesn't.

Basically you can use C++ as long as you don't (extensively) use: the standard library, exceptions, templates or rtti (do lambdas work? never tried). Whether you'd want to call the remaining language really 'c++' is another question.

@Voo: On the Arduino, templates are not necessarily a bad thing.

@Edgar Very clever trick, but certainly not the way you'd use templates in general code. A better way to phrase it might be that you have to be very careful with how you use templates since they can very easily lead to large quantities of code being generated behind your back.

@Voo Is that just a limitation of the AVR compiler? GCC and Clang do a pretty good job of optimizing template usage for desktop work. Or is it more an issue with standard-library/etc. templates, which are very general so may have lots of stuff you don't need?

@JAB Ignoring STL templates, it's still easy to introduce code bloat through templates. Here's a dummy example that shows a pretty common issue — defining a template function which includes a large amount of code which doesn't need to be genericized. Those two programs are functionally identical, but through GCC with -O2 on my desktop, bloated.cc generates a 31KB executable while trimmed.cc generates a 14KB executable.

@MattK Ah, I see what you mean. (Though in that case the call to preamble seems like it could be kept in the template function with minimal code bloat rather than being a separate call, unless the compiler decided to inline those calls).

See amended reply for comments on some of those points.

@JAB It's generally recommended for efficient code to try and forward to non-generic functions (e.g. standard libraries cast T's to void* and deal with those). Absolutely doable but makes for awkward programming and is easily forgotten. Nick's template example is pretty similar: Instead of forwarding the byte* and size to a generic function we now have almost identical code multiple times in memory. If you had to write it by hand you'd notice the duplication.

@Voo - I guess the same goes for using other features such polymorphism and inheritance and other OOP features?

@Curious The general gist is that C++ is complex enough that it can be rather hard to know what exactly the compiler is doing in the background. Then you also have to rely on your compiler to do certain optimizations for certain things to be feasible (do you know whether your compiler does COMDAT folding?). It can be done, usually by limiting yourself to certain features, but it's a bit fragile (i.e. a tiny change can lead to very different non-functional behavior).

C++ is fine with Arduinos or other AVR based Systems.
I've been use it for quite a while in a home automation project.
The avr runtime does not support exceptions nor dynamic memory allocation, as has been stated. you can provide an implementation  though.
There is much of C++ left to make use of. here are some examples
Templates
They are very useful because, e.g. they allow to move work from runtime to compiletime. I use template for a replacement of the Arduino HAL functions DigitalWrite and others, without the runtime and code bloat.
compare this
int main(void)
{
        DDRB |= (1<<7);
        while(  (  ( PINB & (1<<6) ) !=(1<<6) ) )
                ;
        while(1)
        {
                _delay_ms(100);
                PORTB |= (1<<7);
                _delay_ms(100);
                PORTB &= ~(1<<7);
        }
}

to this
int main(void)
{
        IOPin<13> ledpin;
        IOPin<12> testpin;
        ledpin.SetDir(out);

        while(0 == testpin.State())
                ;
        while(1)
        {
                _delay_ms(100);
                ledpin.SetHigh();
                _delay_ms(100);
                ledpin.SetLow();
        }
}

The template based version is much more readable, and generates exactly the same assembler code. In the abovementioned linked article i explain the template and why this works.
more on templates
The following code uses the "curiously recurring template pattern" CRTP.
It is used to create a job class, which i use for a primitive scheduling
This template builds a chain of registrable items.
template<class registered>
struct Registered {
    static registered *registry;
    registered *chain;
    Registered() : chain(registry) {registry=static_cast<registered*>(this);}
};

The job class applies the CRTP pattern. The constructor takes the actual callback where the work is done, and how often the job is done.
class Job : public Registered<Job>
{
    voidFuncPtr m_p;
    uint16_t m_periodic;
    uint32_t m_lastrun;
    uint16_t m_initialdelay;
    public:
    Job(voidFuncPtr p,uint16_t periode=0,uint16_t initialdelay=0):m_p(p),m_periodic(periode),m_lastrun(0),m_initialdelay(initialdelay)
    {

    }
    void run(uint32_t t_ms)
    {
        // tbd handle wraparound !!
        if(t_ms >= m_lastrun + m_periodic + m_initialdelay)
        {
            m_p();
            m_lastrun=t_ms;
            m_initialdelay=0;
        }
    }
};

to use the job class i just create the instances for the jobs and pass lambdas or regular function pointers
Job jserial([](){mqttrouteradapter.handleSerialMQTT();},10);
Job jupdate(updatemc,1);
Job jprint(printstate,500);

initialize the beginning of the chain of jobs
template<> Job *Registered< Job >::registry = 0;

and inside main, run an infinite loop which calls the jobs.
while (1)
    {
        for ( auto p = Job::registry; p; p=p->chain )
        p->run(millis());
    }

Lambdas
Nice to avoid a callback function
instead of
void handleserial(void)
{
    mqttrouteradapter.handleSerialMQTT();
}
Job jserial(handleserial,10);

i can write something like
Job jserial([](){mqttrouteradapter.handleSerialMQTT();},10);

the new meaning of auto
Allows to deduce the type automagically. This function iterates over "something" passed the second parameter. It compiles, if the passed type provides the operations/attributes used in the function.
And yes, this works only since c++17
void runRx(const char* data, auto msg_registry) {
    for (auto p = msg_registry; p; p = p->chain) {
        p->rx(data);
    }
}

using a recent compiler
If you want to use a recent compiler (The Arduino IDE uses gcc4.9) you can build your own gcc avr toolchain rather easily. Then you have gcc 7.2 with c++17 support !
An other very good reason to use gcc 7.2 is, that they have improved the error messages by a great deal.
My conclusion is, there is no excuse using c, except you havn't yet learned c++. And use a new compiler !

nor dynamic memory allocation - malloc/free and new/delete are both available in the standard IDE.

The talk about C++ being incompatible with small MCUs implies that developers would use features it provides. In a good C++ project you're expected to use vectors and iterators instead of C arrays, throw exceptions instead of returning error codes, use lambda-functions, templates etc.
As long as you don't use those features, C++ memory consumption is manageable. The reason for this is simple: such limited C++ is just a syntactic sugar around C structures and function pointers.
The problems usually start when you write a class which is complex enough that its constructor can fail. Then you have a tough choice to make: start using exceptions and drastically increase memory consumption, or write classes which pretend they never fail to construct (which often results in a program which pretends to work).

AFAIK, the Arduino environment does not support exceptions.

@EdgarBonet It wouldn't be a very useful feature to support anyway, considering most boards have about 2K RAM.

@DmitryGrigoryev Or a third choice - use the constructor to set up the class in a known but non-working state, and have a second "initialisation" function which does all the operations which can fail.  This is a fairly standard design pattern.  If you then use a factory which is a "friend", the second "initialisation" function isn't exposed to the rest of the world, and the factory can legitimately report "I'm sorry, I can't do that, Hal".  This has minimal extra cost compared to just calling a constructor; certainly nothing like as heavy as adding exception handling.

@Graham Possible, but it would mean all error conditions must be explicitly handled in code. You won't be able to simply write f(g(x)), you'll have to wrap every action which could fail in the error-handling code.

@DmitryGrigoryev You say that like it's a bad thing. :)  The second "initialisation" function could just report true/false, or it could be more detailed about the cause of failure.  It's up to you as the coder.  In general though, if you don't understand every error condition, then I'd say you haven't thought enough about your design or code.  If you've done your design properly, there simply is no such thing as an unexpected error.  Sure, there could be errors you think shouldn't happen, but a robust implementation will still cover them.

@Graham Well yes, having to write extra code is a bad thing. Your argument reads a bit like "you shouldn't use default in a switch statement, because if you've done your design properly, there's not such thing as an unexpected value". Exceptions are not unexpected errors, they are errors for which you have no cure but to abort the current action, and possibly try again.

@DmitryGrigoryev Having to write unnecessary code is a bad thing, sure; but having to write more code to do the job properly is not.  Handling errors appropriately really isn't unnecessary. Perhaps it takes more code if you're reliant on downstream functions to throw an exception if "new" fails and you try to dereference a null pointer, for example.  But that's where PC coding and embedded coding differ.  On a modern PC with essentially infinite resources you can generally get away with bad habits like that because it rarely if ever happens; but in the embedded world you can't.

@DmitryGrigoryev "errors for which you have no cure but to abort the current action, and possibly try again" are/should not be very common in embedded environments. Any possible "error condition" (external hardware not ready, transmitted failure, etc) should probably be explicitly handled and thus not really be exceptional.

To write effective code with limited resources (RAM, program space, processing), you need to know enough about the processor to avoid features which it can't do.  In this case you're limited on all three counts, so you want to get away from anything complex and slow.
A good start is to avoid any features later than C++98, or at least C++03.  These features generally come at a cost.
Beyond that, particular issues are:-

Polymorphism.  All classes using virtual members have a virtual method table, meaning every function call from that class needs to look up against a table.  On a small processor, this does slow down your function calls.  By all means use this where it's required, but if you have performance issues then you want your polymorphic classes to live at a higher level where the function calls happen less often.  Don't do this for low-level functions which get called thousands of times in a loop.
Exceptions.  Already covered by other answers.
Inline.  This is a good thing.  Where you can use this, it can claw back some processing cycles: not just from the function call itself; but also from further optimisation in the calling functions.

And of course general issues for embedded firmware on low-end micros:-

Dynamic memory allocation (new and delete, or most STL containers).  This is always an anti-pattern in embedded development.  It requires a chunk of RAM to be set aside for heap, and you always need to consider the possibility of allocation failing.  If you really need some kind of dynamic storage, consider whether a FIFO buffer or something better bounded would be appropriate.
Longer integers.
Integer multiply and divide.
Anything floating-point.
Anything using a lot of stack, whether this is lots of local variables, lots of function parameters, or over-enthusiastic function partitioning.

Integer multiplication is OK on Arduinos, as the ATmegas have a hardware multiplier. But note that some Arduino-compatible boards (Trinket, Digispark, ...) are based on ATtinies, which do not have such multiplier.

Arduino libraries relying on C++11 are not that uncommon. Also, a lot of STL containers can be used without dynamic memory allocation. Nothing stops you from creating an std::vector on stack.

@EdgarBonet Isn't that only an 8-bit x 8-bit multiplier though?  Technically an 8-bit value is not an integer. ;)

Yes, it's a 8×8→16 bit multiplier. It is used by the compiler to implement all multiplications far more efficiently than a bitwise shift-and-add. Multiplying two ints requires only three 8×8→16 multiplications (two bytes of flash and two CPU cycles each) and a few additions. 2. Technically, both int8_t and an uint8_t are 8-bit integer types. But this is completely unrelated to my first comment.

@EdgarBonet Error on my part - it's an integer, just not an "int". :)

@DmitryGrigoryev Sure, if you need features from C++11 or later, you can use them - you just need to be aware of the implications on a low-spec processor.  Re STL containers, the std::vector container may live on the stack, but its data (which of course is the important bit) will be on the heap because it has to be resizable.  Unless the STL implementation is a bit non-standard, or I guess if you've done something funky with the allocator, but that's probably beyond the skills of the OP at the moment.  std::array could be entirely on the stack though (and yes, this is a C++11 addition).

std::array can be a stack-only allocation. std::vector is dynamically sized, so even if some flavor of std::vector can be stack-only on construction, causing a resize by adding elements will need dynamic memory.


text:
Error in program that measures distance from a ultrasonic sensor
I am trying to use an ultrasonic sensor in conjuncture with different devices like a proximity sensor and a solenoid and alarm.
This is how the project is supposed to work:
A container is placed on a fixture and the proximity sensor detects the placement of the container. Once the container is detected the ultrasonic sensor needs to be activated and the pulse time is measured and the distance is calculated. The container has unique features on each side and the aim of the ultrasonic sensor is to measure the distance and if the distance value is within the required spec then it should turn on a solenoid to allow the next operation or if it's outside the spec it should raise an alarm.
following is the code:
/*Objective of this project

1. To be able to detect when a container is placed in the wrong oreientation and cut of the supply to pneumatic system if so.
We will use the following devices to do so

1. Ultrasonic sensor to measure distance differences of both sides of the container
2. IR sensor to measure if the conatiner has been placed or not (This sensor will activate the ultra sonic sensor)
3. A soliend that will be controlled by the output of the ultrasonic sensor. The solenoid will control the air flow.

*/

int trigPin = 7;
int echoPin = 8;
int contSig = 2;
int solSig = 12;
int errSig = 13;
void setup() {

  Serial.begin(9600);
  pinMode(trigPin,OUTPUT);
  pinMode(contSig,INPUT_PULLUP);
  pinMode(echoPin,INPUT);
  pinMode(solSig,OUTPUT);
  pinMode(errSig,OUTPUT);

  }

void loop() {
  if (digitalRead(contSig) == 0){
    Serial.println(digitalRead(contSig));
    digitalWrite(trigPin,LOW);
    delayMicroseconds(10);
    digitalWrite(trigPin,HIGH);
    delayMicroseconds(10);
    int duration = pulseIn(echoPin,HIGH);
    Serial.println(duration);
    float dist = (duration/2) * 0.034;
    Serial.println(dist);
    if (dist >=20 && dist <= 60){
      digitalWrite(solSig,HIGH);
      digitalWrite(errSig,LOW);
    }
    else{
      digitalWrite(solSig,LOW);
      digitalWrite(errSig,HIGH);
    }
  }

}

I am facing a few issues.
1.The first If statement at the beginning does not seem to work properly.
2.The output on the serial monitor alternates between zeros and actual values.  I am not sure why this set of zeroes keeps coming inbetween but this will make the project fail.
Following is the output from the serial monitor:
0
0
0.00
0
2892
49.16

pulseIn returns zero if no pulse is detected within the default timeout period. The other zeros are ones that you print explicitly.

"The first If statement at the beginning does not seem to work properly"  Why do you say that?

I have simulated this program on tinker cad, I do not understand why the zeroes are still appearing. As per the logic, we should not be having zeroes.  The if the state does not seem to be working because when I change the contSig value from 0 to 1 I still get a reading from the ultrasonic sensor which should not be happening


text:
WifiManager Custom Parameters not working on ESP-01
I have tested this code on Lolin Nodemcu v3 and it is working perfectly. However when I switched to ESP-01 The Wifimanager works but no custom parameters are saved although WIFI Credentials are saved.
#include <FS.h>          // this needs to be first, or it all crashes and burns...
#include <WiFiManager.h> // https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>

int ledPin = 2;
char mqtt_username[40]; char mqtt_password[40];     String mqttusername;    String mqttpassword;

WiFiManager wm;

bool shouldSaveConfig = false;
void saveConfigCallback () {  Serial.println("Should save config");  shouldSaveConfig = true; }

void setup() {
  Serial.begin(115200);  pinMode(ledPin, OUTPUT);  digitalWrite(ledPin, LOW);

  setupSpiffs();  wm.setSaveConfigCallback(saveConfigCallback);
  WiFiManagerParameter custom_mqtt_username("username", "username", mqtt_username, 40);
  WiFiManagerParameter custom_mqtt_password("password", "password", mqtt_password, 40);

  wm.addParameter(&custom_mqtt_username);  wm.addParameter(&custom_mqtt_password);

  strcpy(mqtt_username, custom_mqtt_username.getValue());     mqttusername = custom_mqtt_username.getValue();
  strcpy(mqtt_password, custom_mqtt_password.getValue());     mqttpassword = custom_mqtt_password.getValue();

  if (shouldSaveConfig) {    Serial.println("saving config");        DynamicJsonDocument doc(1024);
    doc["mqtt_username"] = mqtt_username;    doc["mqtt_password"] = mqtt_password;
    File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {  Serial.println("failed to open config file for writing"); }
    serializeJson(doc, Serial);    serializeJson(doc, configFile);    configFile.close();    Serial.println("");    //end save
  }
  while (WiFi.status() != WL_CONNECTED) { delay(100); Serial.print(".");  resetbtn(); }  Serial.println("");
  Serial.print("Connected to WiFi: ");  Serial.println(WiFi.SSID());
  Serial.print("IP: ");  Serial.println(WiFi.localIP());
  Serial.println("connected...yeey :)");
}

void loop() {
Serial.println("user is: ");   Serial.println(mqtt_username);
Serial.println("pass is: ");   Serial.println(mqtt_password);
}

void setupSpiffs(){
//   SPIFFS.format();
  Serial.println("mounting FS...");

  if (SPIFFS.begin()) {    Serial.println("** Mounting file system **");
    if (SPIFFS.exists("/config.json")) {      Serial.println("** Reading config file **");      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        size_t size = configFile.size();        std::unique_ptr<char[]> buf(new char[size]);
        configFile.readBytes(buf.get(), size);        DynamicJsonDocument doc(1024);        DeserializationError error = deserializeJson(doc, buf.get());
        if (error) {          Serial.print(F("deserializeJson() failed: "));          Serial.println(error.c_str());          return;        }
        strcpy(mqtt_username, doc["mqtt_username"]);             strcpy(mqtt_password, doc["mqtt_password"]);
      } else {        Serial.println("** Failed to load json config **");      }
      configFile.close();      Serial.println("** Closed file **");
    }
  } else {    Serial.println("** Failed to mount FS **");  }
}

void resetbtn() {    if ( digitalRead(ledPin) == HIGH ) {  wm.startConfigPortal("Burooq");    Serial.println("connected...yeey :)");  }   }

At the serial Monitor I get:
*WM: [2] <- HTTP WiFi save
*WM: [3] Method: POST
*WM: [2] Parameters
*WM: [2] --------------------
*WM: [2] username: test
*WM: [2] password: test
*WM: [2] --------------------
*WM: [3] Sent wifi save page
*WM: [2] processing save
*WM: [2] Connecting as wifi client...
*WM: [3] STA static IP:
*WM: [2] setSTAConfig static ip not set, skipping
*WM: [1] CONNECTED:
*WM: [1] Connecting to NEW AP: MYSSID
*WM: [3] Using Password: SSIDPASS
*WM: [3] WiFi station enable
*WM: [3] enableSTA PERSISTENT ON
*WM: [1] connectTimeout not set, ESP waitForConnectResult...
*WM: [2] Connection result: WL_CONNECTED
*WM: [3] lastconxresult: WL_CONNECTED
*WM: [1] Connect to new AP [SUCCESS]
*WM: [1] Got IP Address:
*WM: [1] XXX.XXX.XXX.XXX
Should save config
*WM: [2] disconnect configportal
*WM: [2] restoring usermode STA
*WM: [2] wifi status: WL_CONNECTED
*WM: [2] wifi mode: STA
*WM: [1] config portal exiting
connected...yeey :)

Connected to WiFi: MYSSID
IP: XXX.XXX.XXX.XXX
connected...yeey :)
user is:

pass is:

user is:

pass is:

user is:

pass is:

user is:

pass is:

the code which should store the values runs before WiFiManager is started


text:
How to avoid MQTT reconnect Loop
I have the following code designed to allow me to control my device from my website using mqtt broker while internet is available. I also built in a local webserver to control the device in case of internet outage given I'm still connected to the same router my device is connected to.
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

int ledPin = 2;

const char* ssid = "SSID";
const char* password = "PASS";
const char* mqtt_server = "MQTTSERVER";
const char* mqtt_user = "MQTTUSER";
const char* mqtt_pass = "MQTTPASS";
const char* mqtt_topic = "topic";
String mqttpayload;

WiFiServer server(80);
WiFiClient espClient;
PubSubClient client(espClient);

void setup() {
  Serial.begin(115200);  pinMode(ledPin, OUTPUT);  digitalWrite(ledPin, LOW);

  WiFi.begin(ssid, password);

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

  Serial.print("Connected to WiFi");

  client.setServer(mqtt_server, 1883);    server.begin();
}

void loop() {
  client.setCallback(callback);
  reconnect();
  if ( mqttpayload == "OFF" ) {   digitalWrite(ledPin, HIGH); Serial.println("Switced OFF"); }
  if ( mqttpayload == "ON" ) {   digitalWrite(ledPin, LOW);  Serial.println("Switced ON"); }
  mqttpayload = "";

  WiFiClient cclient = server.available();
  if (!cclient) {  return;  }  while(!cclient.available()){  }
  String request = cclient.readStringUntil('\r');  Serial.println(request);  cclient.flush();

  int value = HIGH;
  if (request.indexOf("/LED=ON") != -1)   {
    digitalWrite(ledPin, LOW);    value = LOW;      Serial.println("Publish message: ON");    reconnect();  client.publish(mqtt_topic, "ON", true);
  }
  if (request.indexOf("/LED=OFF") != -1)  {
    digitalWrite(ledPin, HIGH);   value = HIGH;     Serial.println("Publish message: OFF");    reconnect(); client.publish(mqtt_topic, "OFF", true);
  }

  cclient.println("HTTP/1.1 200 OK");
  cclient.println("Content-Type: text/html");
  cclient.println("");
  cclient.println("<!DOCTYPE HTML>");
  cclient.println("");
  cclient.print("LED status: ");

  if(value == HIGH) {    cclient.print("OFF");  } else {    cclient.print("ON");  }
  cclient.println("

");
  cclient.println("Turn ON
");
  cclient.println("Turn OFF
");
  cclient.println("");
  Serial.println("");
}

void callback(char* topic, byte* payload, unsigned int length) {
  for (int i = 0; i < length; i++) {     mqttpayload += (char)payload[i]; }
}

void reconnect() {
  if (!client.connected()) {
    while (!client.connected()) {
      Serial.print("MQTT..");
      if (client.connect("2021", mqtt_user, mqtt_pass)) {
        Serial.println("MQTT connected");        client.subscribe(mqtt_topic);
      } else { error(); }
    }
  }
  client.loop();
}

void error() {  Serial.print("failed, rc=");      Serial.print(client.state());      Serial.println(" try again in 5 seconds");      delay(5000);   }

The problem lies when I test it while connected to my router with no internet. The code loops trying to connect to MQTT server and get stuck which doesn't allow me to send local HTTP requests.
I tried modifying the MQTT reconnect loop to the one below, which solves the problem but introduces another issue which is delaying the HTTP requests up to 6-9 seconds.
void reconnect() {
 if (client.connect("2021", mqtt_user, mqtt_pass)) {
  Serial.println("MQTT connected");
  client.subscribe(mqtt_topic);
 } else { error(); }
 client.loop();
}

So the question here, what should I do to get around this issue?

You should only try connecting to your MQTT server when there's no active connection. With your second piece of code you are (re)connecting every iteration of your loop() and this might introduce the delay you seem to be experiencing. Place an if (!client.connected) { ... } around the if (client.connect()) { .. } code.

@StarCat if you look at the main code, it's there, and this is what makes it troublesome to me. if internet connectivity is lost, this will hold Arduino from receiving my HTTP requests.

You could throttle the amount of reconnect attempts by only calling reconnect() every few seconds and not continuously. I've had good results with checking once every 30 seconds. If you do that, you should call client.loop() from your main loop() and not from reconnect().

It's quite simple: on each iteration of loop() if the client isn't connected then try to connect. Not while the client isn't connected then try to connect. Only try once each time through.

You could look at the PubSubClient example mqtt_reconnect_nonblocking which might be what you're looking for. It only tries to connect when there's no connection (I assumed your code already did this, but it looks like it doesn't).

In the loop, check the network first, you can also ping to internet to make sure the internet is available. If negative, just skip reconnecting and try to check the internet connection or try another way to connect to MQTT or esp.


text:
Is my 8x8 led matrix module broken?
I have an Arduino Mega set up with an 8x8 led matrix as laid out in this circuito.io project: https://www.circuito.io/static/reply/index.html?solutionId=6013e67aeaa9ed0030f668fb&solutionPath=storage.circuito.io

But when I plug in the usb cable, it looks like this:

I'm using the default code supplied by circuito.io (this was just meant to be a "hello world" jumping off point)
When I run the code, some of the leds flicker on and off, but the ones that are on in the image tend to stay on regardless.

Did you open a serial monitor and choose an option? The code waits for input over the serial connection.

@PeterPaulKiefer Yes I did, I also tried adding an option that would simply clear the screen (to no effect)

Some guesses: The module is not correctly wired. Show a picture where I can see the connections, the arduino and the matrix completely then, I could check it for you. - A wire is broken. I think you have checked this already. -- The Module is broken. That's possible!. Have you a second one to try? The chip seems to be replacable. Have you another MAX7219 chip to replace it? -- You could have a typo in the code, by accident: add your code (ino-file; the one you use) to the question. I would check that for you.

What happens if you only connect Vcc and GND to the module? Could you post a photo of the underside of the module? It might be a bad solder connection. Try wiggling all the connections to make sure they make proper contact. I've had breadboards that sometimes didn't make a proper connection with the wires that I inserted.

So I've tried wiring the MAX7219 chip up myself following this as a guide: http://wayoda.github.io/LedControl/pages/hardware
I only wired up the first column because my breadboard is only so big (plus, I just need to see what's up)
I seemed to have the exact same problem with the example code from circuito.io, but - when I loaded up the LCDemoMatrix example, which uses the http://wayoda.github.io/LedControl/ library instead, it works!
I'm not sure what was wrong with the first demo I used, possibly the modification I used to just turn on a single led was wrong.

@Gerben - Plugging in just VCC and GND still results in the same pattern

VCC, Ground, and Din are connected together per your frizzy drawing. This cannot be as the leds light. A schematic, of what you have, would be much easier to read and follow. The information all we can do is take a SWAG at it. FYI the Frizzy thing at circuit IO has the same problem.

In that case there is a problem with your matrix module.

It's likely that it is just the orientation of the module is wrong. Pull out the LED module, rotate 180 degrees, put it back in and it should work. The dot point should be on the bottom right.


text:
What happens when you call malloc()/free()/new/delete?
So I understand that generally speaking, dynamic allocation should be avoided. My question isn't how or why, but what happens when you call a function that allocates memory?
On Windows or Linux, when a program allocates memory, a whole bunch of stuff happens, things like virtualisation and security related features that have no relevance to arduino, and the bit that I'm interested in, memory management:
There will be some code, that will look at the alignment and size requirements of the allocation request, look at the pool of memory it has access to, find a space big enough, make a note of the allocation (which also uses some amount of memory) and then return a pointer to the allocated space back to the calling function.
Is there a custom malloc implementation for each device, or does it come with the arduino toolchain (and does that mean Arduino has a different implementation from Teensy, or avr from sam?), or is there some magical default implementation supplied by the compiler? What kind of memory overhead is incurred with every allocation? How easy is it to override this functionality and implement your own (out of morbid curiosity or tendency towards masochistic endeavours)?

For an overview of malloc() on AVR, see this page of the avr-libc documentation.

Regarding "each device" vs "Arduino toolchain" and malloc:, largely neither.  It's part of a libc implementation that typically covers many devices. Customizing the libc malloc in an algorithmic way usually means patching building libc yourself. There are a few Arduino specific stubs e.g. for new/delete and moving the stack/heap break, but the bulk of what you're asking about (which is a lot) has really not much to do with Arduino.

The four or so non-AVR malloc() implementations that I've looked at, including Due and ESP8266 ones use same the basic scheme described in EdgarBonet`s link and are tunable in roughly the same ways.

The "avoid dynamic allocation" afaik is an MCU thing, I asked a pro (non-embedded) C++ dev about it and he looked puzzled but agreed that it should be avoided if the coder doesn't know what they are doing. Without an OS, the MCU cannot clear garbage, so mistakes matter a lot more than on a PC, but dynamic allocation certainly can be done, and done reliably, on an MCU, as long as the system parameters are understood and respected.

I'm sorry @dandavis but I see "MCU" and all I can think of is a certain comic book movie franchise.

We tend to use MCU for microcontroller, some people use just micro for short. A bit confusing at first.

There are some hardware-specific abstractions (they mostly define the maximum memory available), but otherwise these are functions are implemented by the C/C++ runtime (on arduinos an implementation called "NewLib") and usually "just work". You might want to take a look at this question, where quite a bit of background is given on the SAM implementation of the hardware abstractions (because it's broken).
And yes, of course using malloc/free has some considerable overhead, which is one reason why it's not the recommended way of allocating memory on microcontrollers. But the logic behind it is mostly the same whether there's 2k of memory or 2G. And the memory model of modern microcontrollers (at least the 32 bit ones) is very similar to the one seen in 32 bit Windows or Linux apps.


text:
how to control switch (proteus) using bluetooth card (HC-05) and arduino?
This is the first time I use the Internet with the Arduino in the proteus ,
What are the stages that I must follow in order to be able to control the switch via Bluetooth?
If it was possible to clarify more, because I really do not know anything about the other applications, taht my first project in iot.

A switch is a mechanical device. It can only be controlled via bluetooth, if you add a motor, which presses the switch mechanically. Though that cannot be simulated in Proteus. Though I don't think this is, what you are really asking. The switch is connected to pin 2 of the Arduino. So you are reading the switch with your code. I guess you don't want to control the switch, but you want to control, what the switch is controlling via the code. So please include your code and explain, what exactly should happen on what serial data and what problems you have with doing that.

That sounds more like an essay question. I don't know Proteus really, but depending on how accurately it models reality, the HC-05 board needs VCC and GND wired.  Possibly others.


text:
default in switch doesn't appear to execute
I have a situation where the default case in my switch statement doesn't appear to execute as expected. I wonder if there is some subtlety I'm missing here?
Given the following enum:
enum HomingPhase
    {
    Idle = 0,
    Detecting,
    Stopping,
    Reversing,
    AtHome,
    };

and the following methods:
void HomeSensor::setPhase(HomingPhase newPhase)
    {
    phase = newPhase;
    Serial.print("Phase ");
    Serial.println(phase);
    }

void HomeSensor::onMotorStopped() const
    {
    std::cout << "Hstop " << phase << std::endl;
    switch (phase)
        {
        case Reversing:
            setPhase(AtHome);
            break;
        case Stopping:
            setPhase(Reversing);
            const auto target = commandProcessor.targetStepPosition(homeSettings->position);
            motor->moveToPosition(target);
            break;
        default:
            setPhase(Idle);
            return;
        }
    }

At runtime, onMotorStopped() is called and I see the following output, which indicates that phase is AtHome (4) on entry to the method.

Hstop 4

I expect the default case to execute, setting the phase to Idle but I do not see the output from setPhase(), which suggests that the default case isn't executing. Subsequent output from elsewhere in the code confirms that phase in fact remains set to AtHome (4) and isn't being set to Idle as expected.
I think I may have gone code blind. Can anyone see the issue?

One's going to std::cout (works). The other to Serial. I don't know std::cout on an Arduino...  Are you really running it on an Arduino?

Yes,  works surprisingly well. I should probably change thos to use one or the other and not mix them like that, but the Serial.println does produce output in other circumstances so it's not that the print statement isn't working.

I would try it with Arduino AVR core 1.6.21. Newer have problems

What happens if you put debug output (either way) on each case and default?


text:
What happens to serial output when no-one is listening?
This question probably needs a better title but I'm having trouble thinking of one! Please feel free to edit or suggest one.
My target system is a pair of Arduino Leonardos linked by XBee radios. One is the coordinator and is expected to communicate with a host PC over the USB connection (virtual serial port). The coordinator parses commands and potentially forwards them on to the endpoint by radio. The endpoint replies to commands and can also generate output spontaneously. Both devices can also send diagnostic output to the USB/Serial port. The endpoint sends "heartbeat" messages every 8 seconds. If the coordinator misses 2 consecutive heartbeats then it'll reinitialize. If the endpoint sends a heartbeat and doesn't get a response within a couple of seconds, then it will also reinitialize.
This all seems to work pretty well, but I've noticed something odd. If I connect to both devices with a terminal emulator and just watch the output, everything is good and the system is stable for at least 14 hours (the longest I've tested it). I can see the heartbeat messages happening and the diagnostic output coming out. However, as soon as I disconnect one of the serial ports, things begin to fail. The XBee comms state machine appears to time out at both sides and goes into an endless re-initialization loop.
I'm struggling to think why this might be, but disconnecting one of the serial ports reliably causes the issue within 10 to 20 seconds (I think the "no heartbeat" timeout is being hit).
It seems like if nothing is listening to the serial port, something is getting jammed up. My understanding is that its OK to read from and write to a port that nothing is connected to, and that data will just fall into the bitbucket. Is this not the case? Why should disconnecting the client from the serial port jam everything up?
UPDATE: I've tested with this modified "blink" sketch:
#include <Arduino.h>

auto& host = Serial;

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
  host.begin(115200);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
  host.print("Time ");
  host.println(millis());
}

With something (PuTTY) connected to the USB/serial port, I get a nice even mark-space ratio on the LED. As soon as I disconnect PuTTY, the 'off' period of the LED becomes about twice as long as the 'on' period, i.e. there is upwards of a second delay each time I write to the serial port. Is that normal?

It depends what the mystery devices you have that communicate over USB are and how they are programmed.

@Majenko, [arduino-leonardo]

@Juraj I never trust tags.

add some LED on/off code to aid debugging ...for example, LED on before serial comm and LED off after serial comm

Do you also read from serial? Eventually (un)plugging the serial port causes an edge on the receiving line which results in an arbitrary value. Depending on how you manage serial inputs on the arduino anything could happen

@jsotola that's a great idea, I think I will do that.

@SimSon yes I do (read from serial). My command parser is pretty bomb proof though so it shouldn't be an issue.

Arduino Leonardo uses its built-in USB to create "Serial Port". Probably that's why it's print acts differently than Arduino UNO. UNO has a separate IC for the virtual com.

OK so here is my solution.
I made a wrapper class called SafeSerial. In SafeSerial.h:
#pragma once
#include <Arduino.h>

class SafeSerial : public Serial_
    {
    size_t write(const uint8_t* buffer, size_t size) override;
    };

In SafeSerial.cpp:
/*
 * SafeSerial implementation for Arduino Leonardo.
 * Overrides the Serial_::write() method and checks that there is enough room
 * in the output buffer. If not, the output is discarded.
 * The intent is to prevent serial output from blocking when no host is listening.
 * All other operations are handed off to the underlying Serial_ instance.
 */

#include "SafeSerial.h"

size_t SafeSerial::write(const uint8_t* buffer, size_t size)
    {
    /*
     * Check if we can write without blocking. If we need to block,
     * then we assume that the host has disconnected.
     */

    if (availableForWrite() < size)
        return 0;

    return Serial_::write(buffer, size);
    }

In my sketch, in global scope:
SafeSerial host;

Now, because I'm using <ArduinoSTL> and all my output goes via std::cout, I need to take some actions to correctly configure that library. This requires modifying the library code per the instructions in the README.md file to make it not default to the built-in Serial instance and to not create default instances of cin and cout. This now needs to be done in the sketch, so (again in global scope):
// cin and cout for ArduinoSTL
namespace std
    {
    ohserialstream cout(host);
    ihserialstream cin(host);
    }

and in setup():
    host.begin(115200);
    // Connect cin and cout to our SafeSerial instance
    ArduinoSTL_Serial.connect(host);

...and finally, I have fully non-blocking Serial I/O even when the host has disconnected, at the risk of some possible data loss. However so far, in my application, data loss doesn't seem to be an issue as I only produce minimal terse output and generally only 1 line every few seconds.
Thank you all for your valuable input.

Theoretically, nothing should happen to serial data if nothing is listening.

For a traditional UART the data is just sent regardless. It doesn't need someone listening for that to happen.  Like a light doesn't need someone to see it for it to be on.
For USB CDC/ACM the data should be discarded even before it's attempted to be sent.

The latter, though, does rely on the host computer "playing ball" and cleanly closing the port properly.  On most operating systems that is handled by the OS and happens automatically. However on Windows it is handed off to the driver, and I guess the driver may even hand it off to the terminal software.
So in Windows there is a chance that when you disconnect your serial port it's not cleanly closing the connection and the USB thinks it's still connected, thus blocking waiting for the serial data to be collected.

I've updated my question with additional info and a simple test sketch. When I disconnect the serial port, I'm seeing something like a second delay every time around my loop.

OK let's try a different angle. It looks like I have a problem with serial output blocking even though there's nothing connected to the serial stream. If I were to write a new stream class that wraps the serial stream, maybe I could make manual checks to see if I should write the data to the underlying stream, or simply discard it. In that situation, what do you think I should check for?

@TimLong Well, the only thing you really can check is the CDC/ACM "Line State" - and the existing code already does that.

You could try looking at the returned value of Serial.availableForWrite() to see if there is enough buffer space...

https://www.arduino.cc/reference/tr/language/functions/communication/serial/availableforwrite/

That looks like it might be worth a try. Thanks for the input.


text:
Arduino connect programatically two wires of external 3.3V device

What is a missing puzzle in here, relay, transistor?
I would like to pull pin of external device to the ground programatically using arduino's digital pin.

Probably you are missing nothing. You can just connect the pins of the Arduino and your device. Writing LOW to that pin pulls it down to ground. Of course you still need to connect the grounds of both devices, just as you did in your image.
Though we cannot be sure, since you didn't give any information about the device. Important would be, if the pin of the device is limiting the current flowing through it. Probably its an input pin with a pullup resistor, thus safe. But if its a pin that provides higher currents (more than 20mA) when connected to ground, you would basically create a short through the Arduinos digital output hardware, which in turn could be fried.
So check your device before implementing it.


text:
Need Help Communicating with Arduino Leonardo Using Custom Bootloader
I have an Arduino Leonardo that has been flashed with a custom bootloader, and it currently has a sketch on it that I cannot replace or modify because doing so would brick the board. The board works and communicates perfectly with a specific software (which I don’t have the source code for), but I want to communicate with it myself and eventually write my own program to interact with the board.
What I Know:

Bootloader works fine, and the Arduino communicates with another executable.
Baud rate for communication is 57600.
I can’t upload new code to the board (due to fear of bricking it), but I want to send and receive commands.
The owner told me that it uses a mouse parser and HID raw reports. While I could have asked the owner how to communicate with it, I was told that if I can figure out how to use it, he will be okay with it and have no problem but will not tell me directly how to do it.

What I Have Tried:

Using PuTTY to connect via the correct COM port and baud rate (57600), but all I see is a blank terminal, and I can't send or receive data.
Tested different terminal programs (Tera Term, CoolTerm), but the result is the same: no response from the Arduino.
Verified serial settings (8 data bits, 1 stop bit, no parity, no flow control) across all terminals.
Looked into capturing USB traffic between the working executable and the board to understand the protocol, but I haven't been successful so far.
I tried different baud rates (9600, 115200) just in case, but 57600 seems to be the right one.

My Goal:
I want to figure out how to connect to the bootloader or current firmware and communicate with the board using serial commands, so I can eventually write my own software to replicate the functionality of the existing executable.
Any advice on how I can proceed from here? Is there a way to reverse-engineer the communication protocol from the executable? Is there a better tool or method to explore the serial communication?
I looked into Wireshark and I see responses from Arduino aka mouse but still not sure how can that help me make own commands.

Re “Looked into capturing USB traffic between the working executable and the board”: this looks like the most sensible approach. You may try using Wireshark for this.