text:
Input Capture Pin Atmel ATmega328P
I have some code that relies on the input capture timer value.
I assume the timer value (as defined by the pre-scaler etc) is not affected by other code running i.e. it is updated every nth clock regardless of what instruction is next?
If you want code or more detail ask in comments and I will post code.

The way IC typically works is completely independent from the CPU and what instructions you are running.
The timer runs freely between the start and end input capture events. At the moment of capture the timer value is frozen into another register. The interrupt is then triggered. You then read that frozen value. It doesn't matter how long after the end event the interrupt executes, or what you do in that interrupt, the captured time is still the same.

Hello @Majenko - thanksfor answer. A quick one though. What happens if during the interrupt the interrupt is fired again faster than the code can run i.e. still responding to the interrupt when interrupt is fired again? I assume it is over-written and we have a loss of data?

The interrupt cannot trigger while it is current triggered. The CPU disables interrupts when it enters an interrupt and enables them afterwards. Any events that occur while the interrupt is running will be ignored.

I assume the timer value (as defined by the pre-scaler etc) is not affected by other code running i.e. it is updated every nth clock regardless of what instruction is next?

yes, unless your code writes to the registers involved.

Aren't there any higher priority Interrupts?  They would certainly affect the timer register

@cyberponk No, registering input capture time works via dedicated hardware, idependent of what the CPU is doing.


text:
How to get my water pump to turn off and on with the moisture level?
I am trying to built an automatic plant watering system with my arduino. I have an LCD display screen that outputs the moisture level, a moisture sensor and a water pump with a relay. I have been trying to get the water pump to read the moisture data and if it reads lower that 60 to turn on the pump for 10 seconds and then turn the pump off until it reads the moisture again to see if it needs more water. However I am unable to get my water pump to turn off. Is it not reading the moisture sensor?
String writeAPIKey = "dCFFuwutXLRoHKQNqbIXrP";  //Put your ThingSpeak Write API key here.
unsigned int interval = 60000;  //Update every Minute
long int now=0, previous=-50000; //Used to hold time variables.
#define DST_IP "maker.ifttt.com"  //Thingspeak Server

//LCD display
//Load libraries
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

 //Define address for the Serial LCD display.
#define I2C_ADDR  0x27  //If 0x3f doesn't work change this to 0x27
#define BACKLIGHT_PIN  3

//Initialise the Serial LCD.
LiquidCrystal_I2C lcd(I2C_ADDR, 2,1,0,4,5,6,7); //These pin numbers are hard coded in on the serial backpack board.

// Moisture sensor
int moistureSensor = A3; // moisture sensor is plugged into A3 on the arduino
int data; // Used to store data from user
int waitTime = 1000;

// water pump
int pumpPin = 8; // water pump
int waterTime = 10; // 10 seconds watering time

void setup() { // put your setup code here, to run once:
  // Moisture Sensor
    Serial.begin(9600);

// LCD display
lcd.begin (16,2);     //Initalize the LCD.
lcd.setBacklightPin(3,POSITIVE);//Setup the backlight.
lcd.setBacklight(HIGH); //Switch on the backlight.
lcd.clear();
lcd.setCursor(0,0);   //go to first column  and first line (0,0)
lcd.print("Hello - Arnold");     //Print at cursor Location
lcd.setCursor(5,1);   //goto first column and second line
delay(1000);

// pump
pinMode(pumpPin, OUTPUT);

 // Wifi
  Serial.begin(9600);  // Open serial Connection to Computer
  Serial1.begin(115200);  // Open serial Connection to ESP8266
  Serial.println("IFTTT Maker");
  Serial1.println("AT+RST");  //Issue Reset Command
  Serial.println("AT+RST");
  delay(1000);

  //DEBUG LOOP- display ESP output to serial Monitor.
  while (Serial1.available()) {
  Serial.println(Serial1.read());
  }
  Serial.println("AT+CWMODE=1");
  Serial1.println("AT+CWMODE=1");  //Set single client mode.
  delay(5000);

  Serial.println("AT+CIFSR");
  Serial1.println("AT+CIFSR"); //Display IP Information

  //DEBUG LOOP- display ESP output to serial Monitor.
  while (Serial1.available()) {
  Serial.println(Serial1.read());
  }
  delay(1000);

  Serial.println("AT+CIPMUX=0");
  Serial1.println("AT+CIPMUX=0");  //Sets up Single connection mode.
  delay(1000);

  //DEBUG LOOP- display ESP output to serial Monitor.
  while (Serial1.available()) {
    Serial.write(Serial1.read());
  }
  delay(1000);

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

    // Moisture
    delay(waitTime);
    data = analogRead(moistureSensor);
    data = map(data, 0, 1023, 0, 100);
    Serial.println(data);

    // LCD
    for(int count = 0; count < 15; count++) {
    lcd.clear();
    lcd.setCursor(7,0);
    lcd.print(data);
    delay(500);
      }

    // pumpPin
    if (moistureSensor <= 60) {
    digitalWrite(pumpPin, HIGH);
    delay(waterTime*1000); // on for 10 seconds
    digitalWrite(pumpPin, LOW);
    delay(waitTime);

    } else if (moistureSensor >=65) {
        digitalWrite(pumpPin, LOW);
        delay(waitTime);

    }

// IFTTT
  now=millis(); //Get the current time.
//Check to see if it's time to run.
if(now - previous >= interval){
  previous = now;
  Serial.println("Running Update");
  updateThingSpeak();
   }
}

void updateThingSpeak(){

  int moisture = analogRead(moistureSensor); //Read the moisture

   //Builds the connection string for the ESP8266
    String cmd = "AT+CIPSTART=\"TCP\",\"";
    cmd += DST_IP;
    cmd += "\",80";
    Serial1.println(cmd);  //Run the command
    Serial.println(cmd);    //Print this to the debug window
    delay(1000);

    //DEBUG LOOP- display ESP output to serial Monitor.
    while (Serial1.available()) {
    Serial.write(Serial1.read());
    }

   //I NEED TO UPDATE THIS IF STATEMENT TO MAKE SURE CONNECTION WORKED
  //if (client.connect(thingSpeakAddress, 80)){
    String httpcmd="GET/trigger/arnold_the_plant/with/key/dCFFuwutXLRoHKQNqbIXrP?";
    httpcmd += "value1=";
    httpcmd += moisture;
    httpcmd += " HTTP/1.1\r\n";
    httpcmd += "Host: maker.ifttt.com\n";
    httpcmd += "Connection: close\r\n\r\n";

    Serial.print("AT+CIPSEND=");
    Serial.println(httpcmd.length());

    Serial1.print("AT+CIPSEND=");
    Serial1.println(httpcmd.length());
    delay(1000);

    Serial.print(">");
    Serial1.println(httpcmd);
    Serial.println(httpcmd);
    delay(3000);

    //DEBUG LOOP- display ESP output to serial Monitor.
     while (Serial1.available()) {
      Serial.write(Serial1.read());
      }

    Serial.println("AT+CIPCLOSE");
    Serial1.println("AT+CIPCLOSE"); //Close the Web Connection

   } // end of void loop

My absolute lack of ever using Arduinos might make me wrong here, and it is possible with the weird that is their libraries, but assuming your MoistureSensor outputs a voltage and the A3 definition is some sort of pin enumeration, should you not be reading with AnalogRead(moistureSensor)? To my tired eyes it looks like you're just comparing 60 and 65 to the fixed value of "A3". Edit:: In fact, you're comparing the pin, whilst you also read it into the moisture variable. Typo I assume?

Probably unrelated to your question, but in httpcmd you need a space after "GET" and a \r after "maker.ifttt.com".

Invert logical level on the pin that controls water pump.
// pumpPin
if (moistureSensor <= 60)
 { digitalWrite(pumpPin, LOW );
 delay(waterTime*1000);
 // on for 10 seconds
 digitalWrite(pumpPin, HIGH);
 delay(waitTime); }
else if (moistureSensor >=65)
 { digitalWrite(pumpPin, HIGH);
 delay(waitTime); }

I'm sorry I am really new to this. What do you mean by this?

In if condition it says that whenever your moisture sensor detects some desired level means a level when you turn OFF your water pump and then wait for 10 seconds as written and then again turn ON your water pump.

And In else if condition your moisture sensor detects some value more then some another desired level then your motor pump is always ON.

I short, here we set two desired level means 60 and 65.Whenever your moisture sensor detects value which is less than and equal to 60 then your motor pump stop and runs 10 seconds and then motor pump start. And If your moisture sensor detect value which is more then 65 then your motor pump is always ON.

source: Stack Exchange

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

sort: votes


text:
Why doesn't my mcp23s17 interrupts work anymore?
I'm using a teensy 4.0 with two mcp23s17 gpio expanders where #1 has 16 buttons wired to it, and #2 has 4 buttons and six rotary encoders. To run everything I'm using majenkos mcp23s17 library. Recently, I refactored my code, and suddenly I'm unable to setup the mcp's to have interrupts working properly.
I've tried to narrow the problem down by commenting out code, and it appears that as soon as I call         gpioExpander.enableInterrupt(pin, CHANGE); in gpioSetup() the problem occurs. In detail, loop() runs fine, but as soon as I press a button, the teensy hangs. Also, to restore the teensy I have to upload the code with the call to gpioExpander.enableInterrupt(pin, CHANGE); commented out in order to have the teensy up and running again.
I've been staring myself blind on the code, and I suspect I'm missing something obvious. Your help is appreciated.
//main.cpp
#include <Arduino.h>

#include "GPIO.h"
#include "MCP23S17.h"

extern MCP23S17 gpioExpander1;
extern MCP23S17 gpioExpander2;

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

void loop() {
    GPIOtest(gpioExpander1, gpioExpander2);
}

//GPIO.h
#ifndef GPIO_H
#define GPIO_H

#include <Arduino.h>

#include "MCP23S17.h"

constexpr uint8_t address = 0;
constexpr uint8_t interruptPin1 = 8;
constexpr uint8_t interruptPin2 = 22;
constexpr uint8_t chipSelectPin1 = 7;
constexpr uint8_t chipSelectPin2 = 21;

void setGPIO1Pins(MCP23S17 &gpioExpander);
void setGPIO2Pins(MCP23S17 &gpioExpander);
void gpioSetup();
void GPIO1interrupt();
void GPIO2interrupt();
void GPIOtest(MCP23S17 &gpioExpander1, MCP23S17 &gpioExpander2);

#endif

//GPIO.cpp
#include "GPIO.h"

#include <Arduino.h>
#include <MCP23S17.h>

volatile bool interruptFlag1 = false;
volatile bool interruptFlag2 = false;

MCP23S17 gpioExpander1(&SPI, chipSelectPin1, address);
MCP23S17 gpioExpander2(&SPI, chipSelectPin2, address);

//  Set all Port Expander pins to desired mode INPUT_PULLUP
//  Set all Port Expander input pins interrupts
void setGPIOPins(MCP23S17& gpioExpander) {
    for (uint8_t pin = 0; pin <= 15; ++pin) {
        gpioExpander.pinMode(pin, INPUT_PULLUP);
        gpioExpander.enableInterrupt(pin, CHANGE);
    }

    // set Port Expander Interrupt configuratons
    gpioExpander.setMirror(true);
    gpioExpander.setInterruptOD(false);
    gpioExpander.setInterruptLevel(LOW);
}

void gpioSetup() {
    gpioExpander1.begin();
    gpioExpander2.begin();
    digitalWrite(chipSelectPin1, HIGH);
    digitalWrite(chipSelectPin2, HIGH);

    pinMode(interruptPin1, INPUT_PULLUP);
    pinMode(interruptPin2, INPUT_PULLUP);

    attachInterrupt(digitalPinToInterrupt(interruptPin1), GPIO1interrupt, LOW);
    attachInterrupt(digitalPinToInterrupt(interruptPin2), GPIO2interrupt, LOW);

    setGPIOPins(gpioExpander1);
    setGPIOPins(gpioExpander2);

    // GPIO registers are read to be cleared
    gpioExpander1.getInterruptValue();
    gpioExpander2.getInterruptValue();
}

void GPIO1interrupt() {
    interruptFlag1 = true;
}

void GPIO2interrupt() {
    interruptFlag2 = true;
}

void GPIOtest(MCP23S17& gpioExpander1, MCP23S17& gpioExpander2) {
    if (interruptFlag1 == true) {
        Serial.println("interrupt 1 = true");
        interruptFlag1 = false;
    }

    if (interruptFlag2 == true) {
        Serial.println("interrupt 2 = true");
        interruptFlag2 = false;
    }
}

Short version, try:
attachInterrupt(digitalPinToInterrupt(interruptPin1), GPIO1interrupt, FALLING);
attachInterrupt(digitalPinToInterrupt(interruptPin2), GPIO2interrupt, FALLING);

FALLING (instead of LOW) being the active ingredient. I'm assuming FALLING is supported. If not you can try synthesizing this with CHANGE and reading the port to see whether or not it is currently LOW.
And then call .getInterruptValue(); to clear the MCP23S17's interrupt condition where you clear the global volatile flags:
void GPIOtest(MCP23S17& gpioExpander1, MCP23S17& gpioExpander2) {
    if (interruptFlag1 == true) {
        Serial.println("interrupt 1 = true");
        interruptFlag1 = false;
        gpioExpander1.getInterruptValue(); // <------
    }

    if (interruptFlag2 == true) {
        Serial.println("interrupt 2 = true");
        interruptFlag2 = false;
        gpioExpander2.getInterruptValue(); // <------
    }
}

Long version:
This a guess, since I'm unable to test. But this is maybe not a bad guess:
You have configured the MCP23S17 device to drive active low on/during an MCP23S17 interrupt condition:
    gpioExpander.setMirror(true);
    gpioExpander.setInterruptOD(false);
    gpioExpander.setInterruptLevel(LOW);

So, were an MCP23S17 interrupt to occur (gpioExpander.enableInterrupt(pin, CHANGE);), the interrupt flag within the MCP23S17 would be set, and INTA/INTB of the MCP23S17 would become active low.
The MCP23S17 datasheet says:

The interrupt condition is cleared after the LSb of the data is
clocked out during a read command of GPIO or INTCAP

You have configured your interrupt pins for interrupting on a LOW level interrupt:
attachInterrupt(digitalPinToInterrupt(interruptPin1), GPIO1interrupt, LOW);

So, if I understand this correctly, your Teensy continually re-enter the GPIO#interrupt() functions until something read causes the interrupt condition to be cleared. You are not clearing the interrupt condition inside the ISR, you're setting a flag to do that later in the main line of execution, which is reasonable by itself. One thing I can guess is that had you'd previous had something to clear the interrupt condition inside the interrupt and it is now outside the interrupt, namely your call to .getInterruptValue(), which reads the INTCAP register mentioned above. Or perhaps you'd be using one of the functions that reads a pin/port that would have cleared the interrupt condition. Clearing the global variable alone will not clear the interrupt condition, and so you're going to go right back into ISR which will reassign the global variable.
An AVR will execute a single instruction outside of the ISR before reentering the ISR. So the effect of remaining in the interrupt condition is to make your code slow, potentially very slow. I don't know off the top of my head what the Teensy 4.x core will do in this case. Either way, it would lock up or possibly look locked up.
If you were reading/getting-interrupt-value inside the ISR it would have cleared it and so it would not re-entered the ISR repeatedly. Or rather, it wouldn't do that in definitely (or just for long). It possible that the Teensy is so much faster that it might re-enter a few times until the MCP23S17 got around to acknowledging that the interrupt condition had be cleared. I'm not advocating for this so, so I'll leave it at that.
I believe ultimately what you want is to set a FALLING edge interrupt:
attachInterrupt(digitalPinToInterrupt(interruptPin1), GPIO1interrupt, FALLING);

Anyway, with FALLING the initial falling edge of the INTA/INTB line sets the interrupt condition in the Teensy (not MCP23S17) but it is cleared when your ISR executes.  So you will not keep re-entering the ISR. So your ISR will enter once to set the global volatile flag. Later when you pick up on the set value of your global volatile flag(s), you need to call .getInterruptValue() (or otherwise read a pin) to clear the interrupt condition in your MCP23S17 (not Teensy) which will de-assert/raise INTA/INTB, at which point the ISR in the Teensy is ready for to get trigger by another falling edge of INTA/INTB.
It's also probably possible to do this with a LOW-level interrupt, but you'd have keep un-configuring them in the ISR and re-configuring them after you clear the MCP23S17's condition. Not sure that would be recommended. But, I think it's possible.

You've really pinpointed where I went wrong. Your keen eye has helped me in the right direction. Appreciate it a lot!

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


text:
I2C sensor hogs the bus with empty write commands
I am trying to read data from a pair of TLE493-W2B6 magnetic position sensors [1, 2] with Arduino over I2C. I can read from each sensor individually, using the Arduino library from the manufacturer [3, with corrections from 4], but when I try to read both sensors, I can only read the first sensor I initialize. The first sensor then issues empty write commands, and the second sensor NACKs when I try to address it. The sensors have different factory-programmed addresses, and they are connected to the same I2C bus on a PCB with pullup resistors. When I scan the bus for I2C devices, both sensors show up (ie they both ACK their own address).
How do I read both sensors over I2C with Arduino?
Code for reading both sensors:
#include <Tle493d_w2b6.h>

Tle493d_w2b6 sensor_A0 = Tle493d_w2b6(Tle493d_w2b6::MASTERCONTROLLEDMODE, Tle493d_w2b6::TLE493D_W2B6_A0);
Tle493d_w2b6 sensor_A1 = Tle493d_w2b6(Tle493d_w2b6::MASTERCONTROLLEDMODE, Tle493d_w2b6::TLE493D_W2B6_A1);

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

  sensor_A1.begin();
  sensor_A0.begin();
}

void loop() {
  sensor_A1.updateData();
  Serial.print(sensor_A1.getX());
  Serial.print(", ");
  Serial.print(sensor_A1.getY());
  Serial.print(", ");
  Serial.println(sensor_A1.getZ());

  sensor_A0.updateData();
  Serial.print(sensor_A0.getX());
  Serial.print(", ");
  Serial.print(sensor_A0.getY());
  Serial.print(", ");
  Serial.println(sensor_A0.getZ());

  delay(500);

}

Here is what the average cycle looks like:

(0.005ms) Read the first six registers of sensor A1.

Address frame =  0x22
R/W = R
Data frames = FF 00 FF 80 F1 1F 6A~ (this is as expected)

(0.828ms) Library sends empty write command to sensor A1?

Address frame =  0x22
R/W = W
Data frames = empty

(2.281ms) Attempt to read the first six registers of sensor A0, address is NACK'd, no data is returned.

Address frame =  0x35~
R/W = R
Data frames = empty

(2.353ms) Library sends another empty write command to sensor A1.

Address frame =  0x22
R/W = W
Data frames = empty

There seems to be something wrong at the fundamental I2C protocol execution. There are no empty writes or reads in the library (I think this isn't even possible with the Wire library, which is used there). Also the spike at the end of the 0x44 write span (as in the image) is suspicious. The sensor is operating at 3.3V. Do you use a 3.3V Arduino? You didn't specify

I was using the 5V rail on the Arduino to power the sensors. I replaced the sensors, and I am now powering them off the Arduino's 3.3V rail, with the Arduino's internal I2C pullups disabled and external pullups to the 3.3V. Still having the same issue. I am going to try sending bits with an I2C host adapter, to see if it's a problem on the Arduino side.

By default the sensor adds trigger bits to the register address, so I'm having some trouble communicating with the device. I'm having some trouble getting the right initialization sequence.

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


text:
Set the wall clock time or change GMT offset without ntp server?
I have been able to get the current time from an NTP server and set what appears to be an internal clock using the configTime() function from the ESP32 core.  I can then get the current time with the function getLocalTime().
I would like to be able to set the time returned by getLocalTime() from user input rather than from an NTP server.  I would also like to be able to update the GMT Offset without needing to reconnect to the server.
How do I interact with the clock value used by getLocalTime()? Is there documentation for this clock somewhere?

per request the SimpleTime example from the ESP32 install:
#include <WiFi.h>
#include "time.h"

const char* ssid       = "YOUR_SSID";
const char* password   = "YOUR_PASS";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

void printLocalTime()
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}

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

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  Serial.println(" CONNECTED");

  //init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  printLocalTime();

  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}

void loop()
{
  delay(1000);
  printLocalTime();
}

Check out this library I wrote
https://github.com/fbiego/ESP32Time

The functions configTime and getLocalTime are from ESP32 core file esp32-hal-time.c. This wraps the ESP32 SDK functions. You can use the SDK functions to set the time and zone. They work with the RTC peripheral of the ESP32.
You can use setTimeZone to set the time zone.
The time.h is standard C time library. The ESP32 SDK makes it to work with the built in RTC (reference). To set the time it gets complicated. You would have to use undocumented SDK time functions.


text:
How to resolve my Timer Interrupt issue
I am trying to work with arduino timer1 interrupts to make an led blink every bit on an 8 bit number, depending on whether its a 1 or 0. However, im trying to make a basic blinking program, and it does not seem to be working.
#include “TimerOne.h”
bool val=0;
void setup()
{
    pinMode(13, OUTPUT);
    Timer1.initialize(500000); // initialize timer1, and set a 1/2 second period
    Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
}

void callback()
{
    val=1;
}

void loop()
{
    digitalWrite(13,val);
    while(!val);
    val=0;
}

The LED doesnt blink at all! Any help would be appreceitated!
thanks!

Try this instead.
#include “TimerOne.h”
bool val=0;
void setup()
{
    pinMode(13, OUTPUT);
    Timer1.initialize(500000); // initialize timer1, and set a 1/2 second period
    Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt
}

void callback()
{
    val=!val;
}

void loop()
{
    digitalWrite(13,val);
}

I'm not surprised the LED doesn't blink - the entirety of your logic in the loop() function is so bizarre as to elicit the question:
WTF?
Let's take a look at it line by line:
digitalWrite(13,val);

Set the LED to whatever val is - val starts as 0, so the LED is off.
while(!val);

While val is not anything except 0, so while val is zero, do nothing. (The interrupt would escape you from this if your val was volatile)
val=0;

Set val to 0.
So how can val be anything except 0 when you do the digitalWrite?

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


text:
For loop question-Simulating a robot' s movement on a 2d array
i' m trying to simulate a robot' s movement on a 2d array. In my case, robot goes forward firstly, if it sees a engel, it turns left and continues its movement. The problem is that, i could not present turning left and moving on left-direction on the initial matrix.
Here' s my code:
#include <Servo.h>
#define x 7                                         //Matrix dimensions
#define y 7

const int trigPin = 12;
const int echoPin = 11;

Servo myServo;                                     //variable definations
Servo myServo2;

int pos = 0;

int counter;
int counter1 = 0;
int counter2;
int counter3;

int integer;
int integer2;
int integer4;

long duration;
long distance;

void setup() {
    Serial.begin(9600);
    myServo.attach(9);
    myServo2.attach(10);
    pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
    pinMode(echoPin, INPUT); // Sets the echoPin as an Input
}

void loop() {
    int my2dArray[x][y] = {                          // initial matrix
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 0, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 1, 1, 1},
    };
    // Clears the trigPin
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
    duration = pulseIn(echoPin, HIGH);
// Calculating the distance
    distance = duration * 0.034 / 2;
    int robot = my2dArray[3][3];                   // first place of robot

    if (counter1 > 0) {
        for (integer = 0;  integer < counter1; integer += 1) {
            if (distance < 10) {                                  //seeing     the object
                for (pos = 0; pos <= 180 ; pos += 1) {              //turning left
                    myServo.write(pos);
                }

                for (pos = 0; pos <= 180  ; pos += 1) {            //moving on after turning
                    myServo.write(pos);
                    myServo2.write(pos);

                    if (pos == 180) {
                        counter3 +=  1;
                    }
                }

                Serial.println(integer);

                for (integer4 = 0;  integer4 < counter3; integer4 += 1) {     //modifying matrix if there is an object
                    my2dArray[3 + integer][3 + integer4] = robot * my2dArray[3 + integer][3 + integer4];
                }

                Serial.println("Break condition.");
                break;
            } else {
                my2dArray[3 + integer][3] = robot * my2dArray[3 + integer][3];    //modifying matrix in case of there is no object
            }
        }
    }

    for (integer2 = 0; integer2 < 7; integer2++) {                          //displaying matrix
        Serial.print(my2dArray[integer2][0]);
        Serial.print("|");
        Serial.print(my2dArray[integer2][1]);
        Serial.print("|");
        Serial.print(my2dArray[integer2][2]);
        Serial.print("|");
        Serial.print(my2dArray[integer2][3]);
        Serial.print("|");
        Serial.print(my2dArray[integer2][4]);
        Serial.print("|");
        Serial.print(my2dArray[integer2][5]);
        Serial.print("|");
        Serial.println(my2dArray[integer2][6]);
    }

    Serial.println();

    for (pos = 0; pos <= 180  ; pos += 1) {                               // moving forward as first movement
        myServo.write(pos);
        myServo2.write(pos);

        if (pos == 180) {
            counter1 +=  1;
        }
    }

    delay(1000);
}

The problem part is:
for (integer4 = 0;  integer4 < counter3; integer4 += 1){      //modifying matrix if there is an object

    my2dArray[3 + integer][3+integer4] = robot * my2dArray[3 + integer][3+integer4];

     }

"integer" value does not change in the problem part, it' s always 0 in despite of the first for loop. How can i pass the "integer" to the problem part properly?

Those variable names are really confusing. You really should name them after what they represent, not the data type that is in them.

Also you really should learn to format your code properly. It makes it so much easier to follow. I have done it for you this time, but you really do need to learn about proper indenting.

Your program is hard to follow with all those meaningless "integer" and "counter" variables, and the logic seems a little odd in places, but I believe the cause of your problems is the break statement:
for (integer = 0; integer < counter1; integer += 1) {
    if (distance < 10) {
        // ...
        for (integer4 = 0;  integer4 < counter3; integer4 += 1) {     //modifying matrix if there is an object
            my2dArray[3 + integer][3 + integer4] = robot * my2dArray[3 + integer][3 + integer4];
        }
        break; // << HERE
    } else {
        // ...
    }
}

What is the purpose of that break? I think you are using it to jump out of the if so that it doesn't run the else, which it won't run anyway since it's an else condition. Instead, what the break is actually doing is terminating the for loop after the first iteration that hits that inner if condition. That is, as long as the distance is less than 10 it will only ever run the for once, and so integer will only ever be 0.


text:
Optocouplers for Arduino DCC decoder - Explain?
I am trying to make an Arduino circuit as outlined here.

This is for connecting an Arduino input to a DCC system. DCC is a command control system for model railways that uses the same two wires for power and data (there's a wikipedia article that explains it better than I can)
I'm wondering what the optocoupler has more than 4 pins for? I'm new to this and I understand the purpose of the optocoupler but I am confused as to how this particular one works. It is a 6N136 optocoupler. I don't understand why it has the extra pins compared to 4 pin optocouplers, and I don't understand how it would read the polarity of the signal. DCC sends commands using polarity as I understand it, so I know I need to read the polarity, but how does the optocoupler do it here?
I have a very limited knowledge of electronics right now so pardon anything stupid I said :P

I also built this circuit but sometimes my R1 1K resistor gets hot and nothing works. I have a dcc Roco Multim.10765 on the dcc side. I can't find what causes, you have an idea?

That specific chip (the 6N137) uses a more efficient IC detector rather than a simple transistor junction.  It also has an "enable" pin that allows it to be turned on or off.  Consequently it needs a power supply to run it. That all means extra pins.
This design allows for higher speed communication (it's a 10Mbaud chip) with less leakage when compared to a traditional design.
The pin VE (pin 7) needs to be pulled up to make the chip work (the job of R2) and the output is pulled high (it's open drain) by R3.
The optocoupler will be on with one polarity and off with the other. It's as simple as that. The diode D1 protects the LED in the optocoupler from the reverse voltages.

Out of curiosity, why does a diode need to be protected by a diode? (LED = Light Emitting Diode).

Reverse voltages on fragile optocoupler LEDs can break them, so by providing a low resistance path to cut out the reverse voltage you stop the led from being damaged.

So if I'm understanding this right, if I run AC current through there, then whenever it's in the reverse polarity of the LED, it will read as off because the LED inside will be off since its a diode?

Pretty much, yes. Except it's open drain, so it will be LOW when it is on.


text:
trying to use millis()
I'm learning how to use the millis() function. Instead of having it in the main body of the program I wanted to place it in a function so I can change the time interval with which an led will flash. I modified the code blinkWithoutDelay. My code is below. The output I get is an LED that is always on. I did print the output of the ledState to the serial monitor. Its changing from on to off repeatedly. So I think the led is really flickering too fast to see. I took a screenshot from the serial monitor. The output is below.
const int LED2 = 2;
int ledState2 = LOW;

void timeCheck(int interval)
{
    unsigned long cMillis = millis();
    unsigned long pMillis;

    if (cMillis - pMillis > interval)
    {
        pMillis = cMillis;

        if (ledState2 == LOW)
        {
            ledState2 = HIGH;
        }
        else
        {
            ledState2 = LOW;
        }
        digitalWrite(LED2, ledState2);
        Serial.println(ledState2);
    }
}

void setup()
{
    Serial.begin(9600);
    pinMode(LED2, OUTPUT);
}

void loop()
{
    unsigned long flashtime = 1000;
    timeCheck(flashtime);
}

The problem here is that the variables you declare in your function are not static. The rest of the code works as expected.
Where you declare the variables at the beginning of your function is correct. There is only one variable in question though as it is the cause of the error you are seeing.
What you need to do is change the variable
unsigned long pMillis;

to
static unsigned long pMillis = 0;

By not having the pMillis as a static variable, each time the function is called the value of pMillis is undefined, which means it is unpredictable whether  (cMillis - pMillis > interval) will be true or false. But with the static declaration the Arduino knows to keep the previous value for the next time you call the function.
An excerpt from Wikipedia:

In computer programming, a static variable is a variable that has been allocated statically—whose lifetime or "extent" extends across the entire run of the program....
A static local variable is different from a local variable. It is initialized only once no matter how many times that function in which it resides is called.

each time the function is called pMillis is set to 0 - it's actually undefined, not zero.

@NickGammon    thank you that is a bit more accurate, but it is still loosing whatever value it was before.

Absolutely. I just wanted to clarify that you couldn't rely upon that declaration having an initial value of zero. In fact, if you make it static then it will have an initial value of zero, which might help.

@NickGammon    thanks Nick. I changed it to be clearer/accurate.

It seems you still did not grasp the idea of pMillis being undefined. By writing “that means the if (cMillis - pMillis > interval) will always be true.” you are are making implicit assumptions on pMillis. I edited the answer to make clear you cannot know the result of the test.

Thank you to everyone for your input. I've read about declaring a static variable before but it didn't make sense to me. I do understand how it works now and see it in action. Thank you again.

Put it out, so it will be global. LedStaye should be bool:

const int LED2 = 2;
bool ledState2 = LOW;
unsigned long pMillis;
void timeCheck(int interval)
{
    if (millis() - pMillis > interval)
    {
        pMillis = millis();
...

Did you test this?  I do not think millis() can be called inside the if logical test

You have used pMillis variable locally. Thats why when you call the function, pMillis initialized as 0. So set pMillis variable globally.


text:
calling a timer when a button is pushed
I'm trying to call a function to keep an LED on for a certain amount of time. The function is called when the button is pushed but the LED stays on. I used the same code in the void loop before moving it into a function and it worked.
const int ledPin2 = 2;
const int buttonPin7 = 7;
const unsigned long onTime = 1000;
unsigned long previousMillis = 0;

//
void timer(){
    unsigned long currentMillis = millis();
    digitalWrite(ledPin2, HIGH);

    if (currentMillis - previousMillis >= onTime){
        digitalWrite(ledPin2, LOW);
        previousMillis = millis();
    }
}

void setup(){
    Serial.begin(9600);
    pinMode(ledPin2, OUTPUT);
    pinMode(buttonPin7, INPUT);
}

void loop(){
    int buttonState = digitalRead(buttonPin7);
    if (buttonState == HIGH) timer();
}

Are you trying to create a monostable multivbrator?

When your code:
if (currentMillis - previousMillis >= onTime){
    digitalWrite(ledPin2, LOW);
    previousMillis = millis();
}

was in the loop, it was executed multiple times, so when if (currentMillis - previousMillis >= onTime) eventually became true, it would set ledPin2 LOW again.
Now that you moved it to the timer funtion, it only gets executed once (and if (currentMillis - previousMillis >= onTime) never gets a chance to become true).
You need to introduce a loop in the timer function. It also looks like you have your currentMillis / previousMillis messed up. I think you are looking for something like this:
void timer(){

    unsigned long previousMillis = millis();
    unsigned long currentMillis = millis();
    digitalWrite(ledPin2, HIGH);

    while((currentMillis - previousMillis) < onTime) {
        // wait for a bit
        sleep(10);
        // update currentMillis
        currentMillis = millis();
    }

    digitalWrite(ledPin2, LOW);
}

This did work really well. I do have an issue though. I setup another button and LED and used the same code while changing the variable names. If the second button was pressed when the first LED was on the second LED wouldn't turn on. If the first LED was off then the second would turn on if the second button was pressed.

Ask a new question, and post your code...

Your code says
if (buttonState == HIGH) timer();

So... what will it do if buttonstate is LOW? Sorry, but the answer is "nothing". You don't have any code to tell it what to do when the button is in the opposite state.
What you should do is check the button, and if it's pressed (whether that's HIGH or LOW depends on your circuit), then light the LED and start the timer (assign to previousMillis).
Then, regardless of the state of the button, check to see if currentMillis - previousMillis >= onTime. If it is, then turn off the LED.

I had the LED write low in the timer function. The button was just calling the function and when the time elapsed it would tell the ledPin to write LOW.


text:
using millis() for a timer
Basically the user presses a button and cycles thru 3 different modes. Mode 1 the LED is on, mode 2 the LED is off and mode 3 the LED is kept on for a certain amount of time. I'm using the millis() to keep track of the time. the LED in the third mode just stays on and never switches to off. I have the Serial.Writes in there to help me debug. I have the delay after the button read since if I didnt put it in it would register a lot of button presses.
int ledPin = 5;
int buttonApin = 9;
int ledMode = 0;

boolean lastButton = HIGH;
boolean currentAButton = HIGH;

// debounce button
boolean debounceFUNC(boolean last)
{
    boolean current = digitalRead(buttonApin);
    if (last != current)
    {
        delay(5);
        current = digitalRead(buttonApin);
    }
    return current;
}

void setMode(int ledMode)
{
    // turns on led
    if (ledMode == 1)
    {
        digitalWrite(ledPin, HIGH);
    }
    // turns off led
    if (ledMode == 2)
    {
    digitalWrite(ledPin, LOW);
    }
    // timer - turns off after 5000
    if (ledMode == 3)
    {
        long interval = 5000;
        unsigned long cMillis = millis();
        static unsigned long pMillis;

        if (cMillis - pMillis > interval)
        {
        pMillis = cMillis;
        digitalWrite(ledPin, HIGH);
        Serial.println("On");
        Serial.println(interval - cMillis);
        }
        else
        {
        digitalWrite(ledPin, LOW);
        Serial.println("Off");
        }

        }
    }

void setup()
{
    Serial.begin(9600);
    pinMode(ledPin, OUTPUT);
    pinMode(buttonApin, INPUT_PULLUP);
}

void loop()
{
    // sets led mode
    currentAButton = debounceFUNC(lastButton);
    delay(500);
    if (currentAButton == LOW)
    {
        ledMode++;
        Serial.println(ledMode);
    }
    else if (ledMode > 3)
    {
        ledMode = 0;
    }
    // ledMode function call
    setMode(ledMode);
}

screenshot of the serial monitor.

I can't spot the question here.

The problem is in the logic, basically your statement:
    if (cMillis - pMillis > interval)
    {
       pMillis = cMillis;
       digitalWrite(ledPin, HIGH);
        Serial.println("On");
        Serial.println(interval - cMillis);
    }
    else
    {
       digitalWrite(ledPin, LOW);
       Serial.println("Off");
    }

will always be true, this is as the difference in time, cMillis - pMillis is always greater than interval.
This means that it never enters the else statement to turn off the LED, and thus means the else statement is usually the first thing that rune at ledMode = 3.
What you need to do as the simplest fix is to change your comparison, change > to <, in the is statement:
if (cMillis - pMillis > interval)

to
if (cMillis - pMillis < interval)

this will ensure the LED is always on during the 5000 mS and then as soon as it is greater it will definitely go to the else

There is a problem with your debounce logic. You want to compare the
current button state with the previous state, which is supposed to be
stored in lastButton. But that variable is initialized to true and
then never updated. Your program may work better if you issue
lastButton = currentAButton somewhere.
You can find lots of tutorials on button debouncing, and there are
several methods. The one you are using, which is based on delay(), is
probably the worst: it should work in this simple case, but delay() is
toxic as soon as your Arduino has more than one thing to do. A very
common (and my preferred) method is to just ignore the button for some
“debounce time” after you detect a state change. A debouncer function
can be based on something like:
if (now - last_state_change < DEBOUNCE_TIME)
    return last_state;

Then you have to detect the button presses, which is not the same as the
button being down: you don't want to interpret the down state as a
continuous stream of very fast button presses. Instead, a button press
is the button being down now whereas it was up on the previous read. A
button_press() function could call the debounce() function and then
have something like
bool press = last_state && !state;

This is effectively detecting falling edges of the debounced button. You
can combine the debouncer and the falling-edge detector into a single
function as follows:
bool button_press()
{
    static bool last_state;
    static uint32_t last_state_change;
    uint32_t now = millis();

    // Ignore the button during the debounce time.
    if (now - last_state_change < DEBOUNCE_TIME)
        return false;

    bool state = digitalRead(BUTTON_PIN);
    if (state != last_state) last_state_change = now;
    bool press = last_state && !state;
    last_state = state;
    return press;
}

Next there is the management of the LED states. What you are trying to
implement is called a finite state
machine, sometimes
abbreviated “FSM”. If you search the Web for that term, you will find a
few examples on how to implement it. It canonically revolves around a
switch statement that enumerates all the possible states and tells
what to do in each of those states. Something like
switch (state) {
    case STATE_FOO:
        if (some_condition()) {
            do_some_action();
            state = STATE_BAR;  // switch to the next state
        }
        break;
    case STATE_BAR:
        ...
}

Below is a FSM implementation of your LED logic. Note that you did not
completely specify what should happen when the “timed” state times out:
you could go to a forth “timed out” state, or you could just go back to
the “off” state. In the code below I've taken that last option:
void loop()
{
    static enum { OFF, TIMED, ON } state;
    static uint32_t timed_started;
    uint32_t now = millis();

    // Switch state on button press.
    if (button_press()) switch(state) {
        case OFF:    // -> TIMED
            digitalWrite(LED_PIN, HIGH);
            state = TIMED;
            timed_started = now;
            break;
        case TIMED:  // -> ON
            // LED is lready on.
            state = ON;
            break;
        case ON:     // -> OFF
            digitalWrite(LED_PIN, LOW);
            state = OFF;
            break;
    }

    // Turn off after LED_ON_TIME.
    if (state == TIMED && now - timed_started >= LED_ON_TIME) {
        digitalWrite(LED_PIN, LOW);
        state = OFF;
    }
}

Note that it would have been more “canonical” to have the tests
if (button_press()) inside the switch rather than the other way
around. Then the test for the timeout would also be inside the same big
switch. It's just that it seemed easier to me to write it this way.
For the sake of testability, here are the pieces that would be missing
for having a complete working program:
const int BUTTON_PIN = 9;
const int LED_PIN = LED_BUILTIN;
const uint32_t DEBOUNCE_TIME = 50;
const uint32_t LED_ON_TIME = 5000;

void setup()
{
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(LED_PIN, OUTPUT);
}

// button_press() and loop() as above.

Thank you very much. The debounce has been an issue and I really wanted to get away from using the delay function. Thank you for the finite state machine information. I will be looking more into it.


text:
Error when using USART with Arduino Mega 2560
I use the Arduino IDE 1.6.9
What I want is a DMX Receiver which receives 1 channel and displays it on the serial monitor. When I try to compile the code, I get the following error:
C:\Users\Helyx\AppData\Local\Temp\build25a76891c667e0896ec10beb77bd0478.tmp/core\core.a(HardwareSerial0.cpp.o): In function `__vector_25':

D:\Programme\Arduino\hardware\arduino\avr\cores\arduino/HardwareSerial0.cpp:48: multiple definition of `__vector_25'

sketch\DmxReceive.ino.cpp.o:C:\Users\Helyx\Documents\Arduino\DmxReceive/DmxReceive.ino:26: first defined here

d:/programme/arduino/hardware/tools/avr/bin/../lib/gcc/avr/4.8.1/../../../../avr/bin/ld.exe: Disabling relaxation: it will not work with multiple definitions

collect2.exe: error: ld returned 1 exit status

exit status 1
Fehler beim Kompilieren.

Any ideas?
Here is my code:
#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdio.h>

#define F_CPU 16000000

#define DMX_BAUD 250000
#define DMX_LOST_TIMEOUT 8000

volatile unsigned char dmx_buffer[10];
volatile unsigned int dmx_lost = DMX_LOST_TIMEOUT;

volatile unsigned int dmx_adresse = 1;

ISR (USART0_RX_vect)

{
static unsigned int dmx_channel_rx_count = 0;
static unsigned char dmx_valid = 0;
unsigned char tmp = 0;

tmp =  UDR0;

if(UCSR0A&(1<<FE0))
{
 if(dmx_channel_rx_count > 1)
 {
   dmx_lost = 0;
 }
 dmx_channel_rx_count = 0;
 dmx_buffer[0] = tmp;
 if(dmx_buffer[0] == 0)
 {
   dmx_valid = 1;
   dmx_channel_rx_count++;
 }
 else
 {
   dmx_valid = 0;
 }
 return;
}

if(dmx_valid)
{
 dmx_buffer[dmx_channel_rx_count] = tmp;
 if(dmx_channel_rx_count < 514)
 {
   dmx_channel_rx_count++;
 }
 return;
}
}

ISR (TIMER2_COMPA_vect)

{
 if(dmx_lost<DMX_LOST_TIMEOUT)
 {
   dmx_lost++;
 }
}

void setup()
{

EICRA |= (1<<ISC11)|(1<<ISC10); //The rising edge of INT1 generates an interrupt request
EIMSK |= (1<<INT1); //External interrupt request 1 enable

//Init usart DMX-BUS
UBRR0   = (F_CPU / (DMX_BAUD * 16L) - 1);
UCSR0B|=(1 << RXEN0 | 1<< RXCIE0);
UCSR0C|=(1<<USBS0); //USBS0 2 Stop bits
sei();//Globale Interrupts Enable

TCCR2A |= (1<<WGM21);
TCCR2B |= (1<<CS22|1<<CS21|1<<CS20);
TIMSK2 |= (1<<OCIE2A);
OCR2A = F_CPU/1024/1000 - 1; //Tick 1ms
Serial.begin(57600);

DDRC = (1<<PE3);
PORTB |= 0x3F;
PORTC |= 0xFF;
PORTC &=~(1<<PE3);

}

void loop()
{

if(dmx_lost==DMX_LOST_TIMEOUT)
{
  dmx_buffer[dmx_adresse] = 0;

}
Serial.print(dmx_buffer[dmx_adresse]);
}

The compiler/linker is providing the answer. There are at least two definitions of the ISR for UART0 RX. One in your code and one in HardwareSerial.

Ahhh i see. Is there a way to tell the compiler to use my definition and ignore the one from HardwareSerial?

There are additional USARTs on a Mega that you could use for DMX. You would otherwise have to remove reference to Serial.

Hmm i'm pretty new to programming. I'm just using the arduino board to get a fast result and later i want to build my own circuit from the beginning. Thats why i try to avoid as much "Ardunio commands" as possible. I tried to uncomment the line in HardwareSerial0.cpp but that doesn't seem to work.

Why is it trying to use the arduino library anyway? I didn't include anything arduino related

But you have Serial.begin/print/etc in you code. And the Arduino IDE build add Arduino.h to your source code. This header then goes along and includes HardwareSerial.h.

If I understand you correctly, you want to receive serial data (in DMX format) on one serial port, and then display that data on the serial monitor (using a different serial port).
The Arduino Mega 2560 is an excellent choice, because it has 4 hardware UARTs.
Alas, there is really only 3 hardware UARTs that you can actually connect to external hardware. USART0 (the Mega pins labeled "TX0" and "RX0") are already connected to the USB interface; the Arduino calls that USART "Serial." (without a number).
I avoid connecting anything to the "TX0" or "RX0" pins on the Mega, so I can use "Serial." (USART0) for sending debugging messages to the serial terminal over the USB cable.
// doesn't compile
ISR (USART0_RX_vect)
{
    // ...
}
// ...
void loop()
{
    // ...
    Serial.print(dmx_buffer[dmx_adresse]);
}

This looks inconsistent to me.
One part of your program is trying to use USART0 ("Serial.") for sending and receiving messages to the serial monitor on the PC.
Another part of your program is trying to use the same USART0 ("Serial.") for sending and receiving messages on the DMX network.
Have you tried connecting the DMX interface to the other available hardware USARTs -- perhaps USART1 ("Serial1.", the pins labeled TX1 and RX1), or USART2 ("Serial2.", the pins labeled TX2 and RX2), or USART3 ("Serial3.", the pins labeled TX3 and RX3)?
Then your code would look more like other people recieving DMX on an Arduino Mega -- (a), (b), (c), etc.:
// the ISR setup that the other DMX-on-Arduino-Mega people use:
ISR( USART3_RX_vect ){
    // ...
}
// ...
void loop(){
    // ...
    Serial.print(dmx_buffer[dmx_adresse]);
}


text:
MQTT broker and Arduino + Sensors NRF24L01
I am newbie, I have never used MQTT before, so I have some questions.
Here is my topology.
I have several sensors (Arduino Pro Mini + NRF24L01) and main server/handler(Arduino Mega + Ethernet Shield or ESP module) to receive/send messages to/from sensor nodes, so all network is build on NRF24L01 (NRF24 Mesh library). But I need to be able to communicate with all these sensors from outside over the internet. Previously I implemented simple socket communication.
I have recently discovered MQTT protocol and it is awesome. I want to implement communication between main server and outside world using it.

What part of my topology should implement broker in? I think it should be on the main server (Arduino Mega) but again communication between main server/master server is implemented via NRF24L01 modules and custom protocol.
Or in my case is better to use HTTP communication with master server?

Please explain this topic and suggest how to implement this correctly in my case.

The normal topology is sensor nodes publishing topic-data on a MQTT broker. And the broker distributing updates to subscribing clients. The MQTT broker is responsible for several levels of QoS (Quality of Service) such as storing attribute/topic-values (persistence), checking that messages are delivered, etc. Typically the broker runs on a server with disk, multiple network connections, etc.
A possible solution is to send sensor messages to a bridge that translates and publishes the message on the MQTT broker. The sensors may use a simple cheap local wireless network (such as based on NRF24L01) and the bridge would publish over IP (Ethernet, WiFi, etc) to the MQTT broker.
Some sensors/actuators might need configuration/control (alarm thresholds, resolution, etc). In this case they need to subscribe to messages (topic updates) from the MQTT broker. Again the bridge needs to provide the subscription and message translation/routing back to the sensor.
Last, topics naming is a challenge as the bridge should be transparent in the naming structure but still configurable. The bridge configuration (e.g. network address/topic translation) could also be handled as a bridge topic.
Cheers!

You can use a Raspberry Pi as your MQTT server and you can also connect a nRF24L01+ module.

nRF24L01+ can directly be connected to the rPi.


text:
Arduino nano 33 BLE serial port not working with C# app
I use an Arduino Nano with some sensors and send data to a PC using the serial port. I just got a new Arduino Nano 33 BLE and tried the same code but its not working. So for testing I just wrote some simple test code on the Arduino Nano 33 BLE side:
void setup()
{
  Serial.begin(57600);
}

void loop()
{
  if (Serial.available())
  {
    char c = Serial.read();
    Serial.write(c);
  }
}

This just sends back whatever arrives through the COM port. Using the Arduino IDE Serial Monitor this works very well with the Arduino Nano 33 BLE.
I also made this very simple C# test code (Windows Forms app):
SerialPort serialPort = new SerialPort("COM17", 57600);
serialPort.ReadTimeout = 4000;
serialPort.WriteTimeout = 4000;
serialPort.Encoding = Encoding.ASCII;
serialPort.DataReceived += SerialPort_DataReceived;
serialPort.Open();
if (serialPort.IsOpen)
{
    Debug.Print("COM port open");
}

This C# code works perfect with my good old Arduino Nano but it doesn't work with the Arduino Nano 33 BLE. I have the COM port open message so the port exists and it is open, but then nothing else, no timeout, nothing.
I already lost one day trying out all sorts of combinations but it just doesn't work, my C# app can't communicate with the Arduino Nano 33 BLE. It looks like a serial port issue so I think I'll put it on hold for now...
EDIT:
The rest of my test code, for reference:
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    try
    {
        Debug.Print(serialPort.ReadExisting());
    }
    catch (Exception exception)
    {
        Debug.Print(exception.Message);
    }
}

private void buttonSend_Click(object sender, EventArgs e)
{
    try
    {
        serialPort.WriteLine("HELLO");
    }
    catch (Exception exception)
    {
        Debug.Print(exception.Message);
    }
}

I'm no expert in C#, but I don't see you actually sending anthing. And where is SerialPort_DataReceived defined?

I only copy/past the essential code... but its there... gonna edit the question and add them

Have you actually made sure (for example through a debug message), that serialPort.WriteLine("HELLO"); is actually executed? From what you described the problem is in your C# app, not in the Arduino part

Using the Arduino IDE Serial Monitor this works very well with the Arduino Nano 33 BLE ... that means that the data is getting to your computer ... what you do with the data after it gets there is off topic here

As I also mention in my question, this C# code works fine with an Arduino Nano, so I'm sure the C# code is working. It just doesn't work with the new Arduino Nano 33 BLE. Probably something to do with he mbed layer... but it doesn't make sense, working with Arduino IDE Serial Monitor and not with a C# compiled app. I also read somewhere that the Arduino Nano 33 BLE USB serial port is virtual, so it is a pure software serial port and not a hardware conversion from serial to USB.

This code should be working. Maybe dumb question: Are you sure the port is the right one? IIRC there are some pitfalls when using the DataReceived event [others say it's completely broken] Try using a thread for the receive end instead.

@PMF yes the code works and it is the correct port, I'm used to this kind of code and serial code exchange, multi threading, events etc. There is really an issue with the new Arduino Nano 33 BLE I guess... I was hoping that someone had seen this before and have some kind of workaround...

I noticed that a lot of line discipline and flow control settings were not made explicit in your C# code, so it made me wonder what they were by default.
In particular DtrEnable appears to be false by default and Handshake is None by default (which seems to be irrelevant). The other default amount to 8N1. The first part I found interesting because it seems more typical in serial APIs for DTR to be automatically asserted when a port is opened when you're not explicitly asking it to.  If I'm reading the .NET documentation correctly, it isn't for your application. The original Nano doesn't much care about DTR apart from a falling edge triggering reset. The board is happy to communicate with it solidly either asserted or not. The original Nano's DTR is only capacitively coupled to reset; there's not a way for the code running on the AVR to respond to DTR (unless you count resetting). That lead to a question about to what extent a Nano 33 BLE would care about DTR.
As it turns out the Nano BLE does care. If I deassert DTR in test with pyserial the board stops sending traffic back. I can write while it's deasserted and after asserting again some queued data arrives. A test environment with pyserial is just more immediately available to me; if needed and I get a chance I'll set up a .net/C# test and confirm with that, but I suspect that won't be necessary. Seeing that result, I searched and found this Arduino Forum post with a somewhat similar problem description. The OP replies in answer to their own post saying:

Problem sorted out. Arduino nano BLE requires DTR and RTS signals to
be On. Then it works like FDTI.

Disabling RTS had no effect during my tests with pyserial. I'm not sure why it would. Perhaps they just asserted it preemptively. Being entirely a virtual port RTS doesn't really make sense for flow control. DTR might arguably still makes more sense in this context; at the level of serial signals it normally tells you something is paying attention on the other side of the connection. I'm not really surprised, either way, that the BLE sense would react to DTR being disabled by not sending data to the host; there's a lot of latitude in how these signals can be handled. That it's not automatically used when the port is opened (or until specifically requested) seems mostly a C# thing. But it looks like the different handling of DTR between the two boards that is making your code work with one but not the other.
So it would seem necessary and sufficient to add
serialPort.DtrEnable = true;

amongst your other settings following the opening of the port.
If there's truth to what the Arduino Forum poster said about RTS, then you would also need
serialPort.RtsEnable = true;

but this is not indicated by the tests I've done (though again with pyserial).

Tx @timemage, you saved my day... hell you saved my week! Yes I confirm that just adding DtrEnable = true does the trick. What the hell were they thinking about? This is a damn virtual port where you don't even have to specify the baud rate! And they care about the DTR signal state? Something that you normally leave unconnected in a hardware serial port? cheeeze...

I think get your frustration. But, to be clear with respect to it being virtual: the host computer doesn't know whether logical requests for changes in baud or DTR result in real world changes to signal levels and timing or that they just terminate the USB stack. From .NET's perspective, it doesn't even know the Serial API is being backed by USB peripheral and not an old style serial port.There's a long tradition of hijacking serial signals for purposes that you'd never guess based on their names.

A 1200 baud request together with DTR (and also RTS in the case of the Due and common ESP32/ESP8266 boards) are used in many Arduino type boards both only in the USB stack (where no actual DTR signal or uart timing exists) and also via transceivers to cause entry into bootloaders, to operate chip erasure, etc. I didn't have a specific reason (until testing) to think that the BLE would care (or not) at non-1200 baud (imaginary baud) rates. To the extent that I'm mildly surprised by anything here, it's in the default behaviour of .NET's SerialPort API.


text:
Arduino Nano 33 BLE Sense's BMI270 accelerometer rev 2
I'm trying to figure out how to use interrupts to get BMI270 acceleration data at high rate, but can't find any info on it. Already spent a few hours looking for some sample code and found nothing. Anyone knows where can I find more info or sample code on this?
EDIT:
its the rev 2 and it has a BMI270

By BMI270 do you mean LSM9DS1?

Sorry, I forgot to mention its rev 2 (https://docs.arduino.cc/hardware/nano-33-ble-sense-rev2)


text:
FastLED + structs + PROGMEM strange behavior
I'm afraid I have to post a lengthy bit of code, because I can't pinpoint what's causing my issues – in short, it appears repeatedly adding float position + float speed in a struct ends up borking the whole thing.
The purpose of the code is to animate at most MAX_PARTICLES particles ("pixels") traveling at random speeds across the LED stripe.
The array named particles stores the current list of particles being managed. Each particle in the array is stored as a struct, as defined at the beginning of the code. Particles are added to the array using function addParticle() at the very end of the code. Particles which reach the end of the stripe are killed in the second part of the loop() function (after FastLED.show()).
Here's the code:
#define FASTLED_INTERNAL // Eliminates a compiler warning
#include <FastLED.h>
#include <colorutils.h>
#define NUM_LEDS 149
#define DATA_PIN 6
#define MAX_PARTICLES 5 // This uses up the memory, mostly
CRGB leds[NUM_LEDS];

struct particle {
  float position;
  CRGB color;
  float speed;
  int id;
};
typedef struct particle Particle;
Particle particles[MAX_PARTICLES];
int numParticles = 0;
int maxId = 0;

// Gramma correction tables (Defalt Gamma = 2.8)
const uint8_t PROGMEM gammaR[] = {
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,
    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,
    2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,
    5,  5,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  9,
    9,  9, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14,
   15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
   23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33,
   33, 34, 35, 36, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 45, 46,
   46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
   62, 63, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 80,
   81, 83, 84, 85, 87, 88, 89, 91, 92, 94, 95, 97, 98, 99,101,102,
  104,105,107,109,110,112,113,115,116,118,120,121,123,125,127,128,
  130,132,134,135,137,139,141,143,145,146,148,150,152,154,156,158,
  160,162,164,166,168,170,172,174,177,179,181,183,185,187,190,192,
  194,196,199,201,203,206,208,210,213,215,218,220,223,225,227,230 };

const uint8_t PROGMEM gammaG[] = {
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,
    1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,  2,
    2,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,  4,  5,  5,  5,
    5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  9,  9,  9, 10,
   10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
   17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
   25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
   37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
   51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
   69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
   90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
  115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
  144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
  177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
  215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255 };

const uint8_t PROGMEM gammaB[] = {
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,
    1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,
    2,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,
    4,  4,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  7,  7,  7,  8,
    8,  8,  8,  9,  9,  9, 10, 10, 10, 10, 11, 11, 12, 12, 12, 13,
   13, 13, 14, 14, 15, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 19,
   20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28,
   29, 30, 30, 31, 32, 32, 33, 34, 34, 35, 36, 37, 37, 38, 39, 40,
   40, 41, 42, 43, 44, 44, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53,
   54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 69, 70,
   71, 72, 73, 74, 75, 77, 78, 79, 80, 81, 83, 84, 85, 86, 88, 89,
   90, 92, 93, 94, 96, 97, 98,100,101,103,104,106,107,109,110,112,
  113,115,116,118,119,121,122,124,126,127,129,131,132,134,136,137,
  139,141,143,144,146,148,150,152,153,155,157,159,161,163,165,167,
  169,171,173,175,177,179,181,183,185,187,189,191,193,196,198,200 };

void setup() {
  FastLED.addLeds<WS2812B, DATA_PIN, BGR>(leds, NUM_LEDS);
  randomSeed(analogRead(0));
  Serial.begin(115200);
}

void loop() {
  if (numParticles < MAX_PARTICLES && random(10)>8) {
    addParticle();
  }

  for (int i=0; i<numParticles; i++) {
    // Antialiasing
    int basePosition = floor(particles[i].position);
    byte percentOnePos = round(255 * (particles[i].position-basePosition));
    byte percentBasePos = 255 - percentOnePos;
    CRGB color0 = particles[i].color % percentOnePos;
    CRGB color1 = particles[i].color % percentBasePos;

    leds[basePosition] += color0;
    leds[basePosition+1] += color1;
  }

  // Apply gamma correction
  for (int i=0; i<NUM_LEDS; i++) {
    //leds[i] = applyGamma_video(leds[i], 2.2);
    // *** applyGamma_video(2.2) pros and cons:
    // PROs: smoother color transitions
    // CONs: much slower; much worse color calibration
    // TODO: pre-render custom, color calibrated gamma tables

    leds[i].red = pgm_read_byte(&gammaR[leds[i].red]);
    leds[i].green = pgm_read_byte(&gammaG[leds[i].green]);
    leds[i].blue = pgm_read_byte(&gammaB[leds[i].blue]);
  }

  FastLED.show();

  for (int i=0; i<numParticles; i++) {
    int basePosition = floor(particles[i].position);
    leds[basePosition] = CRGB::Black;
    leds[basePosition+1] = CRGB::Black;
    particles[i].position += particles[i].speed;
    if (particles[i].position > (NUM_LEDS+1)) { // We want to render it fading out
      for (int j = i; j<numParticles-1; j++) {
        particles[j] = particles[j+1];
      }
      numParticles--;
      i--; // We want the for() cycle to process the particle we shifted down
    }
  }
  debugParticles();
}

void debugParticles()
{
  for (int i = 0; i<MAX_PARTICLES; i++) {
    if (i>0) {
      Serial.print(", ");
    }

    Serial.print(i);
    Serial.print(",");
    Serial.print(particles[i].id);
    Serial.print(",");
    Serial.print(particles[i].position);
  }
  Serial.println("");
}

void addParticle()
{
  particles[numParticles].color = CHSV(random8(),255,150);
  particles[numParticles].position = 0;
  particles[numParticles].speed = (0.0+random(10))/100+0.01;
  particles[numParticles].id = maxId++;
  numParticles++;
}

For debugging purposes, each unique particle ever created has a unique ID. The debugging output contains the following fields:

[0] the array index for the first entry in the array (always 0)
[1] the unique ID of the particle stored in the first record of the array
[2] the position of the particle stored in the first record of the array
[3] the array index for the second entry in the array (always 1)
[4] the unique ID of the particle stored in the second record of the array
[5] the position of the particle stored in the second record of the array
(and so on – three fields for each record in the particles array)

Finally, here's an interesting excerpt from the output, after ~1,500 records:
0   0   30.36   1   1   30.28   2   2   147.70  3   3   59.04   4   4   73.15
0   0   30.38   1   1   30.30   2   2   147.80  3   3   59.08   4   4   73.20
0   0   30.40   1   1   30.32   2   2   147.90  3   3   59.12   4   4   73.25
0   0   30.42   1   1   30.34   2   2   148.00  3   3   59.16   4   4   73.30
0   0   30.44   1   1   30.36   2   2   148.10  3   3   59.20   4   4   73.35
0   0   8.00    1   1   30.38   2   2   148.20  3   3   59.24   4   4   73.40
0   0   8.00    1   1   30.40   2   2   148.30  3   3   59.28   4   4   73.45
0   0   8.00    1   1   30.42   2   2   148.40  3   3   59.32   4   4   73.50
0   0   8.00    1   1   30.44   2   2   148.50  3   3   59.36   4   4   73.55
0   0   8.00    1   1   30.46   2   2   148.60  3   3   59.40   4   4   73.60
0   0   8.00    1   1   30.48   2   2   148.70  3   3   59.44   4   4   73.65
0   0   8.00    1   1   30.50   2   2   148.80  3   3   59.48   4   4   73.70
0   0   8.00    1   1   30.52   2   2   148.90  3   3   59.52   4   4   73.75
0   0   8.00    1   1   30.54   2   2   149.00  3   3   59.56   4   4   73.80
0   0   8.00    1   1   30.56   2   2   149.10  3   3   59.60   4   4   73.85
0   1   0.00    1   2   149.20  2   3   59.64   3   4   73.90   4   4   73.85
0   1   0.00    1   2   149.30  2   3   59.68   3   4   73.95   4   4   73.85
0   1   0.00    1   2   149.40  2   3   59.72   3   4   74.00   4   4   73.85

Notice how in all but the last three lines, the array index and the particle ID are still in sync (0=>0, 1=>1, 2=>2, 3=>3, 4=>4), which means no particles have died yet (new particles would have larger IDs). I'm trying to say that no particle re-assignment magic has happened yet – for now, we're just running the boring code which moves particles along the strip.
And yet, on the sixth line in the output, the first particle's position becomes mangled – notice how on the first five lines the first particle's position has steadily increased by 0.02 (presumably that particle's speed) up to 30.44, whereas on the sixth line it inexplicably becomes 8.00 (other times I experimented, it becomes 32.00). Not only that, but that 8.00 (the particle's position) never increases again, and three lines from the bottom the code also decides to kill the first particle altogether (notice that the second column becomes 1, which means the first record in the particles array now stores the particle with unique ID 1, instead of unique ID 0).
I have no idea what I'm doing wrong – I've been experimenting with this over and over, killing off all the bugs and warnings I could find, and still no luck.

My guess: not checking position leads into the overwritting memory after the leds (which is variable particles).

I'm afraid I don't follow. All of these are automatic variables, I'm not doing any DIY memory management.

You are using leds[basePosition+1] = ... and if the base position is 148, it means you are writing at the position 149. That means AFTER the space allocated for the CRGB leds[149] as you have 149 elements starting with index 0 and ending by index 148

By George, I think you've got it! Haven't tested yet (and can't until tonight), but I think you've spotted it! Please jot down an answer proper, so we can do this by the numbers.

As you are keeping the particles over the position 149 (because of fading), I'd expect overwritting the memory after the space allocated for the leds variable.
According to the log it started somewhere around position 148, which is earlier, but in your code is this:
int basePosition = floor(particles[i].position);
leds[basePosition] += color0;
leds[basePosition+1] += color1;

So if you have position 148, you are already changing something after the array. It might add zero values in the color1 (for 148.0 and 148.1) so it didn't changed anything but later the value gets nonzero and changes a wrong memory.


text:
NeoPixel library performance: Adafruit vs. FastLED
I'm new to these addressable LED things – I just received a 149-LED WS2812B strip today, and I'm experimenting with various approaches. Adafruit's own tutorial says the FastLED library is faster than their Adafruit_NeoPixel library, so I wanted to test their performance.
I'm running this code on a Nano clone:
// Adafruit
#include <Adafruit_NeoPixel.h>
// FastLED
#include <FastLED.h>
// Common
#define NUM_LEDS 149
#define DATA_PIN 6

// Adafruit initialization
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);
const uint32_t adaBlack = strip.Color(0, 0, 0);
const uint32_t adaWhite = strip.Color(255, 255, 255);

// FastLED initialization
CRGB leds[NUM_LEDS];

void setup() {
  // Common
  delay(2000);

  // Adafruit setup
  strip.begin();

  // FastLED setup
  FastLED.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);

  // Common
  Serial.begin(57600);
}

void loop() {
  unsigned int adafruitMillis = adafruitLoop();
  unsigned int fastLedMillis = fastLedLoop();
  // Yes, this is ugly -- but it works every time
  Serial.print(adafruitMillis);
  Serial.print(",");
  Serial.println(fastLedMillis);
}

unsigned int adafruitLoop()
{
  long unsigned startMillis = millis();
  for (int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed++) {
    strip.setPixelColor(whiteLed, adaWhite);
    strip.show();
    strip.setPixelColor(whiteLed, adaBlack);
  }
  return (unsigned int) millis() - startMillis;
}

unsigned int fastLedLoop()
{
  long unsigned startMillis = millis();
  for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed++) {
    leds[whiteLed] = CRGB::White;
    FastLED.show();
    leds[whiteLed] = CRGB::Black;
  }
  return (unsigned int) millis() - startMillis;
}

The results are totally disastrous for FastLED (shown in red):

Am I doing something wrong, or is FastLED winning on features, rather than on speed?
For the record, I did check whether the performance hit comes from setting the pixel values or from sending the data – FastLED is faster at setting the pixel values than Adafruit's library, but that doesn't matter because setting two pixel values takes 3 ms or less for the entire strip, regardless of the library. Sending the data to the strip takes most of the time, and that's where FastLED lags behind big time (900 ms compared to Adafruit's 200 ms).

Might I suggest a more realistic test-case. Like setting all pixels to white, then call show, then set all pixels black, and call show. Maybe repeat this like 100 times to get a bigger time-diffence value.

You can't rely on the timing reported by millis when comparing FastLED and Adafruit's neopixel library.  Writing out Neopixel data involves disabling interrupts, which is what the clock uses to advance.  FastLED accounts for this and attempts to update the system clock time after writing out led data to account for the amount of time that interrupts were disabled, but the adafruit NeoPixel library doesn't.  You need to use something else to compare timing.
(WS2812 data has a pretty strict data rate - 800khz, or about 30µs per rgb led)
(I should know, I wrote FastLED :)

(Also - when it comes to WS2812 data on AVR, the Fast in FastLED is also for the writing data - the tuned assembly output takes exactly 30µs per pixel (1.25µs per bit, or 20 clock cycles on a 16Mhz avr), and in that 30µs, not only is it writing out data, but it's also doing the scaling/dithering/color correction for the led data to write out)

Also - the rate throttler referred to above is to cap updating WS2812 leds at a rate no higher than 400Hz - WS2812 leds freak out if you update them more than 400 times/second.

Fair enough, that makes sense. I had noticed that in practice the speed difference was barely noticeable – certainly nothing like the 4x difference the millis() data seems to suggest. I was just too lazy to actually rig up a separate clock to measure real user time. Thank you for taking the time to clarify this.
Having said that, I did manage to squeeze a bit more speed out of it by removing the throttler altogether – and the LEDs didn't get borked.

As I understand it, the Fast in FastLED isn't for sending the data, but for manipulating the array/data that holds the colors. The FastLED library contains many functions optimized for dealing with 8-bit unsigned integers for holding color values, including color addition, 8-bit scaling, partially-defined color palettes (for example, you define 8 waypoints in the palette, but can grab a color from the full 8-bit range and it interpolates on the fly using the fast 8-bit math.
Not just math, but also conversion to/from RGB and HSV realms, etc.
It supports pushing multiple strips at the same time (parallel) by writing to the whole PORT instead of just one pin of the 8-pin port, so if you split your strip into multiples, you can really make speed gains in writing to the LEDs.

Fair enough, I had ended up with the same impression – but the difference in performance for this basic test is so large I wanted to make sure I wasn't using it wrong. Thanks for taking the time to whet my appetite, though!

Your evaluation code is fine, but probably doesn't represent a real-world use case. I've commonly seen animation code structured to have a fixed rate for the FastLED.show() command, and you have to complete all your animation steps between each frame update. That is where the fast 8-bit color and math routines are useful.

That's a legitimate observation, but it depends on whether the library is throttling data bursts, or if what we're seeing is plain overhead. If it's throttling data it's all good, because all of my real-world scenario calculations will eat into the time it's currently idling. But if this is overhead then all of this is going to add up to the calculations, resulting in limited performance. I actually did track down a refresh rate throttler in the library, and hope to experiment a bit tonight. In case you're curious: https://github.com/FastLED/FastLED/blob/master/FastLED.cpp#L41


text:
Weather API Arduino
#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {my mac };
char serverName[] = "api.weather.gov";

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

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

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  int ret = client.connect(serverName,443);
  if (ret==1) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /stations/KGSO/observations/latest");
    client.println("accept: application/geo+json,*/*");
    client.println("user-agent: arduino, mymail@asdf.com");
    client.println("host: api.weather.gov");
    client.println();
  }
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
    Serial.println(ret);
    Serial.println(client.status());
  }
}

void loop()
{
  // if there are incoming bytes available
  // from the server, read them and print them:

  if (client.available()) {
    Serial.print("\ngotsome\n");
    char c = client.read();
    Serial.print(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
}

When I run this I get:
connecting...
connected
disconnecting.
Why don't I get data? I thought it was about the header info. But I looked at https://www.weather.gov/documentation/services-web-api#/ and it doesn't say it needs much.

what happens if you remove the last if block?

connecting...
connected

Yes I think Juraj has the answer (thanks): Can't get there from here. Maybe that's an excuse to get a raspberry pi.

The Ethernet library doesn't support secure connection (so called SSL, but TLS now). To connect to a secure HTTP transport HTTPS the secure connection is necessary. The AVR MCU don't have the computing power to compute the security keys. And for less popular 32bit MCU nobody created a 'SSL' implementation for Ethernet library yet.
esp8266, esp32, MKR1010, Uno WiFi, Nano 33 IoT can do HTTPS, but all only over WiFi as far as I know.


text:
Missing buffers with serial communication
I am currently facing a problem with Serial communication with my arduino MEGA 2560.
My project is to collect data from an encoder. There are 2 signals : ACP and ARP. For 1 rotation, there are 16 384 ACPs (counter) and 1 ARP (reference).
I have to store the high level and length of EACH ACP and if there is an ARP. To receive these signals I created a little PCB with a dual line receiver (because At the output of the encoder I revceive differential signals).
To store these data, I use a buffer of bytes. I need 3 bytes to store both ACP length and high and 1 ARP (I store the data in an ISR, see code below) :
buff1[i] = char((arpNbr << 7) +  (acpPeriod >> 8));
i++;
buff1[i] = char(acpHigh);
i++;
buff1[i] = char(acpPeriod);
i++;

I use 2 circular buffers (when 1 is filled, I start wrinting into the other). As there are different speed rotation, the fastest one is 15 RPM (rotation per minute) so 1 ACP signal (1 period) last for 244 us and 4 s are needed for 1 rotation.
To collect the data, I directly use :
Serial.write(buff1, sizeof(buff1));
Here is the code I am using :
#include <eRCaGuy_Timer2_Counter.h> //To use timer in ISRs

//Constants
#define NO_DEFAULT_LED_PIN            40
#define DEFAULT_LED_PIN               42
#define WRITE_LED_PIN                 44
#define REC_IN_PROGRESS_LED_PIN       50
#define ACP_LED                       46
#define ARP_LED                       48
#define ACP_PIN                       20
#define ARP_PIN                       21
#define STOP_REC_BUTTON_PIN           28

#define SIZE                          800
#define BAUDSPEED                     230400

//Variables
boolean recordingEnded = false;
volatile boolean writing = false;
volatile unsigned short arpNbr = 0;
volatile unsigned short acpHigh = 0;
volatile unsigned short acpPeriod = 0;
volatile int i = 0;
volatile bool change_buffer = 0;

char buff1[3 * SIZE];
char buff2[3 * SIZE];

//Variables for interruption routines
volatile unsigned long acpHighUs = 0UL; volatile unsigned long acpPeriodUs0 = 0UL; volatile unsigned long acpPeriodUs1 = 0UL;

/**************************************************************************************/
/* Initialization                                                                     */
/**************************************************************************************/
void setup()
{
  Serial.begin(BAUDSPEED);

  //Setup LED pins
  pinMode(DEFAULT_LED_PIN, OUTPUT);
  pinMode(NO_DEFAULT_LED_PIN, OUTPUT);
  pinMode(SD_WRITE_LED_PIN, OUTPUT);
  pinMode(REC_IN_PROGRESS_LED_PIN, OUTPUT);
  pinMode(ACP_LED, OUTPUT);
  pinMode(ARP_LED, OUTPUT);

  //Setup ACP and ARP inputs
  pinMode(ACP_PIN, INPUT_PULLUP);
  pinMode(ARP_PIN, INPUT_PULLUP);

  //Setup the button
  pinMode(STOP_REC_BUTTON_PIN, INPUT_PULLUP);

  //Light ALL LEDs during initialisation
  digitalWrite(DEFAULT_LED_PIN, HIGH);
  digitalWrite(NO_DEFAULT_LED_PIN, HIGH);
  digitalWrite(SD_WRITE_LED_PIN, HIGH);
  digitalWrite(REC_IN_PROGRESS_LED_PIN, HIGH);
  digitalWrite(ACP_LED, HIGH);
  digitalWrite(ARP_LED, HIGH);
  delay(500);

  //Setup the timer
  timer2.setup();

  //Setup is done
  digitalWrite(NO_DEFAULT_LED_PIN, LOW);
  digitalWrite(SD_WRITE_LED_PIN, LOW);
  digitalWrite(ACP_LED, LOW);
  digitalWrite(ARP_LED, LOW);

  //Attach interruption at the end of the initialisation (recording starts...)
  attachInterrupt(digitalPinToInterrupt(ACP_PIN), acpRising, RISING);
  attachInterrupt(digitalPinToInterrupt(ARP_PIN), arpRising, RISING);
}

/**************************************************************************************/
/* Main loop                                                                          */
/**************************************************************************************/
void loop()
{
  //Check if the user stops the recording
  if (digitalRead(STOP_REC_BUTTON_PIN) == LOW && !recordingEnded )
  {
    noInterrupts();
    delay(500);

    //Switch off the recording LED
    digitalWrite(SD_WRITE_LED_PIN, LOW);
    digitalWrite(REC_IN_PROGRESS_LED_PIN, LOW);
    digitalWrite(ACP_LED, LOW);
    digitalWrite(ARP_LED, LOW);

    return;
  }

  //Check if the writing should be done
  if (writing && !recordingEnded)
  {
    digitalWrite(WRITE_LED_PIN, HIGH);

    if (change_buffer) {
       Serial.write(buff1, sizeof(buff1));
    }
    else {
       Serial.write(buff2, sizeof(buff2));
    }

    digitalWrite(WRITE_LED_PIN, LOW);
    writing = false;
  }
}

/**************************************************************************************/
/* This method is called at the beginning of each ACP.                                */
/**************************************************************************************/
void acpRising()
{
  digitalWrite(ACP_LED, HIGH);
  acpHighUs = timer2.get_count();
  acpPeriodUs1 = timer2.get_count() / 2 - acpPeriodUs0;
  acpPeriodUs0 = timer2.get_count() / 2;

  acpPeriod = acpPeriodUs1;

  attachInterrupt(digitalPinToInterrupt(ACP_PIN), acpFalling, FALLING);
}

/**************************************************************************************/
/* This method is called at the end of each ACP.                                      */
/**************************************************************************************/
void acpFalling()
{
  digitalWrite(ACP_LED, LOW);
  acpHighUs = (timer2.get_count() - acpHighUs) / 2;
  acpHigh = (unsigned short)acpHighUs;

  if (change_buffer) {
    buff1[i] = char((arpNbr << 7) +  (acpPeriod >> 8));
    i++;
    buff1[i] = char(acpHigh & 0xFF);
    i++;
    buff1[i] = char(acpPeriod & 0xFF);
    i++;

  }
  else  {
    buff2[i] = char((arpNbr << 7) +  (acpPeriod >> 8));
    i++;
    buff2[i] = char(acpHigh & 0xFF);
    i++;
    buff2[i] = char(acpPeriod & 0xFF);
    i++;
  }

  arpNbr = 0;

  if (i == 3 * SIZE) {
    i = 0;
    change_buffer = !change_buffer;
    writing = true;
  }

  attachInterrupt(digitalPinToInterrupt(ACP_PIN), acpRising, RISING);
}

/**************************************************************************************/
/* This method is called at the beginning of each ARP.                                */
/**************************************************************************************/
void arpRising()
{
  digitalWrite(ARP_LED, HIGH);
  arpNbr = 1;

  attachInterrupt(digitalPinToInterrupt(ARP_PIN), arpFalling, FALLING);
}

/**************************************************************************************/
/* This method is called at the end of each ARP.                                */
/**************************************************************************************/
void arpFalling() {
  digitalWrite(ARP_LED, LOW);
  attachInterrupt(digitalPinToInterrupt(ARP_PIN), arpRising, RISING);
}

Problem :
I use CoolTerm software to collect my data into a .txt file and analyse it with Hexed.it.
It seems like after a certain period, like 6-10 minutes, I loose a part of 1 buffer. I checked this beacause as I wrote above, I need 3 bytes for information and in Hexed.it, I saw that I had only 2 bytes at once, and after, data was correct.
After analysing in depth, I saw that there was a part of a buffer and a few more (1-2) which were missing. I managed to see this because there was not 16384x3 bytes between 2 ARP (reference signal of the encoder).
I checked all timings to see if I sent the buffer before it was filled but everything is fine...
I also tried other methods like :

Writing on a SD card;
Changing buffer size;
Changing baudrate;
Using polling method instead of ISRs.

But nothing concluant ...
EDIT:
It seems like my problem came from CoolTerm software after correcting my code. I now use RealTerm and I made a 1 night recording duration and every seems to be perfect. I don't have any data lost.

You attach interrupts quite often which I’d say is uncommon at least. I don‘t know what attachInterrupt() does in the background, but if it uses dynamic memory allocation I could imagine that calling it frequently might lead to problems.

Also you should not return from the main (loop) function on a uC. I don‘t know if it‘s legal, but it doesn‘t make much sense

@SimSon: 1. attachInterrupt() does no memory allocation. 2. loop() is not main(): returning from loop() is perfectly fine, and expected.

@EdgarBonet good to know! Will it be like while(1) loop(); in the end?

@SimSon: main() does indeed call loop() repeatedly.

What do you mean by “a part and other buffers are not transmitted”? Do you continue to receive data? Is the received data different from what you expect? If so, in what way is it different? Also, what is the typical frequency of the ACP signal?

@EdgarBonet Sorry for creating a new answer but I can't aswer to your pevious one. I can edit it but can't answer to it... Weird... So, for your answer 2. Writing passes to true in acpfalling ISR, after i = 0. 3. Thanks to have seen this. I am making a test to see if this is the problem... Hope it will resolve 4. I will have a look, thanks! 5. Using char *buff = change_buffer ? buff1 : buff2; won't take useless time ? I mean, if it just a matter of reading. Because, as far as I know, ISRs have to be as short as possible.

StackExchange sites are not forums. You don't post answers below answers, and so on, please take the [tour] (again). -- If you need some clarification, comment below the question or the answer that is unclear. -- If you have new information after reading a comment or an answer, edit your question. There is that little link on the left below your question.

@EdgarBonet I am trying to 'add a comment' to your comment to your comment but I can't. it tells me : 'You need to have 50 reputation to comment'. How can I handle this situation to answer your comment and not creating stupid answers all the time ?... Sorry for this answer ...

@Greg_B - You have 2 accounts with the same name, but 2 different IDs. If you can't comment, please edit the question with new information.

Not a direct answer to your questions, but after reading your code I
would like to give some comments:

You are not using “circular buffers”, you are double-buffering.
If you used a circular buffer, you would not need two of them.
recordingEnded is always false and thus serves no purpose.
When writing and change_buffer are both true, you should transmit
buff2, not buff1, as the ISR is now filling buff1.
There are too many globals. Variables that are used in a single
function should be local to the function. If you need the value to be
preserved between calls, qualify the variable as static.
The code that fills the buffers would be clearer, IMO, if you avoided
the repetition. E.g.

char *buff = change_buffer ? buff1 : buff2;
buff[i++] = (arpNbr << 7) | (acpPeriod >> 8);
buff[i++] = acpHigh & 0xFF;
buff[i++] = acpPeriod & 0xFF;

Note that buf[i++] is idiomatic C/C++.
Now, regarding your specific question, you mentioned in a comment that
“there were not 3x16384 bytes between 2 ARP”. This may well be a
consequence of issue 3: you are not sending the bytes in the correct
order, as at times (when Serial.write() runs ahead of the ISR) you may
be sending old data.

Edit: to answer the comment

char *buff = change_buffer ? buff1 : buff2; won't take useless time?

Not really. Testing change_buffer is something you have to do either
way. Assigning the buffer address to a local pointer is also done, under
the hood, by the compiler. In the best case, it optimizes your code to
something like:
register char *Z;
if (change_buffer)
  Z = buff1 + i;
else
  Z = buff2 + i;
Z[0] = (arpNbr << 7) | (acpPeriod >> 8);
Z[1] = acpHigh & 0xFF;
Z[2] = acpPeriod & 0xFF;
i += 3;

Using an explicit buff pointer gives a similar result, as the compiler
will allocate this to the CPU's Z register. Actually, you may get
shorter code, as the compiler may not entirely factor out the
repetition.


text:
esp8266 ip address issues
I have android studio app and arduino codes they are connected to each other using esp8266
but it works only on one network when I use another network it doesn't recognise it's ip address instead it gives 0.0.0.0

Only this worked

 #include <LCD5110_Graph.h>
    #include <Adafruit_MLX90614.h>

    #define DEVICE_ID "Monitor1"

    #define DEBUG true
    #define REQ_CODE_ACK 1
    #define REQ_CODE_VALUES 2

    //84w * 48h
    LCD5110 myGLCD(8,9,10,12,11);
    extern uint8_t SmallFont[];   //8h * 6w font

    Adafruit_MLX90614 mlx = Adafruit_MLX90614();
    int pinLM35 = A0;         //Pin A0 is for LM35
    int fsrAnalogPin = A2;    //Pin A2 is for force sensor
    int blinkPin = 13;        // Pin 13 is the on-board LED

  String mSSID = "LibyaADSL-9a86";    //initial ssid and password
  String mPASS = "BYRTPCRJAHPWQ";

    //http request code
    int service_code;

    //wifi listen variables
    String wifiBuf = "";
    char character;
    int connectionId = 0 ;

    //sensor values
    float sensor_mlx, sensor_heart, sensor_lm35;
    int sensor_force;

    void setup() {
      //init LCD
      myGLCD.InitLCD();
      myGLCD.setFont(SmallFont);
      randomSeed(analogRead(7));

      //init MLX90614
      mlx.begin();

      //init serial
      Serial.begin(115200);           //Arduino-PC
      Serial3.begin(115200);          //Arduino-ESP8266\

      //init esp8266
      init8266();

      pinMode(blinkPin,OUTPUT);         // pin that will blink to your heartbeat!

      delay(200);
    }

    //init esp8266
    void init8266()
    {
        Serial.println("Init ESP...");
        String stationConCmd = make8266InitCommand();

        sendCommand("AT+RST\r\n",2000,DEBUG);       // reset module
        sendCommand("AT+CWMODE=1\r\n",1000,DEBUG);  // configure as access point
       // sendCommand("AT+CWDHCP=1,1\r\n",1000,DEBUG);
       // sendCommand("AT+CIPSTA=192.168.0.101,192.168.0.1,255,255,255,0\r\n",1000,DEBUG);    // HI اني ضفته
        sendCommand(stationConCmd, 1000, DEBUG);

        delay(1000);
        sendCommand("AT+CIFSR\r\n",1000,DEBUG);     // get ip address
    ///
        sendCommand("AT+CIPMUX=1\r\n",1000,DEBUG);  // configure for multiple connections
        sendCommand("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80
    }

    //Make command string for connect to AP
    String make8266InitCommand()
    {
        String cmd = "AT+CWJAP=\"" ;
        cmd += mSSID;
        cmd += "\",\"";
        cmd += mPASS;
        cmd += "\"";
        cmd += ",11,0\r\n";

        return cmd;
    }

i still can't figure it out
Hope someone can help
Thank you

you send AT+RST immediately after AT+CWJAP. it doesn't have time to connect to the new WiFi. with a remembered network it worked, because it connect to the network automatically

@Juraj how much delay i need to put ?

@jsotola post updated, please check

the logic of your sketch is wrong. you throw a bunch of random commands at the AT firmware. it is unclear from your question if you use or want to use the remembered connection or you did turn off autoconnect and want to connect every time etc...

this is written from a perspective of a library but is valid for raw AT Commands too: https://github.com/jandrassy/WiFiEspAT#persistent-wifi-connection

@Juraj i updated the question with a new image showing the error, please check

what is ,11,0 in CWJAP? remove it

If you configure the esp as an access point then it should also be the DHCP server and be supplying ip addresses to it's clients.  Only if you configure it to be a client station itself (eg. connect to your router as client) will it be assigned an ip address.

what question do you answer here?

i updated the question with a new image showing the error, please check

The comment on CWJAP line said it was to configure as access point which made think there was some confusion with wifi network concepts.  However, the error you show occurs right after you try to connect to your ADSL wifi so there is something not right with that network name or password.  Or maybe your wifi AP is doing mac address filtering.


text:
const char* to double
I'm trying to use an if statement to check when the time goes past a specific point and run a specific function. To do this I'm looking to convert time into a double and running something along the lines of if(timeCurrent >= 8.30). I seem to however have an issue with the conversion part, normally I'm aware the standard practice in C++ would be to do the following:
DateTime now = rtc.now();
static char buffer[80];

sprintf(buffer, "%02d.%02d", now.hour(), now.minute());
String str(buffer);
double timeCurrent = strtod(str);

However, this doesn't work for Arduino. What can be done to create the same desired function?

this may help ... you made no mention of any research that you may have done ... https://playground.arduino.cc/Code/Time

convert buffer to float, not String. but there are more elegant end efficient solutions. if you really want float then 0.01 * m + h

There is really no need to take the extra effort in converting first to char buffer, then String and then double. Just convert the ints from the RTC directly to a float like juraj wrote. And I doubt, that your code is a good practice in C++ either

I'm aware the standard practice in C++ would be to do the following... Umm... no, it certainly would not. What would give you that impression?

Don't do that. Converting a time to double is highly inefficient.
Moreover, your approach suffers from a rollover issue every 24h.
If you just want to compare the time of day with 8:30, you can do it in
a very straightforward way:
if (now.hour() > 8 || (now.hour() == 8 && now.minute() >= 30))

If the long if annoys you, you can put the comparison logic inside a
static inline function. If you really want to combine hour and minute
into a single number, then convert to an integer rather than a double:
if (now.hour() * 100 + now.minute() >= 830)

This can be made more efficient if you think in binary rather than
decimal: you can build a 16-bit number with one byte holding the hours
and the other byte holding the minutes:
if ((now.hour() << 8) | now.minute() >= (8 << 8) | 30)

Again, you may encapsulate the ((a)<<8|(b)) in a macro or static
inline function if it helps with readability. If you want to compare to
an absolute time, your best option is to build a DateTime object
representing the deadline, and compare with now as:
// Assume timeout should be today at 8:30.
DateTime timeout(now.year(), now.month(), now.day(), 8, 30, 0);
if (now.secondstime() >= timeout.secondstime())

Here the secondstime() method is used to convert the DateTime into a
scalar number (a 32-bit integer of type time_t) that can be easily
compared and is far more efficient than using floats.