text:
Arduino CH340 Driver Problem
I'm trying to connect my Arduino Uno to the Arduino IDE in Windows, but the only way it works is with a CH340 driver.
I am concerned about this as I can only find a download of it published by two Chinese companies- wch.cn or Jiangsu Qinheng Co., Ltd.- maybe they're both 1 company; even when Windows looked for a driver on the web that was the one it downloaded.
When I went to Device Manager to look for the driver in the official Arduino download zip, Windows said it couldn't find any drivers.
I am concerned about the security implications of the driver being Chinese and wonder if there are any other CH340 drivers (unless CH stands for China...)
Anyway thx for answering!!! :)

The CH340 is a Chinese knock-off of FTDI chips. That doesn't mean they are bad or that their drivers are unsafe. It's just what it is. FTDI, on their own, is trying also to "fix" their own drivers to not necessarily work well with CH340 chips. So you may be stuck with their drivers, like it or not. They are drivers and so may run at a trusted level in your computer. If you are serious about such security, then you should also consider that FTDI may be working with still other groups that also may sacrifice your security, too. There's no truly safe haven. Just the feelings of one.

Switch to a Mac. In macOS, the CH340 drivers are provided by Apple themselves and preinstalled on every Mac.

Or switch to a genuine Arduino Uno, which uses the official USB standard for USB-to-serial communication, i.e. a USB CDC device implementing ACM and PSTN protocols.

@jonk what makes you think the CH340 is a FTDI knock-off? They don't use the FTDI drivers at all.

@Passerby Sorry. Perhaps just a difference in perspective. The CH340 showed up in "cheap" boards from China many years ago. At first, none of us understood exactly what had happened, as FTDI was pretty much the only player at first. If you google "knock-off" and "CH340" you'll see I'm not the only person in the world seeing things that way. I don't mean to belittle the device. But it was introduced in order to lower the BOM cost to some players needing an FTDI equivalent. Little doubt about that. If my words offend, my apologies. As I said, "that doesn't mean they are bad." And I meant that.

CH340 is immensely widely used. There may be many drivers or only a few BUT either way they are in use in the very many millions. Note that Arduino Clones are 110% legitimate. What is not meant to be used is the Arduino NAME per se. The design and system software is fully open source.

@jonk by the time the CH430 showed up Silicon labs and Prolific had be making their USB-UART bridges for years (CP2102, PL2304), and people had been making clones of them too.   Arduino used the FTDI chip, but most cheap arduino closes use the CH430 now.

@Jasen Yup. Cheap is the word.

@jonk saying its a knock off just cause its a competing product is just plain wrong.

@Passerby I remember the period of time when it first, unexpectedly, appeared and we hobbyists were struggling hard to find drivers to work with it. It literally took us by surprise as the products hadn't declared its use. We discovered it when the boards arrived, instead, and then had to deal with some difficult hacks to make things work. I have my impressions from that day. You can have the floor on the topic now. I'll leave it for you.

WCH is the manufacturing company that first produced the CH340. They are Chinese.


text:
Serial Monitor shows a continuous "word salad" without a loop
I have written a little program which should (at the end) host a little website. This is just my setup. But for some reason, it writes "srl?" endlessly onto the serial monitor. I just connected the ESP8266-01 to my Arduino UNO, using 115200 baud with the nodeMCU board. Using different boards results in an error telling me I should use nodeMCU.
As I have written in the title, I do not understand how it can produce an endless output without a loop with Serial.print/write in it.
#include <ESP8266WiFi.h>

const char* NAME = "x"; //ssid
const char* PWRT = "x"; //password

WiFiServer server(80);

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

  Serial.printf("connect with %s \n", NAME);
  WiFi.begin(NAME, PWRT);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }

  server.begin();
  Serial.printf("webserver open, access with %s\n", WiFi.localIP().toString().c_str());

}

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

}

"I just connected the ESP8266-01 to my Arduino UNO, using 115200 baud with the nodeMCU board". What NodeMCU board? The ESP8266-01 is not a NodeMCU. How did you connect everything up? If your Arduino uses SoftwareSerial to communicate with the ESP8266-01 at 115200 baud, that will not work reliably. Use 9600 baud.

you have a reset loop

What do you mean @Juraj?

@StarCat like this https://virtuino.com/images/arduino_esp8266_connections.png but to RX and TX instead of Pin 2 and 3

Please post the actual serial output and how you connected arduino and esp

You need to show the actual output. "Word salad" could be anything. For example, are the words ""connect with" and "webserver open, access with" part of this salad?

A reset loop is where code starts to do something (like print a message) and then encounters an error condition, which causes it to crash and reset. Then it prints the message again, crashes again, and so on.

The ESP8266WiFi.h is for running on an ESP8266 host, but your are trying to use it on an Arduino Uno. This caused the crash of your sketch on Arduino Uno.
Based on the connection diagram you provided, you are using the ESP-01 as an wifi-shield and the ESP-01 by default is having an AT commands firmware. In order to use the ESP-01 as a wifi shield, you need an library like WiFiEspAT.

source: Stack Exchange

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

sort: votes


text:
I can't upload codes to my ESP8266
,this is the error I encounter when i try to upload my code
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#ifndef STASSID
#define STASSID "your-ssid"
#define STAPSK  "your-password"
#endif

const char* ssid     = STASSID;
const char* password = STAPSK;

const char* host = "192.168.1.1";
const uint16_t port = 3000;

ESP8266WiFiMulti WiFiMulti;

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

  // We start by connecting to a WiFi network
  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP(ssid, password);

  Serial.println();
  Serial.println();
  Serial.print("Wait for WiFi... ");

  while (WiFiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  delay(500);
}

void loop() {
  Serial.print("connecting to ");
  Serial.print(host);
  Serial.print(':');
  Serial.println(port);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;

  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    Serial.println("wait 5 sec...");
    delay(5000);
    return;
  }

  // This will send the request to the server
  client.println("hello from ESP8266");

  //read back one line from server
  Serial.println("receiving from remote server");
  String line = client.readStringUntil('\r');
  Serial.println(line);

  Serial.println("closing connection");
  client.stop();

  Serial.println("wait 5 sec...");
  delay(5000);
}

Need a bit more information, what ESP8266 module are you using? Does it have a Reset swtich that needs to be held to program? Like discussed at this link... https://tttapa.github.io/ESP8266/Chap06%20-%20Uploading.html#:~:text=press%20and%20hold%20the%20reset,will%20boot%20in%20program%20mode

why are you posting a picture of text? ... you pasted the code, paste the error message also ... if you can't upload then the code is irrelevant and only clutters up the post

Which version of arduino IDE do you use? Try to update

Try updating the Serial Driver in your system or try using lesser baud rate, i.e. 9600 instead of 115200.

You should be able to program an ESP8266 at 500Kbit/s or faster. If it only programs at 9600, something's not right.

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


text:
double type sensor data is not displayed on bluetooth terminal app on phone
Hi I am working on a project in which I am supposed to tell if a person is running/standing/walking and going upstairs/downstairs or he is on straight road. The person will carry a arduino uno module to which gps,bluetooth and altitude sensor is attached. Also I am trying to send my phone his speed and current altitude he is experiencing using HC-05 bluetooth module. I am sure that there is no problem with altitude sensor. Also I must note that my gps module(GY_NE06MV2) is not acting proper when it comes to speed of the person. I believe this is because I experimented in my house and not outside. The problem is that I cannot see speed and altitude data on bluetooth terminal app"ArduTooth" on my phone. It is just like a blank space which should have been my data. I am presenting my code which is not very long and I hope you could help me get through this.
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

TinyGPSPlus gps; //gps object to be used
SoftwareSerial BTserial(10, 11); //bluetooth serial connection
SoftwareSerial gps_serial(4,3); //gps serial connection
Adafruit_BME280 bme; //altitude measuring sensor object

#define SEALEVELPRESSURE_HPA (1011) //sea level pressure in Turkey/Eskisehir

double speed = 0; //speed of a moving body
double current_altitude = 0;
double previous_altitude = 0;

void setup() {
Serial.begin(115200); // serial connection to computer
BTserial.begin(9600);
gps_serial.begin(9600);
bme.begin(0x76);

delay(3000);

previous_altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);

}

void loop() {
//data from gps device is fed to gps object
while (gps_serial.available() > 0){
    gps.encode(gps_serial.read());
}

if(gps.speed.isValid()){
speed = gps.speed.kmph();
BTserial.write(speed); // this is where the problem-1 is, this data is not shown on mobile phone
bluetooth terminal application
BTserial.write(",");

  if(speed <= 5 && speed > 0.5){
    BTserial.write("walking");
    BTserial.write(",");
  }
  if(speed <= 0.5){
    BTserial.write("standing");
    BTserial.write(",");
  }
  if(speed > 5){
    BTserial.write("running");
    BTserial.write(",");
  }

  }else{
    BTserial.write("m.s.n.n"); //stands for "moving status not known"
    BTserial.write(",");
  }

current_altitude = bme.readAltitude(SEALEVELPRESSURE_HPA);
BTserial.write(current_altitude); //this is where problem-2 is, this data also is not displayed
on phone
BTserial.write(",");
//this part determines either the body goes upstairs or downstairs or he is on straight road
if(current_altitude - previous_altitude >= 0.7){
  BTserial.write("going ups.");
  previous_altitude = current_altitude;
}
if(previous_altitude - current_altitude >= 0.7){
  BTserial.write("going downs.");
  previous_altitude = current_altitude;
}
if((current_altitude - previous_altitude <= 0.3) || (previous_altitude - current_altitude <=
0.3)){
  BTserial.write("on s.r");
  previous_altitude = current_altitude;
}
BTserial.write(";");

delay(1000);

}

I must note that purpose of BTserial.write(",");  is that every seperate entry sent to phone via bluetooth must be seperated by ",".

Have you verified, that your serial bluetooth connection is working? I mean without all the other code. Also you are using the write method, which is mostly used for binary data. I guess that you want to transmit ASCII encoded dara, thus you need to use print() for the altitute variable transmit

Bluetooth module is working fine I guaranteed that. I will try that thanks. Also can you tell me about gps module which makes me sad as it does not give speed. I believe it is because I am at home doing experiments. I am using tinygps++ library and its functions for that

You can convert you double data to string type.this trick may help. And you also can just sent a byte for different positions and decode them in app.

SoftwareSerial is a very badly behaved library. It blocks interrupts
while sending or receiving bytes. Using it with whatever depends on
interrupts is asking for trouble. Using two instances of
SoftwareSerial concurrently is doubly asking for trouble. It is very
likely that they are interfering with one another, as each one blocks
interrupts for an unreasonably long time, and each one relies on
interrupts for detecting incoming data.
You don't seem to be using the hardware serial interface (Serial),
which is a shame, as it is the only serial port you have that works
really well. I suggest you try to use this interface for one of your
devices (maybe the GPS), and a single software interface for the other
one.
Or, better yet, use Serial for both. The transmit and receive parts of
a serial port are fairly independent, save for the fact that they work
at the same speed. You could use the transmit part for the Bluetooth
module and the receive part for the GPS. This should ensure reliable
communication with both devices, without ever blocking interrupts for
too long.


text:
Arduino and ZMPT101B But Not Stable Sigma Output In 7segment Display(TM1637) using filter library
#include <Arduino.h>
#include <math.h>
//TRUE RMS START
#include <Filters.h> //Easy library to do the calculations
#include <TM1637Display.h>
float testFrequency = 100;                     // test signal frequency (Hz)
float windowLength = 100.0 / testFrequency;   // how long to average the signal, for statistist
int Sensor = 0; //Sensor analog input, here it's A0
int Sensor2 = 0; //Sensor analog input, here it's A1

float intercept = -0.04; // to be adjusted based on calibration testing
float slope = 0.0405; // to be adjusted based on calibration testing
float current_Volts, output_volts; // Voltage

unsigned long printPeriod = 500; //Refresh rate
unsigned long previousMillisTRUE = 0;
int truermsflag = 0;
int inputvolt = 0, outputvolt = 0;
RunningStatistics inputStats;
RunningStatistics inputStats2;
int sigmaint = 0;
//TRUE RMS end
//#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
//#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

// Module connection pins (Digital Pins)
#define CLK 3
#define DIO 2

#define CLK1 4
#define DIO1 5

#define switcht 6
#define Relay1 8
#define Relay2 9
#define Relay3 10
#define Relay4 11
#define TRelay 12
// The amount of time (in milliseconds) between tests
int i = 0;
int timerflag = 0, onetimeflag = 0;
int volt = 0, voltoutput = 0;
TM1637Display display(CLK, DIO);
TM1637Display display2(CLK1, DIO1);
const uint8_t DONE[] =
{
    //SEG_B | SEG_C | SEG_D | SEG_E | SEG_G,           // d
    SEG_D,   // O
    //SEG_C | SEG_E | SEG_G,                           // n
    //SEG_A | SEG_D | SEG_E | SEG_F | SEG_G            // E
};
const uint8_t Dely[] =
{
    SEG_B | SEG_C | SEG_D | SEG_E | SEG_G,           // d
    SEG_A | SEG_D | SEG_E | SEG_F | SEG_G,           // E
    SEG_F | SEG_E | SEG_D,                           // L
    SEG_F | SEG_B | SEG_G | SEG_C // Y
};
const uint8_t HIVOLT[] =
{
    SEG_F | SEG_E | SEG_B | SEG_C | SEG_G,           // H
    //SEG_B | SEG_C,           // I
    //SEG_F | SEG_E | SEG_D | SEG_C | SEG_B, // V
};

const uint8_t L0VOLT[] =
{
    SEG_F | SEG_E | SEG_D,                           // L
    //SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,//0
    //SEG_F | SEG_E | SEG_D | SEG_C | SEG_B  ,// V

};

int ledPin =  13;      // the number of the LED pin
unsigned long previousMillis1 = 0, previousMillis2 = 0, previousMillis3 = 0;      // will store last time LED was updated
//unsigned long currentMillis;
unsigned long previousmacro = 0;
unsigned long currentMacro = 0;
int acVoltage(int adcpin);
int average(int pin);

void setup()
{
    //
    //  sbi(ADCSRA, ADPS2);
    //  cbi(ADCSRA, ADPS1);
    //  cbi(ADCSRA, ADPS0);
    analogReference(EXTERNAL);  // set ADC positive reference voltage to 1.1V (internal)
    pinMode(switcht, INPUT);
    pinMode(switcht, INPUT_PULLUP);
    pinMode(Relay1, OUTPUT);
    pinMode(Relay2, OUTPUT);
    pinMode(Relay3, OUTPUT);
    pinMode(Relay4, OUTPUT);
    pinMode(TRelay, OUTPUT);

    //For Optocuplar Relay
    digitalWrite(Relay1, HIGH);
    digitalWrite(Relay2, HIGH);
    digitalWrite(Relay3, HIGH);
    digitalWrite(Relay4, HIGH);
    digitalWrite(TRelay, HIGH);

    pinMode(ledPin, OUTPUT);

    display.setBrightness(0x0f);
    display2.setBrightness(0x0f);
    //display.setSegments(Dely);

    //  delay(3000);
    //  display.clear();
    //  display.setSegments(HIVOLT, 3, 0);
    //
    //  delay(3000);
    //  display.clear();
    //  display.setSegments(L0VOLT, 3, 0);

    //display2.setSegments(Dely);
    //display.clear();
    Serial.begin(57600);

    //delay(1000);
}

void loop()
{
    if (truermsflag == 0)
    {
        //TRUE RMS

        truermsflag = 1;
        //END TRUE RMS
    }
    unsigned long currentMac = micros();

    if (currentMac - previousMillis3 > 3)
    {
        previousMillis3 = currentMac;
        //Easy life lines, actual calculation of the RMS requires a load of coding

        inputStats.setWindowSecs( windowLength );
        inputStats2.setWindowSecs( windowLength );
        Sensor = analogRead(A0);  // read the analog in value:
        Sensor2 = analogRead(A1);  // read the analog in value:
        inputStats.input(Sensor);  // log to Stats function
        inputStats2.input(Sensor2);  // log to Stats function

        //Serial.println("run") ;

    }

    if ((unsigned long)(millis() - previousMillisTRUE) >= printPeriod)
    {
        previousMillisTRUE = millis();   // update time every second
        current_Volts = intercept + slope * inputStats.sigma(); //Calibartions for offset and amplitude
        current_Volts = current_Volts * (56.613);             //Further calibrations for the amplitude
        inputvolt = round(current_Volts);
        Serial.print(" START ");
        Serial.print("Input Volts:");
        Serial.println(inputvolt);
        Serial.print("Input Sigma");
        Serial.println(inputStats.sigma());
        Serial.println(" END ");
        output_volts = intercept + slope * inputStats2.sigma();
        output_volts = output_volts * (56.613);
        outputvolt = round(output_volts);
        //Serial.print("Output Volts:");
        //Serial.println(outputvolt);

    }

    //end
    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis3 > 1000)
    {
        // save the last time you blinked the LED
        previousMillis3 = currentMillis;
        digitalWrite(ledPin, LOW);

        // display.showNumberDec(inputvolt, false, 3, 1);

    }

    /*
      unsigned long currentMillis = millis();

        if ((currentMillis - previousMillis1 > 1000) && timerflag == 0) {
          previousMillis1 = currentMillis;
          digitalWrite(ledPin, HIGH);

          if ((digitalRead(switcht) == LOW) && timerflag == 0 && onetimeflag == 0) {

            i = 10;
            onetimeflag = 1;
          }
          if ((digitalRead(switcht) == HIGH) && timerflag == 0 && onetimeflag == 0) {

            i = 180;
            onetimeflag = 1;

          }
          display2.showNumberDec(i--);
          if (i == 0) {
            digitalWrite(TRelay, LOW);
            timerflag = 1;
          }
        }
        //Timer Relay Function END

        //ADC Functions

        //display.setSegments(HIVOLT, 1, 0);

    if (timerflag == 1) {
          display2.showNumberDec(outputvolt, false, 3, 1); // Expect: _14_

          if (outputvolt > 245) {
            display2.setSegments(HIVOLT, 1, 0);
            digitalWrite(TRelay, HIGH);
          }
          else if (outputvolt <= 180) {
            display2.setSegments(L0VOLT, 1, 0);
            digitalWrite(TRelay, HIGH);
          } else {
            display2.setSegments(DONE, 1, 0);
            digitalWrite(TRelay, LOW);
          }
        }

    */

    if (240 < current_Volts)
    {

        digitalWrite(Relay1, LOW);
        digitalWrite(Relay2, HIGH);
        digitalWrite(Relay3, HIGH);
        digitalWrite(Relay4, HIGH);
    }
    if ((90 <= current_Volts) && (current_Volts <= 120))
    {
        digitalWrite(Relay1, HIGH);
        digitalWrite(Relay2, HIGH);
        digitalWrite(Relay3, HIGH);
        digitalWrite(Relay4, LOW);

    }
    if ((121 <= current_Volts) && (current_Volts <= 150))
    {
        digitalWrite(Relay1, HIGH);
        digitalWrite(Relay2, HIGH);
        digitalWrite(Relay3, LOW);
        digitalWrite(Relay4, HIGH);

    }
    if ((151 <= current_Volts) && (current_Volts <= 240))
    {
        digitalWrite(Relay1, HIGH);
        digitalWrite(Relay2, LOW);
        digitalWrite(Relay3, HIGH);
        digitalWrite(Relay4, HIGH);
    }
    //ITimer2.init();
    //ITimer1.init();
    // ITimer1.attachInterruptInterval(TIMER2_INTERVAL_MS, TimerHandler2);
    //ITimer2.attachInterruptInterval(TIMER2_INTERVAL_MS, TimerHandler2);
}

int acVoltage(int adcpin)
{
    int adcvalue = 0, returnresult = 0;
    unsigned long sum = 0, avg = 0, squre = 0;
    double root = 0;

    for (int j = 0; j < 10; j++)
    {

        unsigned long currentMacro = micros();
        unsigned long currentMillis;
        if ((currentMacro - previousmacro > 2000))
        {
            previousmacro = currentMillis;

            adcvalue = average(adcpin);
        }
        squre = (long)adcvalue * adcvalue;
        //delayMicroseconds(667);
        sum += squre;
    }

    avg = (long)sum / 10;
    //Serial.print("after average of squre");
    //Serial.println(avg);
    root = sqrt(avg);
    returnresult = (int)root;
    return returnresult;
}

int average(int pin)
{
    int sum = 0;
    float avg = 0;
    int val = 0;
    int funsend;
    for (int i = 0; i < 5; i++)
    {
        val = analogRead(pin);
        sum += val;

    }

    avg = (float)sum / 5;
    funsend = round(avg);
    //Serial.print(" average function");
    //Serial.println(avg);
    //Serial.print("Value");
    //Serial.println(funsend);
    //delay(20);
    return funsend;

}
</code>```

Please describe what you mean when you say "not stable".


text:
Accessing struct's variable parametrically on ESP8266
I have 2 instances of a struct. One has def values stored and second stores values read from a file on SPIFFS.
I'm trying to use a for loop over all struct's variables - if file was read OK and key was found, store its value in final_par else get value from def_par.
For that, I've created keys array - but I can't find a way to iterate, in a for loop
as final_par.keys[i] = def_par.keys[i] - but this is not possible.
How can it be done ?
struct parameters
{
  bool ext_inputs;
  bool auto_relay_off;
  bool useSerial;
  bool useWDT;
  bool useOTA;
  bool useResetKeeper;
  bool useFailNTP;
  bool useDebugLog;
  char deviceTopic[20];
  char groupTopic[20];
  char prefixTopic[20];
  int inputUpPin;
  int inputDownPin;
  int outputUpPin;
  int outputDownPin;
  int inputUpExtPin;
  int inputDownExtPin;
  int auto_relay_off_timeout;
};
char *keys[] = {"ext_inputs", "auto_relay_off", "useSerial", "useWDT", "useOTA", "useResetKeeper",
                "useFailNTP", "useDebugLog", "deviceTopic", "groupTopic", "prefixTopic", "inputUpPin",
                "inputDownPin", "outputUpPin", "outputDownPin", "inputUpExtPin", "inputDownExtPin",
                "auto_relay_off_timeout"};

parameters def_par{false, false, false, true, true, false, true, "devTopic", "noGroup", "myHome", 2, 1, 14, 12, 0, 2, 60};

parameters final_par;

If you want to copy every value use memcpy(&final_par, &def_par, sizeof(parameters));

it is not possible to access a field by name. how to do it depends on what you want to do with it.

The names only exist in the source code. Once compiled the program has no knowledge of any names.

for dynamic name value pairs with basic data types ArduinoJson can be used. especially if it should be stored in FS

You can create a 'hardcoded' copy function:
void CopyParameter(int parameterIndex)
{
    switch (parameterIndex)
    {
    case 0: final_par.ext_inputs = def_par.ext_inputs; break;
    case 1: final_par.auto_relay_off = def_par.auto_relay_off; break;
    ...
    default: // Error
    }
}

Of course you can also pass final_par and/or def_par as arguments.
If you don't want to use an index, create an enum with the index values for each parameter, like:
enum EParameters
{
    ExtInputs,
    AutoRelayOff
    ...
};

void CopyParameter(EParameter parameter)
{
    switch (parameter)
    {
    case ExtInputs   : final_par.ext_inputs     = def_par.ext_inputs    ; break;
    case AutoRelayOff: final_par.auto_relay_off = def_par.auto_relay_off; break;
    ...
    default: // Error
    }
}

The disadvantage is that you have to keep the structure and the copy function manually synchronized.
The advantage is that you can do a shallow, deep copy or even add more logic depending on each struct member.

You can do it but it can be awkward. You'll need an array of structs, each member of which describes one member of your 'struct parameters' - essentially, an expansion of your present 'keys[]'.
Then you can consult this array randomly or in order to find the name, data-type, and memory offset of a given parameter (indexed by parameter order), or search it, to access the same information by parameter name.
Here's your parameter struct with some (incomplete but runnable) code to list the descriptor array, and incidentally, show how to build and use the array. Note that the code compiles but with a warning that a member of your 'parameters' was not initialized. I chose not to fix that; it isn't used here and doesn't prevent compilation.
struct parameters
{
  bool ext_inputs;
  bool auto_relay_off;
  bool useSerial;
  bool useWDT;
  bool useOTA;
  bool useResetKeeper;
  bool useFailNTP;
  bool useDebugLog;
  char deviceTopic[20];
  char groupTopic[20];
  char prefixTopic[20];
  int inputUpPin;
  int inputDownPin;
  int outputUpPin;
  int outputDownPin;
  int inputUpExtPin;
  int inputDownExtPin;
  int auto_relay_off_timeout;
};
//char *keys[] = {"ext_inputs", "auto_relay_off", "useSerial", "useWDT", "useOTA", "useResetKeeper",
//                "useFailNTP", "useDebugLog", "deviceTopic", "groupTopic", "prefixTopic", "inputUpPin",
//                "inputDownPin", "outputUpPin", "outputDownPin", "inputUpExtPin", "inputDownExtPin",
//                "auto_relay_off_timeout"};

parameters def_par{false, false, false, true, true, false, true, "devTopic", "noGroup", "myHome", 2, 1, 14, 12, 0, 2, 60};

parameters final_par;

// A couple of functions to extract data from an array or struct:
#define countof(a) (sizeof(a)/sizeof(a[0]))                             // ret # of array elements (not bytes)
#define offsetof(struc, member) ((int)(&(((struc*)(0))->member)))   // ret byte-offset from start of struct to the given member

// Enumerate possible parameter types
typedef enum {
   t_bool,
   t_char,
   t_int
} parType;

// Descriptor table - contains name, type, and offset of each parameter
// Could go in flash to save a bunch of RAM
struct descriptor {
   const char *name;
   parType pType;
   uint8_t offset;
} Descriptors[] = {
   { "ext_inputs", t_bool, offsetof(parameters, ext_inputs) },
   { "auto_relay_off", t_bool, offsetof(parameters, auto_relay_off) },
   // ...
   { "inputUpPin", t_int, offsetof(parameters, inputUpPin) },
   // ...
   { "auto_relay_off_timeout", t_int, offsetof(parameters, auto_relay_off_timeout) }
};

void setup() {
    Serial.begin(115200);
    Serial.println("parameter        type          offset\n");
    // List the parameters' names, types, and offsets within 'struct parameters'
    for( uint8_t i = 0;  i < countof(Descriptors);  ++i ){
        Serial.print(Descriptors[i].name);    Serial.print(", ");
        Serial.print(Descriptors[i].pType);   Serial.print(", ");
        Serial.println(Descriptors[i].offset);
    }
}

void loop(){
    ;
}


text:
Why isn't my Arduino Nano Every recognized as a Nano Every and why won't it upload sketch?
I have a genuine Arduino Nano Every board that isn't showing up quite right.  I actually have 2 hooked up to the computer on different ports and one of them, when I click on 'Port' shows as:
COM12 (Arduino Nano Every)

But the other one just shows up as:
COM18

The COM18 device used to have (Arduino Nano Every), but doesn't anymore.  The other problem I have is that when I try to upload a sketch to the device, it compiles and gets to uploading and then has a bunch of errors:
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
avrdude: jtagmkII_getsync(): sign-on command: status -1
An error occurred while uploading the sketch

I've tried changing the selection on "Registers emulation:" between ATMEGO328 and None (ATMEGA4809) but I get the same errors whenever I try to upload a sketch.  Is my Every bricked?  Or is there some way to revive it?
I'm not sure why this happened.  I was able to upload sketches before, and have barely even used this device.
Does somebody have any ideas on how to get this working again, or should I just throw it away and get another one?

the USB chip on Nano Every is a SAMD11 with Arduino firmware. you could try to flash the firmware. https://www.arduino.cc/en/Guide/NANOEvery#firmware-for-samd11d14a

Your programmer chip is bricked. Lol

I'm not the one who voted down, but you might show some effort, like trying to restore the bootloader. Both symptoms are clear: The Arduino does not work as the expected USB device any more. You might need to use another programmer (another Arduino for example) to access it.

Don't worry about the down-vote. If you got 20 you might worry. :)

Encountered this on linux, solved by selecting the tty/ACM0 port


text:
Why do NRF24L01 modules only communicate in 1 direction
I have 2 NRF24L01 +pa +lna modules connected to 2 arduino mini pros. One of the modules is on a joystick and the other one is on a airplane. Everything worked perfectly until last week when they stopped communicating. So I wrote a simple receiver and transceiver code to see if they worked. The result is that if the module on the plane is the transceiver and the joystick is the receiver everything works fine. If they have the opposite roles then I only get empty messages onto the serial monitor way more often than the transceiver sends a message.
Receiver code:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8);

const byte address[6] = "00001";

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

  radio.begin();
  radio.openReadingPipe(0, address);
  radio.startListening();

}

void loop() {
  if (radio.available())
  {
    char text[32] = {0};
    radio.read(&text, sizeof(text));
    Serial.println(text);
  }

}

Transceiver code:
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7,8);

const byte address[6] = "00001";

void setup() {
  radio.begin();
  radio.openWritingPipe(address);
  radio.stopListening();

}

void loop() {

  const char text[] = "Hello World";
  radio.write(&text, sizeof(text));
  delay (1000);
  // put your main code here, to run repeatedly:

}

There are a lot of Chinese clones of the nRF24L01+ chips around, and some work better than others.

switch the modules around

In receiving code....try only defining variable.
char text[32];
You change the datarate , palevel and channel in nrf24l01.
See datasheet for more info.
Or visit https://howtomechatronics.com/tutorials/arduino/arduino-wireless-communication-nrf24l01-tutorial/
You may have power issue because pro mini might not deliver sufficient....to neglect use a 10uf Cap in nrf.


text:
Arduino Uno + SIM808 EVB 3.2.4 not working properly?
So recently I found this tutorial online about the SIM808. It looked super cool so I ordered the sim808 evb 3.2.4 off amazon. Hooked up the module and connected the RX (11) and (10) TX pins.
Here is the code I'm working with tried to follow along as best I could with the tutorial but now I am completely confused, purchased a SIM card activated the SIM card and it seems to be connecting just fine
In the serial monitor sometimes I receive this: 14:05:06.243 -> Init Success, please send SMS message to me!
But most of the time I'm receiving this: 14:04:37.586 -> Sim808 init error
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>
#define MESSAGE_LENGTH 160
char message[MESSAGE_LENGTH];
int messageIndex = 0;
char MESSAGE[300];
char lat[12];
char lon[12];
char wspeed[12];
char phone[16];
char datetime[24];
#define PIN_TX 10
#define PIN_RX 11
SoftwareSerial mySerial(PIN_TX,PIN_RX);
DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,
void sendSMS();
void getGPS();
void readSMS();
void setup()
{
mySerial.begin(9600);
Serial.begin(9600);
//******** Initialize sim808 module *************
while(!sim808.init())
{
Serial.print("Sim808 init error\r\n");
delay(1000);
}
delay(3000);
Serial.println("SIM Init success");
Serial.println("Init Success, please send SMS message to me!");
}
void loop()
{
//*********** Detecting unread SMS ************************
messageIndex = sim808.isSMSunread();
//*********** At least, there is one UNREAD SMS ***********
if (messageIndex > 0)
{
  readSMS();
  getGPS();
  sendSMS();

  //************* Turn off the GPS power ************
  sim808.detachGPS();

  Serial.println("Please send SMS message to me!");

}
}
void readSMS()
{
Serial.print("messageIndex: ");
Serial.println(messageIndex);
sim808.readSMS(messageIndex, message, MESSAGE_LENGTH, phone, datetime);
//*In order not to full SIM Memory, is better to delete it
sim808.deleteSMS(messageIndex);
Serial.print("From number: ");
Serial.println(phone);
Serial.print("Datetime: ");
Serial.println(datetime);
Serial.print("Recieved Message: ");
Serial.println(message);
}
void getGPS()
{
while(!sim808.attachGPS())
{
Serial.println("Open the GPS power failure");
delay(1000);
}
delay(3000);
Serial.println("Open the GPS power success");
while(!sim808.getGPS())
{
}
Serial.print(sim808.GPSdata.year);
Serial.print("/");
Serial.print(sim808.GPSdata.month);
Serial.print("/");
Serial.print(sim808.GPSdata.day);
Serial.print(" ");
Serial.print(sim808.GPSdata.hour);
Serial.print(":");
Serial.print(sim808.GPSdata.minute);
Serial.print(":");
Serial.print(sim808.GPSdata.second);
Serial.print(":");
Serial.println(sim808.GPSdata.centisecond);
Serial.print("latitude :");
Serial.println(sim808.GPSdata.lat);
Serial.print("longitude :");
Serial.println(sim808.GPSdata.lon);
Serial.print("speed_kph :");
Serial.println(sim808.GPSdata.speed_kph);
Serial.print("heading :");
Serial.println(sim808.GPSdata.heading);
Serial.println();
float la = sim808.GPSdata.lat;
float lo = sim808.GPSdata.lon;
float ws = sim808.GPSdata.speed_kph;
dtostrf(la, 4, 6, lat); //put float value of la into char array of lat. 4 = number of digits before decimal sign. 6 = number of digits after the decimal sign.
dtostrf(lo, 4, 6, lon); //put float value of lo into char array of lon
dtostrf(ws, 6, 2, wspeed);  //put float value of ws into char array of wspeed
sprintf(MESSAGE, "Latitude : %s\nLongitude : %s\nWind Speed : %s kph\nMy Module Is Working. Mewan Indula Pathirage. Try With This Link.\nhttp://www.latlong.net/Show-Latitude-Longitude.html\nhttp://maps.google.com/maps?q=%s,%s\n", lat, lon, wspeed, lat, lon);
}
void sendSMS()
{
Serial.println("Start to send message ...");
Serial.println(MESSAGE);
Serial.println(phone);
sim808.sendSMS(phone,MESSAGE);
}`

the code is a mess. please format it properly so that it is legible

why are you asking if it is working properly? ... do you not know what you want it to do and what it is doing?

I recommend you to use AT command ..then using some kind of library. You need to dig into library for better information.
https://randomnerdtutorials.com/sim900-gsm-gprs-shield-arduino/
Go through this link....this will give you a rough idea.


text:
How do I connect 4 or more Arduinos to a single shared GSM Module?
Is it possible to connect 4 or more Arduinos to a single GSM Module.?
All the Arduinos need to send SMS at a specific time daily.
How do I make sure thet don't time collide with each other, other than sending sms at different times for each Arduino?.
I want the SMS to be queued up, and be sent one by one.

connect the GSM to only one arduino

You should consider connecting one Arduino to the GSM module, and connect the 4 Arduinos together using SPI, I2C, or any other inter-hardware comms protocol. Before I knew these options existed, I once wrote a bit of code to send data between Arduinos by having one pin represent the data being sent and another pin changing every time a new bit was available. You could do something similar with an extra line per pairing, so an Arduino could tell the primary that it had new data to send.
Anyway, check out the "Wire Library" - it's basically for this kind of work. I think you'll be happier trying to have one Arduino "in charge" and connected to the CSM while the rest vie for its attention.

At the risk of arguing with myself, give the SPI library a look-in as well. Depending upon the situation, SPI can be easier to work with. It's the simpler of the two protocols.


text:
Longruner Nano ATMega 328P input stays HIGH for 1s longer than the reality
I have a Longruner Nano ATMega 328P (copy of arduino nano, main difference being the USB connector, CH340 instead of the usual FT232, from what I could find using google searches).
I wrote a super basic code to test its signal detection capabilities:
setup(){
  pinMode(13, OUTPUT);
  pinMode(2, INPUT);
}

loop(){
  digitalWrite(13, digitalRead(2));
}

Hard to make it simpler to test a simple thing: when I give a HIGH signal to D2, D13 is HIGH too.
To test it, I used a simple male-male jump cable and connected VIN pin to the D2 one, for a very brief moment. And I notice D13 stays HIGH for around a second (measured with serial, lowest I could get was 996ms after super quickly touching D2 with the jump cable).
I tried to change the pinMode to INPUT_PULLUP following a similar question I found, but it didn't change anything regarding this delay.
Am I doing something wrong? Maybe a wrong configuration? Or is this just a hardware issue due to the fact that I'm using a copy and there's more than just the USb connector that changes?
I can adapt and work with this if it's required, but being able to have an accurate signal detection would help me greatly.

Don't use Vin as a logic source. Use the +5V pin.
Also, disconnecting the pin is not the same as grounding it. It is "floating". For a proper test, connect a +5V to the pin, and follow it with a Gnd.
A floating pin has an undefined logic level.
What would work in your case is to have a (say) 1k resistor between D2 and Gnd. That way, the moment you disconnect the voltage input the "pull-down" resistor will return it to 0V.

@Supamiu alternatively (for testing) configure D2 as INPUT_PULLUP and connect it to ground with the jumper

So you mean I should have a jumper between D2 and GND, and use another jumper to connect +5V to D2 and observe the trigger on D2?

@Supamiu No, you should add a resistor between D2 and GND, not a jumper. A jumper would end up with a short circuit when you connect D2 to +5V. https://www.electronics-tutorials.ws/logic/pull-up-resistor.html


text:
Sending data struct with 2 int fields from Arduino to Raspberry via NRF24L01
I'm trying to do wireless thermometer on max31865 arduino and nrf24l01 but I'm having problem sending whole data struct I can send int or char arrays but when I try to send whole struct I got output as
id: 131073 temperature: 0

Is there error in my code or there is some issue with differences in how arduino and raspberry store data? I don't really have experience in this so my question is how do I send struct that contain two fields of int or there is some better way? I need to transmit id and temperature in one package.
Transmitter code(Arduino)
#include <SPI.h>
#include "RF24.h"
#include <Adafruit_MAX31865.h>

#define RREF      430.0
#define RNOMINAL  100.0

typedef struct{
  int id = 100;
  int temperature = 100;
}
temp;

temp data;

bool radioNumber = 0;
int i =0;
Adafruit_MAX31865 thermo = Adafruit_MAX31865(10, 11, 12, 13);
RF24 radio(7,8);

byte addresses[][6] = {"1Node","2Node"};
bool role = 0;

void setup() {
  Serial.begin(115200);
  thermo.begin(MAX31865_3WIRE);
  radio.begin();
  radio.setChannel(125);
  radio.setPALevel(RF24_PA_MIN);
  radio.powerUp();
  radio.setDataRate(RF24_1MBPS);
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
  radio.stopListening();
}

void loop() {
      data.id = 1;
      data.temperature = 2;
    //int temp = 2; //thermo.temperature(RNOMINAL, RREF);
    Serial.println(temp);
    if (!radio.write( &data, sizeof(data) )){
        Serial.println(F("failed"));
     }
     delay(1000);
}

Receiver code(Raspberry pi b3+)
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include <RF24/RF24.h>

using namespace std;

typedef struct{
        int id = 99;   // debug value
        int temperature = 99;
}
temp;

RF24 radio(22,0);
temp data;

bool radioNumber = 1;
const uint8_t pipes[][6] = {"1Node", "2Node"};

int main(int argc, char** argv)
{
    radio.begin();
    radio.setChannel(125);
    radio.setPALevel(RF24_PA_MIN);
    radio.setDataRate(RF24_1MBPS);
    radio.setRetries(15, 15);
    radio.printDetails();
    if (!radioNumber) {
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1, pipes[1]);
    } else {
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(1, pipes[0]);
    }

    radio.startListening();

    while (1) {
            if (radio.available()) {
                int tem = 0;
                while (radio.available()) {
                    radio.read(&data, sizeof(data));
                }
                cout << tem  << "  " << "id: "<< data.id<< " temperatura: " << data.temperature << endl;
                delay(925);

            }
        }
    return 0;
}

EDIT:
Ok after running sizeof(data) on both devices, I notice that structs have different size 4 bytes for arduino and 8 for raspberry. So change on raspberry side to
typedef struct{
  uint16_t id = 100;
  uintt16_t temperature = 100;
}
temp;

And this is working but, may I ask why int have various size on arduino and raspberry?

Your problem is that you are communicating between an 8-bit and a 32-bit architecture.
On an 8-bit architecture int is 16 bits. On a 32-bit it's 32 bits. Why the difference? Because "it is". It's how it's always been since the dawn of C. The concept of int is a flexible idea with no fixed defined size - the size is largely defined by the architecture and the compiler. Although conventions now dictate that an int will be 16 bits on an 8-bit system and 32-bits on a 32-bit system.
You can think of it as the integer size being the same as the internal register width of the processor but with a lower bound of 16 bits.
This is precisely why the fixed width integer types uint16_t etc exist - so that you can enforce the same data size on different architectures.
Incidentally you should also be aware of the endianness of your systems. In your case they are both "little endian", but "big" (and even "middle") endian systems also exist.  This defines what order each byte of an integer (and other multi-byte data types) is stored in memory. If you send an integer from a little-endian to a big-endian system and don't apply any transformation to the data to reverse the bytes then the values will be completely wrong.

Thank you for such comprehensive answer, I was aware of big/little endian systems but I never thought about differences in architectures like you mentioned. Now I think I got this  next step is to somehow manage with the noise. Again thanks for the nice answer

Had the same issue between an atmega328p and an esp8266, scratched my head for a good couple of hours before stumbling upon this, wouldn't have thought about it, even though it makes perfect sense! Thank you!


text:
WebSocket Server for MKR1000
I was looking for a websocket server for my MKR1000 but nothing I found works.
I tried all the libraries that come with Arduino but half of those don't compile on the MKR1000 and those that do it don't work at all.
Your help would be greatly appreciated!

There is a dedicated  WiFi/Ethernet Shield that supports websocket server. But it is only worked with Uno and Mega. This shield name is PHPoC Shield

This relatively simple one has always worked for me on several Arduinos (but I haven't tried it on the MKR1000 specifically):
https://github.com/morrissinger/ESP8266-Websocket
I have forked it and made some changes, but nothing fundamental:
https://github.com/ocrdu/NINA-Websocket
Have a go; it will probably work for you. Note that it works on more Arduinos than the name suggests; it's quite universal.

Thanks for your answer, but devices based on ESP8266, doesn't work

IIRC (it's been a while), this websocketserver works on other Arduinos as well, it's more universal than the name suggests.

Thanks Ocrdu, https://github.com/ocrdu/NINA-Websocket works fine . I didn't use WiFinina I use instead WiFi101 and work ok.


text:
sensitive distance detection using 2 HC-05 module/ 2 arduino unos
Hi I am doing a project in which I use 2 HC-05 modules and 2 arduino unos driving them. 1 bluetooth module is master and the other is slave. Master module is stationary while slave is moving. If the distance between these 2 modules is less than 1.5 meter, master device turns on a led. If the distance is more than 1.5 meter, the led will not be turned on. This is the basic idea and it works but not as I wanted. I present the code
master device code:
#include <SoftwareSerial.h>
//master device code
SoftwareSerial BTSerial(5, 6); // RX | TX
#define LED 4
unsigned long timer = 0;
unsigned long timeDifference = 0;
char data;

void setup()
{
  Serial.begin(9600);
  BTSerial.begin(9600);
  pinMode(LED, OUTPUT);
  delay(5000);
}

void loop()
{
  BTSerial.write('A');
  timer = millis();
  while(!BTSerial.available()){}
  data = BTSerial.read();
  if(data =='B'){
    timeDifference = millis()-timer;
  }
  Serial.println(timeDifference);

  if(timeDifference < 280){
    digitalWrite(LED,HIGH);
  }else{
    digitalWrite(LED,LOW);
  }
  delay(500);

}

slave device code:
#include <SoftwareSerial.h>
//slave device code
SoftwareSerial BTSerial(5, 6); // RX | TX

char data;

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

void loop()
{
  while(!BTSerial.available()){}
  data = BTSerial.read();
  if(data =='A'){
    BTSerial.write('B');
  }

}

So what happens here is that master device sends a char and starts timer. Slave receives the char and send another char to master device. When master device receives char, it stops timer and looks at how much time passed. The problem is that when I put those bluetooth devices together, the time difference is like 280ms. When I move away in the room with slave device, it is still like same. It is not sensitive. What can I do to make this more sensitive? I am waiting for your opinions

The approach you're using will not work. You're trying to use speed of light time measurement to gauge distance. There are a whole host of problems with that. First, the clock on the Arduino is not fast enough (high enough resolution). You need accurate, sub-nanosecond time resolution for that (see this video: https://www.youtube.com/watch?v=9eyFDBPk4Yw). Second, BLE is a packet protocol. The overhead and variability of sending packets will totally swamp the tiny difference in round-trip time due to speed of light delay.
The usual way to gauge distance with BLE is to measure signal strength. That is also error-prone, but you can at least get rough "immediate", "near", "middle" and "far" distance measurements.
Alternately you could use and ultrasonic range sensor.

hello how can I measure signal strength. What is the way to do so?

Have a look at this question. The RSSI describes the signal strength and thus can give you an indication of the distance.

See Chrisl's comment, which includes a link. Note that the signal strength based distance estimate is fairly crude, and influenced by things like reflective walls and obstructions.

In addition to the concerns above, your code won't work the way you want it to. You are initializing timer every loop so the time difference will always be 0. Instead, you should only write A from master device when it receives the response B and only then reset timer.
void loop()
{
  while(!BTSerial.available()){}
  data = BTSerial.read();
  if(data =='B'){
    timeDifference = millis()-timer;
    timer = millis();
    BTSerial.write('A');
  }
  Serial.println(timeDifference);

  if(timeDifference < 280){
    digitalWrite(LED,HIGH);
  }else{
    digitalWrite(LED,LOW);
  }
  delay(500);
}

Your approach is never going to work no matter how hard you try; it's like trying to use a hammer to bake bread!  If you need accurate time-of-flight distance measurements, use a sensor designed to do that, like the ST Micro VL53L0X time-of-flight IR LIDAR module.


text:
Send JSON body with SIM900 board
I'm trying to send JSON, but i'm not able to set Content-Type header.
Other commands are successful:
[23:49:41:856] AT+SAPBR=3,1,"CONTYPE","GPRS"␍␊
[23:49:41:899] ␍␊
[23:49:41:899] OK␍␊
[23:49:52:327] AT+SAPBR=3,1,"APN","internet"␍␊
[23:49:52:367] ␍␊
[23:49:52:367] OK␍␊
[23:49:59:585] AT+CSQ␍␊
[23:49:59:594] ␍␊
[23:49:59:610] +CSQ: 18,0␍␊
[23:49:59:610] ␍␊
[23:49:59:621] OK␍␊
[23:50:07:449] AT+SAPBR=1,1␍␊
[23:50:08:501] ␍␊
[23:50:08:512] OK␍␊
[23:50:13:900] AT+SAPBR=2,1␍␊
[23:50:13:928] ␍␊
[23:50:13:928] +SAPBR: 1,1,"127.0.0.1"␍␊
[23:50:13:955] ␍␊
[23:50:13:955] OK␍␊
[23:50:21:261] AT+HTTPINIT␍␊
[23:50:21:291] ␍␊
[23:50:21:291] OK␍␊
[23:50:40:284] AT+HTTPPARA="CID",1␍␊
[23:50:40:320] ␍␊
[23:50:40:320] OK␍␊
[23:50:47:652] AT+HTTPPARA="URL","http://127.0.0.1:5000/data"␍␊
[23:50:47:713] ␍␊
[23:50:47:713] OK␍␊
[23:50:54:359] AT+HTTPPARA="CONTENT","application/json"␍␊
[23:50:54:414] ␍␊
[23:50:54:414] +CME ERROR: operation not allowed␍␊
[23:51:06:576] AT+HTTPDATA=38,10000␍␊
[23:51:06:612] ␍␊
[23:51:06:612] DOWNLOAD␍␊
[23:51:12:034] ␍␊
[23:51:12:050] OK␍␊
[23:51:19:386] AT+HTTPACTION=1␍␊
[23:51:19:414] ␍␊
[23:51:19:414] OK␍␊
[23:51:27:747] ␍␊
[23:51:27:758] +HTTPACTION:1,500,290␍␊
[23:51:35:599] AT+HTTPREAD␍␊
[23:51:35:628] ␍␊
[23:51:35:628] +HTTPREAD:290␍␊
[23:51:35:635] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">␊
[23:51:35:692] <title>500 Internal Server Error</title>␊
[23:51:35:735]
Internal Server Error
␊
[23:51:35:766]
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.
␊
[23:51:35:935] ␍␊
[23:51:35:935] OK␍␊

ip addresses aren't real.
My server received invalid request (with JSON body, but without special header), and replied 500 Internal Server Error.
Revision: 1137B08SIM900M64_ST_DTMF_JD_MMS

127.0.0.1?! How do you expect to get there?

I wrote ip addresses aren't real.. I don't want to share my public ip.

Sorry, missed that bit. I'm viewing on my phone at the moment.

You need firmware version B10 to use the content Param. You have B08.

@Majenko, thank for your reply. At the moment I'm trying to upgrade to 1137B15SIM900M64_ST through pl-2303hx adapter, but my attempts are unsuccessful.

It's not something I have ever tried (I have never used a SIM900), so I can't help with that sorry.

Thanks for @Majenko.
I solved problem by upgrade firmware to 1137B15SIM900M64_ST.


text:
Best strategy to parse 5 byte arrays to find a pattern
Ok here it goes, my first ever question posted to stackexchange! Please be gentle on me!
I am using an Arduino UNO (at the moment, will move to a faster micro later - but still use an Arduino sketch) to read in data as an SPI slave to extract the display data off of a commercial product that has no other exploitable data output that I can use. I am using a very generic sketch that Nick Gammon posted for the purpose of demonstrating the capability - and I can read the SPI data coming in ok. (Thanks Nick!)
The data is being pulled from a commercial product that has a 8 character, 5X7 dot matrix LED display that was specially made for this product and after exhaustive searches and emails to Broadcom/Avago - has no datasheet, but there are slightly similar products that I was able to use to get a bit of a handle on how the part works, I just went on the assumption that even if the interfaces are not the same, they probably didn't reinvent their command structure. However; the display doesn't have a nice driver chip embedded like your typical parallel LCD display.
I had to do a bit of reverse engineering using a logic analyzer to figure out:

It is SPI data at 4MHz.
The gist of the commands coming in and in what order
Used excel to convert the pixel mapping of the display to the font actually getting displayed on the device.
That the displayed font/text for each of the 8 characters is made up of 5 bytes - where the bit positions of those bites end up lighting a tiny LED in the display so the letter 'H' looks like 0x7F, 0x08, 0x08, 0x08, 0x7F. Each byte controls a column of 7 LEDs, ignoring a row.

Right now:

I am using a modified version of Nick's slave sketch to simply extract the first 44 bytes of the command string to display something on the display
all that is important to me is the 40 bytes after the first 4
because those bytes are what get displayed. I am taking 5 elements of the 44 byte array that I know correspond to a character and spitting them out on the serial monitor such as:
0x00, 0x01, 0x5F, 0x11, 0x00 // i
0x7F, 0x08, 0x08, 0x08, 0x7F // H
etc...

And now after a lengthy introduction - my actual question:
I need to parse the patterns of each of the 5 bytes that makes up a letter and convert it to ASCII text so that the actual word is displayed on the serial monitor.
Back when I used to use another programming language / environment on PICs we had things like LOOKUP and LOOKDOWN which made comparing patterns a bit more abstracted, which is weird considering Arduinos...
I need help coming up with a function that takes the 5 bytes that I need to build each letter from and maybe compares it to an array that represents each possible letter and then maybe passes the matching result to another function to build / concatenate the displayed word out of those characters? That method sounds wildly inefficient, but it's all my little brain can come up with and I'm drawing a blank on how to even do that... I don't need a lot of error checking because thus far the data I'm getting is spot on with what I see on the actual display - we are also talking one 8 character word (max) at a time and it is fairly static, no scrolling words or a lot of chatter - just a single word or some data that changes relatively infrequently. But the displayed data can be different enough than the last to make trying to match entire words out of the question unless it's a side feature to speed things up. I think work properly it needs to work on one character out of 8 - one at a time. Another thought is maybe summing the 5 bytes to determine if we have a match or not, but I'm not sure if two different characters might end up having the same sum? Math is not my strong suit. Thanks for any and all help.

i see no reason for such a lengthy post ... it appears that you want to decode the data going to a 5x7 dot matrix display and determine which character is being displayed ... the data arrives on SPI .... am I understanding it correctly?

How many different characters are likely to be displayed? 10? Can't you just use a lookup table?

So it is a 5x7 LED (so 35 different LEDs per character) and thus the 5 characters (at 8 bits each) would allow for 40 combinations, and so 5 are unused. Is this right so far? A lookup table of all the actual characters that arrive is probably the easiest, you could store that in PROGMEM.

Comparing all the bytes for every character may sound inefficient, but the MCU is pretty fast. So unless you have something else that requires a lot of computation, this will be plenty fast enough. Though you could indeed try to do some tricks, like adding the bytes (as you suggested), or XOR the five bytes. I like to use excel for these things. Put the 5 bytes in five columns. Put your formula in the last column. Then check if all calculated values are unique. You could also try using only certain pixel-columns.

If you post the pixel data for all the characters, I'm willing to do this for you, as it sounds like a fun exercise. Though as I stated, it's probably unnecessary.

If you have a large data set you could implement a tree search. The top of the tree is all the possible first bytes. The next layer is the possible second bytes following each possible first byte - etc. Or you could make a partial tree - where you have a number of arrays of bytes 2-5 (which could actually be a 32-bit integer) and those arrays are grouped by the first byte. If you have things in order you could also "divide and conquer" your data set instead of doing a linear search. There's plenty of algorithms to choose from.

Another thought: a 5x7 array of pixels gives you 35 bits of data. If you can find 3 pixels that never get turned on you could discard those and compress the data into 32 bits. That can be easily represented as a number the Arduino can handle and make searching easier. Especially if you were to use divide and conquer to narrow in on the data, since > and < is easier with a pure number.

XOR would be a bad choice for creating a "checksum". Symmetrical letters (of which there are plenty) will negate most of the XOR operation leaving you with just the value of the middle byte.

This is really a pure programming problem rather than an Arduino one, but to get you started, you could do a table lookup, like this:
#include <stdio.h>
#include <string.h>

// number of items in an array
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

unsigned char patterns [] [5] =
  {

    { 0x7F, 0x08, 0x08, 0x08, 0x7F },   // H

    // other byte patterns here

  };  // end of patterns

char patterns_converted [] =
  {

  'H',

  // other letter equivalents here

  };  // end of patterns_converted

char convert_pattern (unsigned char what [5])
  {
  for (int i = 0; i < ARRAY_SIZE (patterns_converted); i++)
    if (memcmp (what, patterns [i], 5) == 0)
      return patterns_converted [i];

  return '?';

  } // end of convert_pattern

int main ()
{

  unsigned char test1 [5] = { 0x7F, 0x08, 0x08, 0x08, 0x7F };
  unsigned char test2 [5] = { 0xAA, 0xBB, 0xCC, 0xDD, 0xEE };  // won't be found

  char x = convert_pattern (test1);

  printf ("Result for test1 is %c\n", x);

  x = convert_pattern (test2);

  printf ("Result for test2 is %c\n", x);

}

You would find out all your bit patterns and put them in the patterns array, and then put the equivalent letter in the patterns_converted array.
The function convert_pattern does a linear search of the table of patterns, returning the corresponding letter, or "?" if not found.
I coded that in pure C++, but since the Arduino IDE basically uses C++ you should be able to convert it for your use.

Thank you-Thank you! Nick Gammon saves the day yet again! I was able to convert your pure C++ to Arduino-C++ and build my lookup table and test cases and it works beautifully! Now I just have to add a little code to compare the last displayed data to new to keep it from needlessly updating. Sorry for all the words - I do have trouble with being concise.


text:
can i use L298N H bridge with 12v 7AH battery?
guys i am working on a rare project so i just need to ask some questions
I have a L298N H bridge motor driver, a Aduino uno board, 12v dc 4000rpm 2ampere motor and a 12v 7ah battery
I just want to ask can i use 12v 7ah battery with my L298N H bridge motor driver
please answer this project is very important to me
please help

Probably, as long as the specifications of the motor and the H-bridge are met. Remember a fully charged 12V battery delvers about 12.7-12.8 Volts. Don’t discharge it beyond 50% (3.5Ah).

Yes, though at 2A you're at the top end of the L298N current limit. Expect excessive heating. You will have to manage your thermal environment appropriately.
You should consider a more capable driver with more current headroom and less heat problems. (Note: the L298N is a very old chip and uses old technology. It's not a good choice for modern drive systems and a more appropriate device should be investigated, for example the MC33931 as the first hit on google).


text:
What's the most direct way to assign Serial.read() bytes to an array?
I'm trying to send NMEA 0183 sentences through LoRa.
Every dinstict NMEA message looks like several char arrays (sentences) followed by '\n'.
In the below picture we see one NMEA distinct message:

This message arrives in the Arduino input buffer every 1 second with differentiated values (numbers) and it has to be sent over LoRa as fast as possible.
In order to send it over LoRa I need to read all bytes on the input buffer and assign them to an array and send them as an array, not one by one. I know that Serial.read() reads only one byte, and that's the problem.
How can I read all bytes and send them as a whole?
This is my code:
  if (Serial.available()) {
     c = Serial.read();
     rf95.send((char *)c, sizeof(c));
     rf95.waitPacketSent();

I use RadioHead library, and the definition of rf.95.send is:
RH_RF95::send  (const uint8_t * data, uint8_t len)
c is of char type.

There is no such thing as "all the bytes ... as a whole" - serial is only individual bytes. Anything more than that is merely a wrapper around reading single bytes.

What I mean with "whole", is an array

@Majenko, for sending over LoRa it matters? is there some overhead? a frame/ envelope?

The reception of serial is often the slowest portion. Anything else you do is pretty much insignificant.

I was missing a null termination character. That got me reading garbage from all over the buffer.
Adding a '0' at the end of the buffer's length is mandatory.
Plus, as David G. noticed, sizeof() function is incorrect. strlen() must be used.

Just use a counted string, not a null terminated string.  Never do strlen() as you know the length already.

The length is not fixed. Sentences can be more or less depending on what sensors must be used every certain moment, and that can happen in run-time.

The length is not fixed, but the length is KNOWN (after you read it).  In fact, you need to know the length to insert the null.  Why insert the null at the known length, and then use strlen to find the length?

The transmitter node doesn't read the length of the transmitting char array until this function: rf95.send((char *)nmea.getSentence(), strlen(nmea.getSentence()));
The receiver node knows the length after accepting it and reading it but there is no strlen() function in there.

Well, what the call probably should be is rf95.send(nmea.getSentence(), nmea.getSentenceLength());  First off: don't cast.  If you seem to need to cast, you've done something wrong.  Figure out what.  Secondly: your nmea wrapper class should know the length of the data it has, so ask it directly.

@DataFiddler suggested something like readBytesUntil.  In fact, you can just use readBytesUntil.  It returns either when timeout happens or when you reach the specified terminator.  It consumes, but does not include the terminator.  The timeout defaults to 1000 milliseconds, and can be modified with the setTimeout() method.
One downside is that you can't differentiate timeout, full buffer, and terminator reached.  This shouldn't be a problem except for serial transmission errors.
If your data is coming in at the NMEA standard 4800 baud, you could reasonably change the timeout to 5 milliseconds and still work.

One thing that might bite you, is the line:
     rf95.send((char *)c, sizeof(c));

It is a mistake to cast the first parameter.  The error you got indicated you should write:
     rf95.send(&c, sizeof(c));

But the sizeof is also wrong.  The return type of Serial::read() is int, in part because there are 257 possible values.  If you declared c as an int, its size would be 2, not 1.
In any case, if you are using readBytesUntil, you pass the same buffer you passed it to rf95.send(), and the return value from the first as the second parameter of the second.

You are right about "sizeof()", strlen() must be used

NO.  strlen() is NOT appropriate.  You already know the number of characters you have read.  Just use that.  In the original example, there was 1 character, so the constant 1 is correct.  In using readBytesUntil, That returns the number of bytes read, which is what should be used.

All more complex Serial reading methods are based on read().
Luckily there's a terminating character '\n' in your case, so you can implement something similar to readBytesUntil by yourself, if you want to.

I suppose I could loop through all data and add them to an array and avoid all '\n' characters except from the las one?


text:
How to fix Master-Slave communication between Arduino Micros Not Working and no serial monitor output problem?
I needed to send MPU6050's accelerometer and gyroscope data and voice recognition module's voice command status flag through the HC-05 Bluetooth module to receiver Bluetooth and Arduino. But because both Bluetooth HC-05 and voice recognition module use software serials, and not more than one software serial can function at a time, I had to search for a solution. I found that one solution is to alternate the serials. But my project is a wireless head mouse project. So, to decrease the mouse cursor lag, I need HC-05 and voice recognition module V3.1 to work parallelly. So, I went to implement the Master/slave approach to use two Arduino boards (one for the collection and calculation of data from MPU and voice recognition module) and the other for just getting these values and sending this data through HC-05. But I got stuck right in the basics. I tried to send data between two interconnected Arduino Micros in Master/Slave manner which uses I2C protocols, but it didn't work. I got nothing on the serial monitor set to 9600 bauds and "Newline" selected on the slave board's Serial monitor. The code I used was from the Arduino examples itself.
Circuit connections between Arduino Micros:
A4->A4
A5-> A5
Gnd-> Gnd
These connections are from the Example tutorials on this website which I followed and double-checked.
I tried both Master Writer &Slave Receive, and also Master reader & Slave sender.
Master Writer & Slave Receiver sketch respectively
// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

#include <Wire.h>

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop()
{
  Wire.beginTransmission(4); // transmit to device #4
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte
  Wire.endTransmission();    // stop transmitting

  x++;
  delay(500);
}

    // Wire Slave Receiver
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Receives data as an I2C/TWI slave device
// Refer to the "Wire Master Writer" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

#include <Wire.h>

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  Serial.begin(9600);           // start serial for output
}

void loop()
{
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}

Master Reader & Slave Sender sketch respectively
// Wire Master Reader
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Reads data from an I2C/TWI slave device
// Refer to the "Wire Slave Sender" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

#include <Wire.h>

void setup() {
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start serial for output
}

void loop() {
  Wire.requestFrom(8, 6);    // request 6 bytes from slave device #8

  while (Wire.available()) { // slave may send less than requested
    char c = Wire.read(); // receive a byte as character
    Serial.print(c);         // print the character
  }

  delay(500);
}

// Wire Slave Sender
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Sends data as an I2C/TWI slave device
// Refer to the "Wire Master Reader" example for use with this

// Created 29 March 2006

// This example code is in the public domain.

#include <Wire.h>

void setup() {
  Wire.begin(8);                // join i2c bus with address #8
  Wire.onRequest(requestEvent); // register event
}

void loop() {
  delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
  Wire.write("hello "); // respond with message of 6 bytes
  // as expected by master
}

Why not just use one Arduino (or arduino-like) board that has more than one UART? There are plenty of options.

@Majenko the problem is that this project is assigned to me by a client I know. And he told me to do it under a low budget. So, I have to make it for the low budget using my code. And also, there are only a two Arduino boards that support the functions needed. One of them being the Arduino Micro, and the other the Arduino Due.

I guess you looked at the tutorials for the Ardiuno Uno. On the Micro the I2C lines are not on A4 and A5. This pinout diagram states, that they are on D2 and D3. So try connecting these together


text:
How to connect more than one arduino serial port together
The idea is to connect more than 1 arduino slave to master as shown in schamatic

simulate this circuit – Schematic created using CircuitLab
The problem is TX slave can not just combine to master RX.
It need to done some trick like tri-state buffer to make slave TX one at time.
Anyway, avr port can config as tristate buffer.
(Q1)Is there any software solution to done this?
Second If I connnect TX to RX for half-duplex communication (using 1 data line). How to make Rx stop listenning to its self while transmiting data?

Diodes and a resistor.

Two resistors--that's it! I just added my answer.

You can do it with two diodes and a resistor:

simulate this circuit – Schematic created using CircuitLab
You'll still have to implement some system to prevent collisions, but electrically that will be sound.

Does it have programing solution?

Tip magically turn the shave devices into open drain? No. Not unless you have the ability to reprogram the slaves and write your own implementation of software serial that emulates open drain.

Will something like Serial.end() and oinMode(x,INPUT) trick work?  or I need to write my own Serial library?

On the slave devices, yes, that would work - but would also disable serial reception. To prevent collisions you need the master to tell a slave it can send, which means reception needs to be working, or you need to implement some other form of signalling architecture (and that would most likely need more changes to your hardware). It's simplest to just add those diodes and a resistor and do it properly - or not use Serial at all and use a proper bus system like I2C.

Without the diodes or some form of direct control over when each slave can send a collision could be fatal to one or both of the slaves. It could cause a dead short circuit (one sends a 1 and the other a 0 at the same time) which could burn out the IO pins.

This approach you have keeps the Rx line always pulled to 5V except when a Tx line from a Slave goes LOW. I had to look it up to ensure that idle is in fact HIGH and not LOW, and yep, it is: https://learn.sparkfun.com/tutorials/serial-communication/all#wiring-and-hardware -- see the diagram under "Hardware Implementation", and also: A signal at the VCC level (3.3V, 5V, etc.) indicates either **an idle line**, a bit of value 1, or a stop bit. So, yes, this solution would definitely work, although I think I prefer my 2-resistor solution I've posted here over this solution.

Sparkfun's explanations are excellent. I'm grateful they and Adafruit, in addition to Arduino of course, exist.

For this scheme to work, you need to make sure that at most one slave
drives its TX at any given time. You will have to devise some protocol
by which the master addresses one slave, and then only that slave
responds. The problem is:

both slaves must have their serial ports turned on in order to notice
when they are addressed by the master
an active serial port keeps its TX pin in a low impedance state,
actively driving it HIGH when not transmitting data.

The best way out of this dilemma is to modify the hardware, as per
Majenko’s answer. If, for whatever reason, you cannot do that
modification, there may be a software-only solution, but only if the
underlying hardware allows you to turn off the serial transmitters of
the slaves, while keeping the serial receivers active.
The Arduino API dos not allow you to keep the serial transmitter active
while the receiver is disabled: the functions Serial.begin() and
Serial.end() control the transmitter and the receiver as a whole. You
may be able to do that by accessing the hardware at a lower-level. You
didn't state what kind of Arduino you are using. Assuming you have
something similar to an Uno, you can disable the transmitter with:
UCSR0B &= ~_BV(TXEN0);

and enable it again with:
UCSR0B |= _BV(TXEN0);

If you want to use the Arduino API for serial communication, you will
have to disable the transmitter right after Serial.begin():
const uint8_t TX_PIN = 1;

void setup() {
    pinMode(TX_PIN, INPUT_PULLUP);  // valid when transmitter is off
    Serial.begin(9600);             // enable serial port
    UCSR0B &= ~_BV(TXEN0);          // disable transmitter
}

But beware that then it will be enabled for a sort time (no more than a
few microseconds), right before you disable it. This may cause a short
if one slave boots while the other is transmitting data.
One problem with this kind of software-only solution is that bugs do
happen, and with your circuit, a bug in the protocol handling can burn
your hardware. If you can manage to at least add some protective
resistors, as in Gabriel Staples’ answer, that should keep you safe.

You can use a single-pole dual throw switch. a simple switch that can switch lines between multiple slaves.
Limitation: The salve will not be able to create a request unless the master has selected its corresponding lines.
Master has to actively ask for the data or send commands to the slaves. Slaves may not be able to initiate the communication (when not selected)

Appreciate for your participation but I prefer software solution first.

Update Nov. 2020: my answer below, though a bit insightful and with many correct statements, is wrong. My schematic below will indeed prevent the Arduinos from damaging each other, but it will not allow proper communication. Majenko's answer here is right. Use his schematic, but read my answer below as well for additional insight and ideas.

ORIGINAL ANSWER:
You can do it with 2 resistors, as shown below. That's it! Super simple!
Electrical explanation:
The goal is simply to protect the two Tx pins from killing each other. Without the resistors one Slave might be writing output LOW while the other Slave is writing output HIGH, which is a dead short--damaging both devices. Simply putting a 1k resistor in series with each Tx pin like this prevents that dead short. Now, if one Tx pin is HIGH while the other is LOW, you get current flow from one into the other through a total of 2kOhms, which means the current will be only I = V/R = 5V/2000 Ohms = 2.5mA, which isn't a problem, as each pin can handle 40mA max and 20mA~30mA continuous safely. Also, a 1k resistor isn't much load, so you should still get good serial throughput even at fairly high baudrates.

simulate this circuit – Schematic created using CircuitLab
The code:
The communication code will be done as normal with Serial.print() or Serial.write(), Serial.read(), etc. Nothing special about the code, except you should make an effort to keep the slaves from talking at the same time to prevent data corruption from slave to master. So, you should have Master request data from a Slave, and a Slave should only talk when it knows the other Slave is not talking (ex: it should only talk when spoken to). The Master coordinates the communication. In this way, this is like SPI: the Master is in charge and tells each Slave when to talk. Since both Slaves are always listening, just use an "ID" to indicate which slave is being spoken to. If a Slave doesn't see it's ID, it should ignore the message.
Ex:
Request a new temperature reading from Slave 1:
Serial.println("1:T");

Now, wait until you get the full response from Slave 1, then send out a request for...let's say, some current reading, from Slave 2:
Serial.println("2:C");

The exact communication codes are up to you--your imagination is the limit.
Again, both slaves see both messages, but they look at the number at the beginning and only reply if it's their number. Doing this technique, you could connect nearly infinite Slaves all on the same line, just adding a 1k resistor to each Slave's Tx line before the junction where they all connect back to the Master's Rx line.
Pretty cool. I never thought of doing this before until you asked the question. Good question.

You hardware setup can prvent damage but I wonder if one slave send no data (given High signal)  will the data get voltage divider effect that divide signal amplitude to half?

@Mlab: Indeed. A “silent” TX actively pulls the line HIGH. That's why you need the diodes.

@EdgarBonet  that why I seraching for solution to make A “silent” TX become high impedance. it should be possible by software some how.

I think my answer is wrong, and needs the diodes due to idle Tx being actively driven (low impedance) HIGH. I'll update my answer as soon as able. I measured the impedance of a HIGH Tx line at something like 26 Ohms early this morning.

26 Ω is the expected resistance of an ATmega pin configured as OUTPUT. C.f. the datasheet section on pin driver strength.


text:
Four temperature SHT31 sensors on ESP32
I have to read out the teperature and humidity of four independent SHT31 sensors with the help of an ESP32. Is there any prefered way to do this, since the only examples I can find online are only with one sensor. I have no access to the address pins of the sensors.
Thank you in advance for any help!

Have you found a solution for your problem ... I am trying to use four SHT31 sensors in a ESP32. I have tried to use the multiplexer with those, but because I am using an I2C extender I could not connected. Thanks for your help and guideline.

Try using TS3A5018, part from TI.
You can then connect 4 independent I2C devices (SHT31).
There are also dedicated I2C channel multiplexers such as these.
Below is the example for I2C multiplexer from TI

Yes, reading 4 SHT31 is possible with an ESP32.
If you have the analog version, readout is quite trivial: you simply use 8 analog inputs (2 for each) to read the signal.
If you have the digital version, which has an I2C interface, you need to control each sensor's address pin separately to select the specific sensor you want to read. Otherwise, there will be an address collision on the bus.

Thank you! The problem is, that I have no access to the address pins

@zet0 Then you need to get I2C bus multiplexers, to get each chip on its own bus lines


text:
Windows upload from command line gives Access Denied
saw somewhere that in order to upload a hex file to an arduino you can look at the Arduino IDE - see the command it runs, then replace the hex file with your file.
this is the command I see in the output window:
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/bin/avrdude -CC:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:C:\Users\yossi\AppData\Local\Temp\arduino_build_696128/sketch_aug21a.ino.hex:i
I try running this from command (as admin):
cd "C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr\bin"
avrdude -CC:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:C:\Users\foosMaster\AppData\Local\Temp\arduino_build_696128/sketch_aug21a.ino.hex:i

gives me Access is denied.
in fact, just running avrdude gives the same error, so really - this has nothing to do with the COM port (which works fine from the IDE)
I tried closing the IDE and running again, tried rebooting - the same.
*** edit 1 ****
I actually ran this:
cd "C:\PROGRA~1\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr\bin"
avrdude -CC:\PROGRA~1\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.42.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM5 -b115200 -D -Uflash:w:C:\Users\foosMaster\AppData\Local\Temp\arduino_build_696128/sketch_aug21a.ino.hex:i

since I didn't want to mess with wrapping the params - but I don't really think it matters - as the problem is running avrdude without any parameter still gives me the same error: Access is denied.

This is because you are running the Windows App Store version of the IDE.
Windows doesn't like you messing with the insides of App Store programs (I think it scares it...).
Install the real version of the IDE from the Arduino.cc website and it will work.


text:
Is there a method of figuring out whether or not my stepper drivers are dead?
I'm working on a project that involves stepper motors, and I'm mainly using DRV8825 stepper drivers. At the moment, it seems like only one of my drivers actually gives the motors any current. The others usually return 0s when I measure their VREFs. One returns a value but still can't pull the motors. After checking all of my DRV8825s and finding only two returned VREFs, I checked my A4988s and none of them gave anything (aside from power supply voltage when measuring different pins). Is there a way I can figure out whether my stepper drivers are actually fried? I have a suspicion that maybe the potentiometers on the drivers are thrown off or there's some other issue I can't place. I'm happy to give more information if that can help to figure out what's going on here. Thank you!

Most surefire way to tell if your drivers work is to wire them up CORRECTLY and try them out.  You should not be frying them if you have the correct setup (including current limit) for your conditions.  That said, conditions include your heat sink install and the environmental temperature.
The usual gotchas:

Note that DRV8825 and A4988s may have different pin locations so be sure to orient them correctly (check their EN pin location) if using a shield.
Also note that the gains from the voltage to the current limits will be different for the different model #s.  Be sure to use an appropriately sized screw driver and attach the meter to the screw driver as you turn to adjust the current limit.


text:
Switching a Solenoid Using Arduino's 5V Output?
I'm a bit stumped on how to switch on a solenoid using a transistor using my Arduino Nano's 5v Output. The solenoid runs on 12V, so I used an NPN transistor to connect the 12V source to the solenoid whenever Arduino sends current to the transistor's base. I connected all the grounds together to the Nano's ground pin, but the solenoid still doesn't switch.
I know the transistor works properly, because the solenoid switches when I use the battery to send base current instead of the Nano. I would think the Nano is capable of sending enough current to activate the Collector -> Emitter path but might be wrong. I'm also wondering if it's an issue with grounding the circuit, but I've made sure there is a common ground. What do you think I'm doing wrong? BTW the transistor I am using is D882P. I would appreciate any help.

simulate this circuit – Schematic created using CircuitLab

This is really an electronics question, because there is nothing specific about the Arduino here, except that it has a maximum output of around 20ma. You have a few problems here, including that the load should be on the "high" side (in series with the collector), there is no flyback protection diode, and that there should be a base resistor to limit current through base. Would you like me to migrate this question to Electronics Stack Exchange?

Please post your code too.

Example answer here: Can arduino be used as a switch?

It would probably be closed as a duplicate if I migrate it, I warn you. Try searching that site for ideas.

I have a page about driving devices from the Arduino on my own web site, if you want some ideas and lengthier discussions about resistor values. However Electronics Stack Exchange is a great site for general electronics questions.

Thanks, I am aware of that stack exchange. Unfortunately, I got banned for asking questions like this. Perhaps I will make a new account

Please don't make a new account. The SE mods particularly dislike people who try to work their way around restrictions by making multiple accounts. You have an answer below, I suggest you take a look at it.

The fact is that the various Stack Exchange sites are supposed to be a repository of useful information. Thus you search for an answer to your question (or something similar) before enraging people by posting a question which has been asked many times before, and has very useful answers.

Low-side switching an inductive load (such as a relay) using a microcontroller (such as Arduino), NPN BJT transistor (with full base resistor calculations), and snubber/flyback diode
Note: this answer demonstrates using the 2N3904 NPN transistor for all of the calculations, since that's what's in the schematic in the question. However, after writing the answer, I noticed the words at the end of the question state it is a D882P (also an NPN type) transistor. So, just follow my methodology here but use the appropriate values for your NPN transistor type, which you can obtain from the datasheet. A quick Google search for "d882p datasheet" reveals this as a potential datasheet.
2N3904 is an NPN transistor (datasheet), as opposed to a PNP transistor, so it must be connected directly to GND and switch the low side of the circuit only, so wire it like this instead:

simulate this circuit – Schematic created using CircuitLab
Notice I've added a diode, D1, to dissipate inductance-induced voltage spikes created when electromagnetic fields (a form of energy storage) collapse in the inductor each time you turn the switch OFF. This diode, due to its function (not type), is called a "flyback", "snubber", or "clamp" diode. Again, it protects the transistor and other components from inductance-induced voltage spikes from the relay coil/inductor. When a voltage spike occurs, it will simply travel around that loop through the diode, relay, and resistor R2 again and again and again until it has all been dissipated as heat in those components and there is no more voltage spike remaining.
I've also added a resistor R2 to limit current through the relay coil. You'll have to size this appropriately to get the correct current through your relay coil, based on the relay's datasheet. If your relay's datasheet says to hook up the relay to 12V directly, you can remove this resistor.
And you'll definitely need a base resistor (R1 in my circuit) or else you'll burn up your Arduino pin.
First, let's collect some necessary values from the Datasheet. These will be used in the calculations below:

VBE(sat) = 0.65 to 0.95V.

This is the diodic voltage drop from Base to Emitter when the transistor is "saturated", or fully ON.

hFE_min = 30

Notice in the screenshots below that I have crossed out all of the 2N3903 transistor hFE entries so they don't distract us from the 2N3904 entries, which is the transistor type I'm using for this example. I then chose the lowest hFE entry for this transistor, which is 30.
This is the "guaranteed" minimum, or worst-case, DC current gain. The formula is simply: I_max_permitted_from_Collector_to_Emitter = gain * I_Base_to_Emitter. So, if your gain is 30, for example, and you drive a base current of 5mA from Base to Emitter, then the "guaranteed" maximum possible current allowed from the Collector to the Emitter will be 30 gain * 5mA = 150mA. Again, this is not what you will get into the Collector, this is what you could get before the transistor itself starts limiting the current into the Collector rather than your load limiting the current through the Collector.

Ic_max_continuous = 200mA

This is the max continuous current you can get from Collector to Emitter without overheating the transistor (assuming, I think, you have adequate cooling through conduction and possibly even convection and radiation via heat sinks--I need to brush up on the thermal and power equations myself). The datasheet may specify if a heat sink is required to achieve this current, but regardless, you should keep your continuous current down to about half this value or less if possible, as the device may reach crazy high temperatures of like 150 C or something with this current and no convective cooling or heat sink. For short bursts, hitting this current is just fine.

Here are some screenshots of where to find these values in the datasheet:

Notice in this next image I've crossed out all of the 2N3903 hFE lines so they don't distract us from the 2N3904 entries, which are for the transistor we care about in this example. Choose the lowest hFE value as the gain you will use in your estimates in order to have a "conservative" estimate, virtually guaranteed to fully turn on your transistor in all cases (ie: for all Collector current values you might like to switch on and off).

Now, let's calculate a Base resistor value for an NPN BJT transistor, assuming your goal is to fully turn on (saturate the Base-Emitter channel of) the transistor:
VBE(sat) has a diodic voltage drop of 0.65 to 0.95V, so your resistor would have to burn off 5 - 0.95 = 4.05V to 5 - 0.65 = 4.35V. Let's just use the lower 4.05V value so we will size for higher currents and faster turn-on speeds.
Your minimum hFE (gain) value for the 2N3904 transistor (not the 2N3903) is 30. Maximum continuous Collector current, Ic is 200mA, so let's increase that by a factor of 2 to 4 and size for 200mA * 3 = 600mA to 1) more fully saturate the Base to Emitter channel and get closer to full turn on under all cases, 2) get faster turn-on, and 3) overcome the fact that decreased gain occurs at higher Collector currents. In Figure 15. DC Current Gain, from the datasheet, for instance, shown below, it shows that the normalized gain decreases from ~0.28 at 100mA Collector current to ~0.13 at 200mA Collector current, which means that the gain of 30 found in the datasheet at 100mA Collector current indicates the gain at 200mA Collector current will actually be approximately 30 gain/(0.28/0.13) = 13.9 gain. Simply multiplying the Collector current we are sizing for by a factor of 2 to 4 (3 in our case) accounts for this fact, so we will use 600mA instead of 200mA in our maximum Collector current calculations below.

So, 600mA / 30 gain = 20mA Base to Emitter to get rock solid turn-on performance. Arduino can do up to 40mA per pin so this is Ok. Note that I recommend 30mA max per Arduino pin (for the ATmega328 microcontroller), and there is also a combined output limit for the ATmega328 microcontroller of 200mA for all pins combined, which you should keep in mind. I describe this on my website in my article "Arduino Power, Current, and Voltage Limitations" here.
V = IR, so R = V/I, so resistor, R that we need = 4.05V/0.020A = 202.5 Ohms. This is the minimum recommended base resistor size. Don't go too much smaller than 200 Ohms, if you go smaller than that at all. A 100 Ohm resistor, for instance, would allow a maximum base current of I = V/R = (I intentionally use the higher voltage value here) 4.35V/100 Ohms = 43.5mA, which could damage your pin.
Don't go larger than 600 Ohms or else you risk not turning on the transistor fully by not saturating the Base to Emitter channel. A 600 Ohm resistor would give you a guaranteed max Base to Emitter current of I = V/R = (I intentionally use the smaller voltage value here) 4.05V/600 Ohms = 6.75mA, which with a gain of 30 would give you a max Collector current (based on your relay coil resistance now) of 6.75mA * 30 gain = 202.5 mA. However, as indicated from Figure 15 shown above, a more realistic gain at 200mA Collector current might be only 13.9, which means your maximum allowed Collector current with a 600 Ohm resistor would be 6.75mA * 13.9 gain = 93.8mA. But, at this current your gain would actually be > 30, not 13.9, which leads back to the 200mA Collector current number. You can see this is a juggling game of numbers since the gain is NOT constant NOR linear, but rather is a function of Collector current, as shown by Figure 15 above. So, perhaps your actual maximum allowed Collector current with a resistor of 600 Ohms would be more like 130mA or something. The point is: any larger of a base resistor than 600 Ohms and you most likely won't be able to achieve the transistor's rated maximum continuous Collector current even if you wanted to. So, there's a reasonable R value range!: 200 Ohms to 600 Ohms, perhaps even leaning more towards the 200 Ohms side if you expect to have high momentary Collector currents anywhere near your maximum continuous Collector current rating of 200mA.

Additional notes on high-side vs low-side driving with NPN BJT or N-Channel MOSFET transistors, for clarity:
An NPN transistor can switch high-side voltages too--you just have to drive the necessary Base to Emitter current is all (and don't exceed any maximum ratings)! That's it! So...if you try to drive the high side, think about it: you turn it on with 5V so your voltage from Collector to GND can't exceed ~5V now because as current starts to flow through the collector, voltage would come up on the Emitter side until your base current no longer flows. Your system would be fighting itself. Even if you gave it 12V before the Collector you'd never see more than ~5V at the Emitter, assuming your Base drive voltage was 5V. If you can design around it, go for it, but generally the "easy" or "normal" way to do things is to use NPN to switch low-side voltages and PNP to switch high-side voltages.
The same goes for N-channel and P-channel MOSFETS. Use N-channel to switch low-side voltages and P-channel to switch high-side voltages, UNLESS you are doing some fancy driving (again), of N-channel to switch high-side voltages, as N-channel MOSFETs are more efficient and can switch higher currents than their equivalent P-channel pairs, due to some electron hardware mumbo jumbo stuff.
Keywords: transistor sizing; BJT transistor circuit calculations, equations, and datasheet; arduino and electrical engineering: transistor (BJT) sizing, equations, datasheet, and calculations example
Additional reading:

[my answer] Electronics Stack Exchange: When is a MOSFET more appropriate as a switch than a BJT? [and a BJT more appropriate than a MOSFET]

They said they had a D882P transistor in fact (still looks like an NPN though).

Ah shoot, you're right. His image is deceiving.

@NickGammon, I went ahead with the calculations anyway. I provide the example. They can figure it out for their case. I needed the practice on these calcs anyway. I haven't done them in a while. I miss electronics and EE. Feel free to migrate this question if you see fit. Your call of course.

Ah shoot. I forgot my flyback/snubber diode too! I'm away from the computer now. Oh well. I'll update it later.

Thanks for the detailed explanation. Why does switching low side voltages with NPN work? Sorry, my understanding of electronics is very basic

@ILike, in order to turn on the large current channel from Collector to Emitter in an NPN transistor, you must drive a small current from Base to Emitter. Since voltage only drives current from a location with a higher voltage to a location with a lower voltage, that means you would have to have >12V at the Base to drive a current to the Emitter if the voltage at the Emitter was ~12V. You don't have >12V at the Base, however, you have only 5V. So, you must position the transistor such that the Emitter is connected to GND so you can drive a current from Base to Emitter with only 5V at the Base.

Furthermore, with the NPN transistor at the high side and with a driving voltage of only 5V at the Base, you will end up in an equilibrium with the voltage at the Emitter being equal to 5V - VBE, and the transistor barely on, allowing only a trickle current from Collector to Emitter, and such that the transistor acts like a resistor, burning off the 12V - (5V - VBE) (the difference between the voltage at the Collector and the voltage at the Emitter) as heat in the transistor. So in your setup, the voltage at the Emitter is about 4.5V or so, with only a trickle from Collector to Emitter.

Update: I discovered I was using the 2N3903 transistor's lowest hFE gain of 15 in all my calculations, so I updated the answer to use the 2N3904 transistor's lowest hFE gain of 30 instead. This doubled the recommended size range result to use for the base resistor.