body:
I have a keyestudio board identical to the arduino mega 2560. I use the matching keyestudio ks0156 W5100 ethernet shield. My code uses the following library for ethernet `paulstoffregen/Ethernet@0.0.0-alpha+sha.9f41e8231b`

I have the following code (initialization and "loop" code):

```c
const int port_broadcast{27333};
char udp_packet_buffer[UDP_TX_PACKET_MAX_SIZE + 1];

const byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

EthernetUDP udp;

void init_ethernet() {
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Error initializing Ethernet using DHCP");

    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
      Serial.println("Ethernet shield was not found.");

      while (true) {
        delay(1);
      }
    }

    if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }

    Ethernet.begin(mac, ip, dns);
  } else {
    Serial.print("DHCP assigned IP ");
    Serial.println(Ethernet.localIP());
  }

  udp.begin(port_broadcast);
}

void update_time() {
  int packet_size = udp.parsePacket();
  if (packet_size > 0) {
     const auto num_read = udp.read(udp_packet_buffer, UDP_TX_PACKET_MAX_SIZE);
    Serial.print("Received ");
    Serial.print(num_read);
    Serial.println(" bytes: ");
    if(num_read > 0) {
      udp_packet_buffer[num_read] = '\0';
      Serial.println(udp_packet_buffer);
    }
  }
}
```

On my Windows device in the same network I have a service that every 2 seconds posts the current time in the format `2021-09-19 15:37:30` over UDP broadcast to my local network. This works quite well until suddenly the board starts receiving wrong values. Here is a sample output from the board:

```
DHCP assigned IP 192.168.1.120
Received 19 bytes:
2021-09-19 19:59:37
Received 19 bytes:
2021-09-19 19:59:39
Received 19 bytes:
2021-09-19 19:59:41
Received 19 bytes:
2021-09-19 19:59:43
Received 19 bytes:
2021-09-19 19:59:45
Received 19 bytes:
2021-09-19 19:59:47
Received 19 bytes:
2021-09-19 19:59:49
Received 19 bytes:
2021-09-19 19:59:51
Received 19 bytes:
2021-09-19 19:59:53
Received 19 bytes:
2021-09-19 19:59:55
Received 19 bytes:
2021-09-19 19:59:57
Received 19 bytes:
2021-09-19 19:59:59
Received 19 bytes:
2021-09-19 20:00:01
Received 19 bytes:
2021-09-19 20:00:03
Received 19 bytes:
2021-09-19 20:00:05
Received 19 bytes:
2021-09-19 20:00:07
Received 19 bytes:
2021-09-19 20:00:09
Received 19 bytes:
2021-09-19 20:00:11
Received 19 bytes:
2021-09-19 20:00:13
Received 19 bytes:
2021-09-19 20:00:15
Received 19 bytes:
2021-09-19 20:00:17
Received 19 bytes:
2021-09-19 20:00:19
Received 19 bytes:
2021-09-19 20:00:21
Received 19 bytes:
2021-09-19 2
Received 19 bytes:
␒0"1    0
Received 19 bytes:
2021-09-19 20:00:␒7
Received 19 bytes:
2021-09-1        ␒0
Received 3 bytes:
2
Received 24 bytes:
20:00␚3!␁B��

```

As you can see suddenly the output makes no sense anymore. There is no sensor attached, no input happening or anything else going on, it just randomly starts outputing wrong values. Also when it starts outputing wrong values it does not continue for long before completely stopping to receive anythin alltogether. According to Wireshark the windows service keeps posting the right data, so I can rule out that it has something to do with the service.

So my question is, why would my board suddenly stop receiving data over UDP without any apparent reason or interaction from the outside? Reseting the board will immediately continue to print more data, but until then it stopped. It got adequate power supply and the LAN cable is very short. Am I doing something wrong in my code? Does it look like an issue with the Ethernet shield?

For completeness sake this is the C# code from the service that is sending to the UDP broadcast:
```cs
  private UdpClient _time_broadcaster;
  private readonly IPEndPoint _broadcast = new IPEndPoint(IPAddress.Parse("192.168.1.255"), 27333);

  private void timer_elapsed(object source, ElapsedEventArgs args) {
   var now = DateTime.Now;
   var year = now.Year;
   var month = now.Month;
   var day = now.Day;

   var hour = now.Hour;
   var minute = now.Minute;
   var second = now.Second;

   var result = $"{year:D4}-{month:D2}-{day:D2} {hour:D2}:{minute:D2}:{second:D2}";
   var data = Encoding.ASCII.GetBytes(result);
   _time_broadcaster.Send(data, data.Length, _broadcast);
  }
```

title: Arduino mega ethernet Udp client randomly failing

Answers: 0


body:
I currently have 2 Arduinos both hooked up to HC-12s and have successfully got them communicating. But I am now trying to be able to process the data sent across and store it as a variable so as to make comparisons. But I'm getting junk data that comes over with the code, which prevents me from being able to do these comparisons.

For example, from one arduino when I sent "stop" I received

    stop<⸮=l⸮⸮⸮

I cant figure out what this junk is from, also, I've limited the receivedChars to a size of 4, why am I getting more than 4 characters?

The code from the sender

    #include <SoftwareSerial.h>

    SoftwareSerial HC12(3, 2); // HC-12 TX Pin, HC-12 RX Pin

    void setup() {
      Serial.begin(9600);             // Serial port to computer
      HC12.begin(9600);               // Serial port to HC12
      Serial.print("Checking HC-12 module: ");
      HC12.write("AT");               //Check for response(this is sending data to the HC, the SET pin must be low for this to work)
      delay(1000);
      HC12.write("AT+RX");            //Gets configs of HC-12
    }

    void loop() {
      while (HC12.available()) {        // If HC-12 has data
        Serial.write(HC12.read());      // Send the data to Serial monitor
      }
      while (Serial.available()) {      // If Serial monitor has data
        HC12.write(Serial.read());      // Send that data to HC-12
      }
    }

The simplified receiving code

        #define BYTELENGTH 4 //Limited to 4 chars
           #define ENDMARKER '\n'  //To know when stop stop reading serial

           SoftwareSerial HC12(3, 2); // HC-12 TX Pin, HC-12 RX Pin

      Serial.begin(9600); //Fastest it can be on the nano
      HC12.begin(9600); // Serial port to HC12s

          char receivedChars[BYTELENGTH - 1];
          int byteIndex;
          char curChar;

          while (HC12.available()) {        // If HC-12 has data
            curChar = HC12.read();
            if(curChar != ENDMARKER){
              receivedChars[byteIndex] = curChar;
              byteIndex++;
            }
          }
          if(strcmp(receivedChars,"") != 0){
            Serial.println(receivedChars);
            receivedChars[0] = 0;
          }

title: Where are these junk characters (from serial) coming from?

Answers: 3

body:
It appears you have a baud rate problem. I am surprised you are getting anything. You need software to start the serial port such as SoftwareSerial mySerial(rxPin, txPin) then in setup  mySerial.begin(9600); You need that in each application and the baud rates need to be the same.

I have used SC16IS750 I2C/SPI-to-UART devices as an external UART, they work great and have many nice features such as a 64 bytes of transmit and receive FIFOs. Some versions of this have been obsoleted but they are still available and work fine. You get 8 additional I/Os as well.

body:
I would say you are printing data outside of your `char` array, because you didn't terminate the C-string in it and the size of your array is too small.

You have

    #define BYTELENGTH 4 //Limited to 4 chars
    char receivedChars[BYTELENGTH - 1];

so your `char` array is only 3 elements big. When you want to save a string in that array, you always need to terminate it with a null character `\0` (which is also zero in decimal representation). So in that `char` array you only have space for 2 characters. But your message "stop" is 4 characters long, so you need a `char` array with at least 5 elements. If you are not in an extreme tight memory situation I would suggest using a buffer with a bit headroom above your biggest message (to be sure, that nothing breaks, if you later use messages that are a bit longer). So more like this:

    #define BYTELENGTH 10 //Limited to 4 chars
    char receivedChars[BYTELENGTH + 1]; // message length + null character termination

And then you need to change your receiving code to add a null character at the end of the message. Also you might want to actually use the newline character `\n` as message delimiting (which you are currently not doing):

    bool full_message_received = false;

    void loop(){
        while (HC12.available()) {        // If HC-12 has data
            curChar = HC12.read();
            if(curChar != ENDMARKER){
              receivedChars[byteIndex] = curChar;
              byteIndex++;
            } else {
              receivedChars[byteIndex] = '\0'; // terminating the c-string
              full_message_received = true; // marking the message as fully received
            }
        }
        if(full_message_received){
            Serial.println(receivedChars);
            receivedChars[0] = 0;
            full_message_received = false;
        }
    }

**What happens, if I don't terminate the string with a null character?** All the functions, that handle C-strings (like `strcmp()` or also `Serial.print()`) use the null character to determine, at which point the string is at its end. They don't know the size of your array, so they just read byte after byte, until they reach the null character. They even read more data than is in your array. The junk characters are most likely exactly, what currently is placed in the memory directly after your array. `Serial.print()` doesn't know, that they don't belong to the C-string, since you didn't use the null character to tell it that. It just keeps printing characters, until it reaches a byte, that is zero.

You even wrote data to memory outside of the array. Depending on what comes directly after your array in the memory this can be without any problems, but you might also overwrite some other data, without knowing, what that data is. That can lead to very weird and hard to debug problems. Be sure to never write outside of your array. You might break things in weird ways.

body:
According to [this vidéo in French][1] it appeared that the problems comes from the SoftwareSerial library which if not reliable enough to provide accurate timings for your transmission. There are alternate software serial libraries (like AltSoftSerial), which use hardware timers, but I can't tel you more because I didn't try to use it.

All I can say, is that I my case removing SoftwareSerial to use the defaut hardware serial port solved the problems I had.

Alternatively, you can use I²C ⇒ UART IC like MAX3100, in order to provide aother hardware UART (With MAX3100 you'll need to add a 3.6468 or 1.8234 MHz crystal and 2×22pf capacitors) - I also didn't try it yet (Chip and crystal are ordered though. Or also you should be able to make the i2c ⇒ UART conversion with one more Arduino.

  [1]: https://youtu.be/ArAcRfPpIYI?t=798


body:
If I search Google for "arduino nano pin numbers", all results show that the pin number of D2 is 5. But that did not work. I searched for some sample codes, and they were 3 for D3 and 5 for D5, etc. So, in codes, the pin number for D`n` is `n`. Then what are the numbers in these diagrams?

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

  [1]: https://i.stack.imgur.com/ICuN3.png

title: Why are the pin numbers of the diagrams and of the code different?

Answers: 3

body:
Every chip datasheet (and also the Arduino boards) uses 2 different ways to refer to the pins:

- Counting the physical pins in the order as they appear on the chosen package of the chip
- Referring to the pins by their function

The first way is only for referring to specific pin positions from the outside, for example when you are building the actual circuit. This also includes special pins like Vcc, GND and Reset. Those pins cannot be referenced by the code (wouldn't make much sense). Also the microcontroller on the inside of its package doesn't know in which package it got stuck by the manufacturer. Each package has a different pin order and form factor. So this counting only makes sense in the context of placing this specific package of the chip into a circuit (like where is Vcc, where ground and where do I need to connect to that specific digital pin), but makes no sense to use for the code inside the controller.

For referring to pins from inside the controller (aka in the code) we use the function of the pins. On an Arduino you have mainly digital and analog pins, which can be controlled. So for the convenience of beginners (which are targeted by the Arduino framework) the digital and analog pins are just numbered. Those are the numbers, that are normally written only the Arduino board. So D2 means the third digital pin inside the Arduino framework. A0 is the first analog pin. Where that pin is physically located on the board isn't interesting for the code, nore does the code know the actual location. For the code its just the third digital output hardware and so on.

**TL;DR:** For building the circuit we must refer to pin positions (like where is Vcc, where is ground) to connect the chip/microcontroller correctly. But the internal code doesn't know, where the physical pins are located and the actual location can also depend on the packaging. So internally we use a different counting system based on the pin function. The Arduino way of counting the digital and analog pins just hides away complexity for the beginner. As reference the numbers are also printed on the Arduino board itself.

---

In case you want to go deeper into the rabbit hole:

Actually the microcontroller has different hardware for different functions incorporated. For example: The analog pins can be used by the ADC (Analog to Digital Converter) to measure an analog voltage. But they also each have digital input and output hardware, just like any other digital pin. Most pins of a microcontroller are multi purpose. The code has to decide, what hardware gets to be connected to the respective pins. When I use `pinMode(2, OUTPUT)` I tell the microcontroller to connect the third digital output hardware to its respective physical pin. When I use `analogRead(A1)` I tell it to connect the second analog channel of the ADC to its respective pin and read an analog voltage through the ADC.

That means, that the code only knows of the function hardware and that it can be connected to their respective pins (whichever these pins are on the outside world). **The numbering in digital and analog pins is only an additional abstraction layer to hide the complexity from beginners.** Actually the code controls the hardware functions via Special Function Registers (SFR). These are special pieces of memory, which are physically hardwired to the respective hardware in the microcontroller. For the digital output hardware the pins are sorted into groups of up to 8 pins. These groups are called Ports, and are numbered with characters. When you look at [this pinout of the Arduino Nano][1], you see, that the Arduino pin D2 is also named PD2, which means PortD third pin (counting from zero up). Arduino pin D8 is also named PB0, so PortB first pin. Functions like `pinMode()`, `digitalWrite()` and `digitalRead()` all just manipulate the SFRs for the wanted port to set the respective pin. Refer to the [Documentation on Port Manipulation][2] for learning how to do it yourself. For beginners it is just easier to use the markings on the board - the Arduino pin number - instead of bearing with the ports and their SFRs directly.

  [1]: https://www.teachmemicro.com/arduino-nano-pinout-diagram/
  [2]: https://www.arduino.cc/en/Reference/PortManipulation

body:
> Why are the pin numbers of the diagrams and of the code different?

Because the Arduino designers chose to re-use the name "pin" for the chip's programmable signal lines, despite it's more common and already existing use to mean any of the protruding external connections to the device.

body:
There are at least four ways of referring to pins on any Arduino board:

1. **Board-order**: Simple numeric order (1,2,3 ...) of physical location of pins on printed circuit board anticlockwise from the USB end (or some arbitrary end)
2. **Arduino-name**: Names used in Arduino source code and/or PCB silk-screen annotation (D1,D2 ... A0,A1 ...).
3. **IC-order**: Simple numeric order of corresponding pin on IC according to numbering used on manufacturers data sheet.
3. **IC Function name**: Names for functions available on pin (RESET, VCC, INT0, PB0,PB1,PB2 ...) as described in data sheet for IC.

For example:

|Nano PCB Pin#|Arduino Name|ATMega328 TQFP Pin#|ATMega328 DIP Pin#|ATMega328 function|
|----------|------------|---|--------------|------------------|
|     1    | D13        |17 |      19      | PB5, SCK, PCINT5 |
|     2    | 3V3        |N/A|      N/A     | N/A              |
|     3    | REF        |20 |      21      | AREF             |
|     4    | A0         |23 |      23      | PC0, ADC0, PCINT8|
|     5    | A1         |24 |      24      | PC1, ADC1, PCINT9|
|etc

There are lots of different Arduino and Arduino-like boards that use the ATMega328, some use different ATMega328 packages (DIP, TQFP, etc) with different pin arrangements. Many arrange the physical PCB pins differently. This is why there isn't a fixed one to one relationship and it is partly why the Arduino IDE provides for it's own simplified naming that it attempts to apply consistently and portably across a variety of different microcontrollers.

---

[![Nano Pinout by PigHixx][1]][1]
[![Key by PigHixx][2]][2]

<sup>(c) PigHixx w/o permission.</sup>

  [1]: https://i.stack.imgur.com/nf4SW.png
  [2]: https://i.stack.imgur.com/cgHjP.png


body:
[![enter image description here][1]][1]
I have 3 adafruit MPUs hooked up to adafruit I2c Multiplexer. All of which is hooked up to a Arduino uno.
Attached is also my code.

    /* Assign a unique ID to this sensor at the same time */

    /*Adafruit_HMC5883_Unified mpu1 = Adafruit_HMC5883_Unified(1);
    Adafruit_HMC5883_Unified mpu2 = Adafruit_HMC5883_Unified(2);*/

    #define TCAADDR 0x70

    #include <Adafruit_MPU6050.h>
    #include <Adafruit_Sensor.h>
    #include <Wire.h>
    Adafruit_MPU6050 mpu1 = Adafruit_MPU6050();
    Adafruit_MPU6050 mpu2 = Adafruit_MPU6050();
    Adafruit_MPU6050 mpu3 = Adafruit_MPU6050();

    void displaySensorDetails(Adafruit_MPU6050 *mpu)
    {
    sensor_t sensor;
    mpu->getGyroSensor();
    Serial.println("------------------------------------");
    Serial.print ("Sensor: "); Serial.println(sensor.name);
    Serial.print ("Driver Ver: "); Serial.println(sensor.version);
    Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);
    Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" uT");
    Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" uT");
    Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" uT");
    Serial.println("------------------------------------");
    Serial.println("");
    delay(500);
    }

    void setUpMPU(Adafruit_MPU6050 *mpu)
    {
      mpu->setAccelerometerRange(MPU6050_RANGE_8_G);
      Serial.print("Accelerometer range set to: ");
      switch (mpu->getAccelerometerRange()) {
      case MPU6050_RANGE_2_G:
        Serial.println("+-2G");
        break;
      case MPU6050_RANGE_4_G:
        Serial.println("+-4G");
        break;
      case MPU6050_RANGE_8_G:
        Serial.println("+-8G");
        break;
      case MPU6050_RANGE_16_G:
        Serial.println("+-16G");
        break;
      }
      mpu->setGyroRange(MPU6050_RANGE_500_DEG);
      Serial.print("Gyro range set to: ");
      switch (mpu->getGyroRange()) {
      case MPU6050_RANGE_250_DEG:
        Serial.println("+- 250 deg/s");
        break;
      case MPU6050_RANGE_500_DEG:
        Serial.println("+- 500 deg/s");
        break;
      case MPU6050_RANGE_1000_DEG:
        Serial.println("+- 1000 deg/s");
        break;
      case MPU6050_RANGE_2000_DEG:
        Serial.println("+- 2000 deg/s");
        break;
      }

      mpu->setFilterBandwidth(MPU6050_BAND_21_HZ);
      Serial.print("Filter bandwidth set to: ");
      switch (mpu->getFilterBandwidth()) {
      case MPU6050_BAND_260_HZ:
        Serial.println("260 Hz");
        break;
      case MPU6050_BAND_184_HZ:
        Serial.println("184 Hz");
        break;
      case MPU6050_BAND_94_HZ:
        Serial.println("94 Hz");
        break;
      case MPU6050_BAND_44_HZ:
        Serial.println("44 Hz");
        break;
      case MPU6050_BAND_21_HZ:
        Serial.println("21 Hz");
        break;
      case MPU6050_BAND_10_HZ:
        Serial.println("10 Hz");
        break;
      case MPU6050_BAND_5_HZ:
        Serial.println("5 Hz");
        break;
    }
    }

    void tcaselect(uint8_t i) {
    if (i > 7) return;
    Wire.beginTransmission(TCAADDR);
    Wire.write(1 << i);
    Wire.endTransmission();
    }

    void setup(void)
    {
    while (!Serial)
        delay(10); // will pause Zero, Leonardo, etc until serial console opens
    Serial.begin(115200);
    Serial.println("HMC5883 Magnetometer Test"); Serial.println("");
    Serial.println("HMC5883 Magnetometer Test"); Serial.println("");

    /* Initialise the 1st sensor */
    tcaselect(0);
    mpu1.setAccelerometerRange(MPU6050_RANGE_8_G);
    Serial.print("Accelerometer range set to: ");
    switch(mpu1.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      Serial.println("+-2G");
      break;
    case MPU6050_RANGE_4_G:
      Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
     Serial.println("+-16G");
      break;
    }
    mpu1.setGyroRange(MPU6050_RANGE_500_DEG);
    Serial.print("Gyro range set to: ");
    switch (mpu1.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println("+- 2000 deg/s");
      break;
    }
    mpu1.setFilterBandwidth(MPU6050_BAND_21_HZ);
    Serial.print("Filter bandwidth set to: ");
    switch (mpu1.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println("5 Hz");
      break;
    }

    /* Initialise the 2 sensor */
    tcaselect(1);
    mpu2.setAccelerometerRange(MPU6050_RANGE_8_G);
    Serial.print("Accelerometer range set to: ");
    switch(mpu1.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      Serial.println("+-2G");
      break;
    case MPU6050_RANGE_4_G:
      Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
     Serial.println("+-16G");
      break;
    }
    mpu2.setGyroRange(MPU6050_RANGE_500_DEG);
    Serial.print("Gyro range set to: ");
    switch (mpu1.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println("+- 2000 deg/s");
      break;
    }
    mpu2.setFilterBandwidth(MPU6050_BAND_21_HZ);
    Serial.print("Filter bandwidth set to: ");
    switch (mpu1.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println("5 Hz");
      break;
    }

    /* Initialise the 3rd sensor */
    tcaselect(2);
    mpu3.setAccelerometerRange(MPU6050_RANGE_8_G);
    Serial.print("Accelerometer range set to: ");
    switch(mpu1.getAccelerometerRange()) {
    case MPU6050_RANGE_2_G:
      Serial.println("+-2G");
      break;
    case MPU6050_RANGE_4_G:
      Serial.println("+-4G");
      break;
    case MPU6050_RANGE_8_G:
      Serial.println("+-8G");
      break;
    case MPU6050_RANGE_16_G:
     Serial.println("+-16G");
      break;
    }
    mpu3.setGyroRange(MPU6050_RANGE_500_DEG);
    Serial.print("Gyro range set to: ");
    switch (mpu1.getGyroRange()) {
    case MPU6050_RANGE_250_DEG:
      Serial.println("+- 250 deg/s");
      break;
    case MPU6050_RANGE_500_DEG:
      Serial.println("+- 500 deg/s");
      break;
    case MPU6050_RANGE_1000_DEG:
      Serial.println("+- 1000 deg/s");
      break;
    case MPU6050_RANGE_2000_DEG:
      Serial.println("+- 2000 deg/s");
      break;
    }
    mpu3.setFilterBandwidth(MPU6050_BAND_21_HZ);
    Serial.print("Filter bandwidth set to: ");
    switch (mpu1.getFilterBandwidth()) {
    case MPU6050_BAND_260_HZ:
      Serial.println("260 Hz");
      break;
    case MPU6050_BAND_184_HZ:
      Serial.println("184 Hz");
      break;
    case MPU6050_BAND_94_HZ:
      Serial.println("94 Hz");
      break;
    case MPU6050_BAND_44_HZ:
      Serial.println("44 Hz");
      break;
    case MPU6050_BAND_21_HZ:
      Serial.println("21 Hz");
      break;
    case MPU6050_BAND_10_HZ:
      Serial.println("10 Hz");
      break;
    case MPU6050_BAND_5_HZ:
      Serial.println("5 Hz");
      break;
    }

    /* Display some basic information on this sensor */
    tcaselect(0);
    displaySensorDetails(&mpu1);
    tcaselect(1);
    displaySensorDetails(&mpu2);
    tcaselect(2);
    displaySensorDetails(&mpu2);
    }

    void loop(void)
    {
    /* Get a new sensor event */
    sensors_event_t a, g, temp;
    tcaselect(0);
    mpu1.getEvent(&a, &g, &temp);
    /* Display the results (magnetic vector values are in micro-Tesla (uT)) */
    Serial.print("Sensor #1 - ");
    //Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print(" ");
    //Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print(" ");
    //Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print(" ");Serial.println("uT");
    Serial.print("Acceleration X: ");
    Serial.print(a.acceleration.x);
    Serial.print(", Y: ");
    Serial.print(a.acceleration.y);
    Serial.print(", Z: ");
    Serial.print(a.acceleration.z);
    Serial.println(" m/s^2");

    tcaselect(2);
    mpu2.getEvent(&a, &g, &temp);
    /* Display the results (magnetic vector values are in micro-Tesla (uT)) */
    Serial.print("Sensor #2 - ");
    Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print(" ");
    Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print(" ");
    Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print(" ");Serial.println("uT");
    Serial.print("Acceleration X: ");
    Serial.print(a.acceleration.x);
    Serial.print(", Y: ");
    Serial.print(a.acceleration.y);
    Serial.print(", Z: ");
    Serial.print(a.acceleration.z);
    Serial.println(" m/s^2");
    delay(500);
    }
In this configuration All of my mpu sensors are sending back unreasonable numbers for acceleration and temperature. Am I initializing my mpus correctly in my code?

  [1]: https://i.stack.imgur.com/Kpq0S.png

title: Adafruit MPU-6050 and adafruit I2C Multiplexer

Answers: 2

body:
It seems like you would need to call `.begin()` on your `Adafruit_MPU6050` instances, [like the examples do][1].

So, following the pattern, in `setup()` you would need to:

```c++
 tcaselect(0);
 if (!mpu1.begin()) {
    Serial.println(F("Failed to find MPU6050 chip 1"));
    while (1) {
      delay(10);
    }
 }

 tcaselect(1);
 if (!mpu2.begin()) {
    Serial.println(F("Failed to find MPU6050 chip 2"));
    while (1) {
      delay(10);
    }
 }

 tcaselect(2);
 if (!mpu3.begin()) {
    Serial.println(F("Failed to find MPU6050 chip 3"));
    while (1) {
      delay(10);
    }
 }
```

I see you're removing some repetition with functions.  I'm guessing you just haven't gotten to doing that with the repeated `switch` statements for printing frequencies and such. You may want to put your `mcu1`/`mcu2`/`mcu3` into an array instead for similar reasons.

An array of `Adafruit_MPU6050`:

```c++
Adafruit_MPU6050 mpus[3];
```

The code for calling `begin()` could look something like:

```c++
size_t index = 0;
for (auto &an_mpu: mpus) {
  tcaselect(index);
  if (!an_mpu.begin()) {
    Serial.print(F("Failed to find MPU6050 chip, mpu["));
    Serial.print(index);
    Serial.println(']');
    Serial.println(F("Halting..."));
    while (1) {
      delay(10);
    }
  }

  ++index;
}
```

  [1]: https://github.com/adafruit/Adafruit_MPU6050/blob/2.0.5/examples/basic_readings/basic_readings.ino#L16

body:
You don't need the I2C multiplexors at all - I currently have seven MPU6050 modules being managed by one Teensy 3.5 chip.  Four MPU6050's are on one of the T3.5's I2C busses, and the remaining three are on another.  I could run them all from just one I2C bus, but I split them just for wiring convenience.  The 'trick' is to replace the I2C address of each MPU6050 in turn in the setup() routine, as shown by the code associated with the blog post referenced below

See [this post][1] and related ones on my blog site 'Paynter's Palace'.

  [1]: https://www.fpaynter.com/2020/07/replacing-hc-sro4-ultrasonic-sensors-with-vl53l0x-arrays-part-iv/

I've been using this technique for quite a while now, so let me know if you have any additional questions.

22 Sept 21 edit:

Here's the function that handles address initialization for the four MPU6050's on the Wire2 I2C bus:

    bool InitWire2Sensors()
    {
      delay(1000);
      Serial.printf("Initializing VL53L0X Sensor Array Elements on Wire2\n");
      bool retval = true;

      //Put all sensors in reset mode by pulling XSHUT low
      digitalWrite(LF_XSHUT_PIN, LOW);
      digitalWrite(LC_XSHUT_PIN, LOW);
      digitalWrite(LR_XSHUT_PIN, LOW);
      digitalWrite(Rear_XSHUT_PIN, LOW);

      //left-front
      //input w/o pullups sets line to high impedance so XSHUT pullup to 3.3V takes over
      pinMode(LF_XSHUT_PIN, INPUT);
      delay(10);

      if (!lidar_LF.init())
      {
        Serial.println("Failed to detect and initialize LF sensor!");
        retval = false;
      }
      else
      {
        Serial.printf("lidar_LF successfully initialized at %x\n", lidar_LF.getAddress());
        lidar_LF.setMeasurementTimingBudget(20000);
        lidar_LF.startContinuous();

        lidar_LF.setAddress(DEFAULT_VL53L0X_ADDR + 4);
        Serial.printf("lidar_LF. address is now 0x%x\n", lidar_LF.getAddress());
      }

      //now bring lidar_LC only out of reset and set it's address
      //input w/o pullups sets line to high impedance so XSHUT pullup to 3.3V takes over
      pinMode(LC_XSHUT_PIN, INPUT);
      delay(10);

      if (!lidar_LC.init())
      {
        Serial.println("Failed to detect and initialize LC sensor!");
        retval = false;
      }
      else
      {
        Serial.printf("lidar_LC successfully initialized at %x\n", lidar_LC.getAddress());
        lidar_LC.setMeasurementTimingBudget(20000);
        lidar_LC.startContinuous();

        lidar_LC.setAddress(DEFAULT_VL53L0X_ADDR + 5);
        Serial.printf("lidar_LC. address is now 0x%x\n", lidar_LC.getAddress());
      }

      //now bring lidar_LR only out of reset and set it's address
      //input w/o pullups sets line to high impedance so XSHUT pullup to 3.3V takes over
      pinMode(LR_XSHUT_PIN, INPUT);
      delay(10);

      if (!lidar_LR.init())
      {
        Serial.println("Failed to detect and initialize LR sensor!");
        retval = false;
      }
      else
      {
        Serial.printf("lidar_LR successfully initialized at %x\n", lidar_LR.getAddress());
        lidar_LR.setMeasurementTimingBudget(20000);
        lidar_LR.startContinuous();

        lidar_LR.setAddress(DEFAULT_VL53L0X_ADDR + 6);
        Serial.printf("lidar_LR. address is now 0x%x\n", lidar_LR.getAddress());
      }

      //now bring lidar_Rear only out of reset and set it's address
      //input w/o pullups sets line to high impedance so XSHUT pullup to 3.3V takes over
      pinMode(Rear_XSHUT_PIN, INPUT);
      delay(10);

      if (!lidar_Rear.init())
      {
        Serial.println("Failed to detect and initialize Rear sensor!");
        retval = false;
      }
      else
      {
        Serial.printf("lidar_Rear successfully initialized at %x\n", lidar_Rear.getAddress());
        lidar_Rear.setMeasurementTimingBudget(20000);
        lidar_Rear.startContinuous();

        lidar_Rear.setAddress(DEFAULT_VL53L0X_ADDR + 7);
        Serial.printf("lidar_Rear. address is now 0x%x\n", lidar_Rear.getAddress());
      }
      //input w/o pullups sets line to high impedance so XSHUT pullup to 3.3V takes over
      pinMode(LR_XSHUT_PIN, INPUT);
      delay(10);

      if (!lidar_LR.init())
      {
        Serial.println("Failed to detect and initialize LR sensor!");
        retval = false;
      }
      else
      {
        Serial.printf("lidar_LR successfully initialized at %x\n", lidar_LR.getAddress());
        lidar_LR.setMeasurementTimingBudget(20000);
        lidar_LR.startContinuous();

        lidar_LR.setAddress(DEFAULT_VL53L0X_ADDR + 2);
        Serial.printf("lidar_LR. address is now 0x%x\n", lidar_LR.getAddress());
      }

      return retval;
    }

Frank


body:
I new in Arduino environment.
Found some code generate sine wave but frequency between 14kHz to 84kHz. URL is [https://www.instructables.com/SineWave-Generator-for-Arduino-DUE/][1]

I need to generate sine waze 400kHz frequency.
Output should be on DAC0 or DAC1.

Any one can help to solve my problem.

  [1]: https://www.instructables.com/SineWave-Generator-for-Arduino-DUE/

title: Arduino Due generate 400KHz sine waze

Answers: 2

body:
I think you may be overestimating the capabilities of the Due DAC. My understanding and experimentation is that waveform generating code (e.g., https://forum.arduino.cc/t/funkgenie-a-wavetable-based-function-generator/214938) can generate consistent output waves up to “a few kHz”. After which the wave shapes suffer from distortion.

If wave shape is not critical (though you did mention you specifically needed a sine wave) you may be able to push further using PWM outputs (e.g., https://forum.arduino.cc/t/due-high-frequency-waveform-up-too-500khz/423392).

However, I think you may need to design a suitable electronic circuit to generate the wave you’re seeking. That may be a topic for the Electrical Engineering stack exchange though? There is an introduction to wave generation circuit options going up into the RF frequencies [here][1].

  [1]: https://www.circuitbasics.com/sine-wave-generators/

body:
The Due's DAC can go up to, and I quote direct from the datasheet:

> Up to 350ksps conversion rate

That means you can set *up to* 350,000 data points on your waveform per second. With two datapoints (giving you a square wave or, more realistically, a waveform with a sharks fin shape) the maximum you could get is (350,000/2) 175kHz.

Given that you stipulate you want a sine wave you're going to need many more than just 2 data points in your waveform. Assuming a (reasonable) minimum of 32 data points (more would give a smoother waveform) you'd be looking at a maximum frequency of about 10kHz. Sacrificing waveform fidelity you could increase that, but the higher you go the less and less it resembles a sine wave.


body:
How do I setup a Due to count rising edges on a pin automatically without having to waste time on an ISR?

I have some wheel encoders, the simplist implementation is direction less where you only count rising edges.

I went the Due to count rising edges automatically and an ISR on a timer will periodically pole the current count

title: Setup Due counter

Answers: 1

body:
You need to pick a timer that isn't being used for anything else and configure it as a simple counter with the clock source set to the external clock pin for that timer.

> At block level, input clock signals of each channel can either be connected to the external inputs TCLK0, TCLK1 or
TCLK2, or be connected to the internal I/O signals TIOA0, TIOA1 or TIOA2 for chaining by programming the TC
Block Mode Register (TC_BMR). See Figure 36-2.
Each channel can independently select an internal or external clock source for its counter:
> * External clock signals(1): XC0, XC1 or XC2
> * Internal clock signals: MCK/2, MCK/8, MCK/32, MCK/128, SLCK
> This selection is made by the TCCLKS bits in the TC Channel Mode Register (TC_CMR).

I am not personally familiar with the peripherals of the Due, but chapter 36 of the [SAM3X datasheet](https://ww1.microchip.com/downloads/en/devicedoc/atmel-11057-32-bit-cortex-m3-microcontroller-sam3x-sam3a_datasheet.pdf) details the workings and registers that you need to set.

Your encoder signal then connects to that clock input pin and the counter then counts every incoming pulse until you reset the count from your other periodic timer ISR.


body:
I am looking for a very low power, small component (perhaps an arduino) that will send a pulse 3.3V logic HIGH pulse once every X seconds to another system.  I want to be able to configure X (maybe a trim pot or something) based on the use case the most rapid use case would be about once per second and the slowest would be once per hour. The duration of the pulse doesn't really matter much as long as it's one second or less.

Adafruit sells an item (PRODUCT ID: 3573) based on a Texas Instruments TPL5110 chip that sort of does this but it's a timed constant HIGH signal, not a pulse.  I am an electronics noob and am not sure what category of component this falls under but I have tried googling and reading tutorials on timers.

title: Timer to send a periodic pulse

Answers: 1

body:
As Edgar Bonet commented, you can do this using an [ATtiny85 IC in an 8-pin DIP package](https://uk.rs-online.com/web/p/microcontrollers/1331672) which is available for about $1 and can be programmed using the Arduino IDE.

You have to tell the Arduino software about the ATtiny85 by installing a "core" for it such as [Spence Konde's](https://github.com/SpenceKonde/ATTinyCore/blob/master/Installation.md)

You will need a device to transfer the program into the ATtiny85, either a $5-$15 [AVR programmer](https://coolcomponents.co.uk/products/pololu-usb-avr-programmer-v2-1) or something like an Arduino Uno using the [Arduino-as-ISP](https://www.arduino.cc/en/Tutorial/BuiltInExamples/ArduinoISP) sketch .

Writing the software will be extremely easy by Arduino standards.

One advantage of the ATtiny85 over the same sized NE555 is that the ATtiny85 needs no external components (resistors capacitors etc) and so is a lot simpler to use. You can run this ATtiny85 on a 3.3 Volt supply (anything from 2.7 → 5.5 V will work).

If you want an ATtiny85 on a pre-assembled PCB (like that Adafruit TPL5110 product), try a [Digispark](https://proto-pic.co.uk/product/digispark-microcontroller-board-usb/) or a $1 [Digispark clone](https://www.aliexpress.com/item/32891293434.html), it can be plugged directly into a USB port for programming with the Arduino IDE. I haven't tried running one on 3.3V but I suspect that should be possible by connecting the 3.3V supply to the "5V" pin to bypass the Digispark's 5V regulator.

---

See https://wokwi.com/arduino/projects/310458692893934146

[![Wokwi project][1]][1]

I was also able to run it on a cheap Digispark clone from a 3V3 supply

[![Digispark][2]][2]

The only advantage over a bare ATtiny85 is that you don't need any programming hardware, just a USB port on a PC.

  [1]: https://i.stack.imgur.com/mWEUf.png
  [2]: https://i.stack.imgur.com/Vfxg9.jpg


body: I'm controlling a car instrument panel with Arduino using the tone() function, however with Arduino Uno's minimum 31Hz frequency I can only set the speedometer at ~12mph or more.  I'd like to be able to set the speed from 0, which would require around 10Hz I believe. Are there any code tricks I could use? Maybe I should use hardware timer, or a different board?

title: Arduino, generating smaller frequency than 31Hz

Answers: 1

body:
For this, I would consider using Timer 1 in mode 14 (fast PWM, with TOP
value controlled by ICR1), with the prescaler set to 64. The timer would
then be clocked at 250 kHz, giving you the following specs:

* timer frequency: 250 kHz (time resolution = 4 µs)
* minimum frequency: 3.81 Hz (exact period = 218 µs = 262,144 ms)
* maximum frequency: 125 kHz (period = 8 µs)

As the time resolution is constant, the frequency resolution worsens as
you increase the frequency. At 400 Hz the resolution is about 0.16%, or
0.64 Hz.

This is not the only possible solution. Toggle mode would work also, and
also other prescaler values, which would give different frequency ranges
and resolutions.

Check the datasheet to see how to set the configuration bits (basically:
non-inverting PWM on either OC1A or OC1B, waveform generation mode = 14,
prescaler = 64). You may be able to find libraries to do this if you
prefer that approach, I have not checked this possibility.


body:
I want to mount an [Arduino Pro Micro][1] inside my PC, hooked up to the PC's USB.

I don't want to have external cables for this, but have it neatly cabled inside.

My motherboard has USB connectors with 9 pins (5+5 grid, 10th pin key), like these:
[![motherboard][2]][2]

These connectors would take a cable that looks like this:

[![9pin cable][3]][3]

But how would I connect this to the Arduino that has Micro USB?

I've been looking everywhere, but 9-pin USB to USB Micro does not seem to exist?

The closest I could find is a cable that goes from USB micro to a 5-pin header:

[![5pin cable][4]][4]

What is the preferred way to hook up an Arduino Micro with internal cabling?

Why does the 9-pin to USB-micro not exist?

  [1]: https://wiki.keyestudio.com/Ks0249_keyestudio_PRO_MICRO_Development_Board
  [2]: https://i.stack.imgur.com/LGHlE.jpg
  [3]: https://i.stack.imgur.com/QehJo.png
  [4]: https://i.stack.imgur.com/qqPXH.png

title: Mounting an Arduino inside a PC

Answers: 1

body:
@Bram, @jsotola is highlighting in the comments that the example photo you show with a 9 pin keyed  two row connector has two usb cables connecting to it. USB connections often have four wires each. The standard wire color coding is:

[![usb wiring Colours][1]][1]
(Source [Wikipedia - USB][2])

Board manufacturers are often looking for a simple way to connect multiple panel mount USB ports to the PCB and this could have been a cheap and convenient way to connect two USB ports per pcb connector.

Some suggestions:

 - Research the specific motherboard online to see if a schematic or connector layout is available. It’s quite likely to be laid out like this:

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

 - Experiment by making your own [connector][4], and use a multimeter to figure out which are the power and which are the data wires.
 - If the old USB ports which used to connect to the PCB are still available, investigate further until you’re more confident about how they were wired.
 - An [adapter][4] may help you experiment further to understand the PCB connections further.

[![enter image description here][5]][5]

 - A [micro-USB breakout board][6] may help you experiment with connections on the Arduino side.
[![enter image description here][7]][7]

  [1]: https://i.stack.imgur.com/f1YTv.jpg
  [2]: https://en.wikipedia.org/wiki/USB?wprov=sfti1
  [3]: https://i.stack.imgur.com/QlwDj.jpg
  [4]: https://www.ebay.com.au/itm/Single-Double-Row-DuPont-2-54mm-Connector-Plug-Housing-Shell-1-10Pin-2-3-9Pin-/264226603708?mkcid=16&mkevt=1&_trksid=p2349624.m46890.l49286&mkrid=705-154756-20017-0
  [5]: https://i.stack.imgur.com/h41YI.jpg
  [6]: https://www.ebay.com.au/itm/USB-Type-B-Micro-B-Male-Plug-Receptacle-Breakout-Module-Board-for-/192267601843?mkcid=16&mkevt=1&_trksid=p2349624.m46890.l49286&mkrid=710-127635-2958-0
  [7]: https://i.stack.imgur.com/tHAEz.jpg


body:
Using the nrf24l01 wireless module I want to control a led with the sketch below.
The transmitter automatically sends data at intervals of one second continuously and when the receiver counter reaches 2, it turns on the LED at the desired time and then turns it off.
but what I want is when I turn off the power of the transmitter when 2 counts are detected from the transmitter, the led does not light up.

I want to turn the led on and off when I turn off the power of the transmitter after sending 2 signals from the transmitter.

Thank you for all the information you provide.

    #include "nRF24L01.h"
    #include "RF24.h"
    #include "SPI.h"
    int ReceivedMessage[1] = {000}; //  NRF24L01 tarafından alınan değeri saklamak için kullanılır
    RF24 radio(3, 4); //  NRF24L01 SPI pimleri. uno'daki Pin 8 ve 9
    const uint64_t pipe = 0xE6E6E6E6E6E6; // 2 NRF24L01 arasındaki iletişim için aynı olması gerekir

    int led = A7;

    bool flag = false;
    bool ledflag  = false;
    unsigned long  previous1 = 0;
    unsigned long  interval1 = 5000;

    unsigned long  previous2 = 0;
    unsigned long  interval2  = 2000;
    int button1PushCounter = 0;

    void setup () {

      radio.begin(); // NRF24L01'i başlatın

      radio.openReadingPipe(1, pipe); // NRF24L01'i almaya hazır hale getirin

      radio.startListening(); // Bilginin alınıp alınmadığını görmek için dinleyin

      Serial.begin(9600);

      pinMode(led, OUTPUT);

    }

    void loop () {

      unsigned long currentmillis = millis();
      while (radio.available())
      {
        radio.read(ReceivedMessage, 1); // NRF24L01'den bilgileri okuyun

        if (ReceivedMessage [0] == 111) //  switch'e basıldığını gösterir
        {

          button1PushCounter++;
          Serial.println( button1PushCounter);
          delay(700);
        }

        if ( button1PushCounter == 2) {

          flag = true;
          previous1 =  currentmillis;

        }

        if ( flag ) {
          if (currentmillis - previous1 >= interval1  ) {

            digitalWrite(led, HIGH);
            ledflag  = true;
            previous2 =  currentmillis;
            flag = false;
            button1PushCounter = 0;
          }
        }

        if ( ledflag && (currentmillis - previous2 >= interval2  )) {
          digitalWrite(led,  LOW);
          ledflag  = false;

        }
      }
    }

title: how to detect when a transmitter is turned off?

Answers: 1

body:
I found solution as below:-

    if ( button1PushCounter == 3 ) {

      for (int i = 0; i < 5; i++)
      {
        delay(1000);
        Serial.println(i);
        a = HIGH;
      }
    }

    if ( a == HIGH ) {

      digitalWrite(led, HIGH);
      delay(1000);
      digitalWrite(led,  LOW);
      a = LOW;
      button1PushCounter = 0;
    }


body:
I am facing a problem in reading data from thingspeak server
after each AT command, I get the right response from the gsm
However, after
```
AT+HTTPPARA = "URL","thingspeak.com/channels/channelNumber/fields/1/last.txt"
AT+HTTPACTION=0
AT+HTTPREAD
```
I always get the response as HTML code so not as content
I really need your help and will appreciate any suggestions.
Thanks in advance.

title: reading data from server arduino and gsm900a

Answers: 0


body:
I am trying to use a Adafruit Sim800H to connect to Azure using MQTT with an SSL certificate. My first step is trying to put a new SSL certificate onto the board. To do this I am using this example here: https://github.com/vshymanskyy/TinyGSM/ ... etCert.ino . This seems to follow the typical suggested steps on how to set the SSL - by using AT command to create and write to a file, which is then set as the certificate.

The code I am running is the same as what is in the Github repo - except I have added extra print commands, getting a better idea of where it has broken. Here is an excerpt:

```
  SerialMon.println(F("Select..."));
  modem.sendAT(GF("+SSLSETCERT=\"" CERT_FILE "\""));
  SerialMon.println(F("cert file on.."));
  if (modem.waitResponse() != 1) return;
  if (modem.waitResponse(5000L, GF(GSM_NL "+SSLSETCERT:")) != 1) return;
  SerialMon.println(F("begin retCode"));
  const int retCode = modem.stream.readStringUntil('\n').toInt();
```

When I monitor my Arduino, I see "Select" and "cert file on.." printed out. However, then it hangs for a long time, and I get an error saying the command is not available.

Can anyone help me follow up on what may be the cause of this?

I have explored trying to update the firmware. I have downloaded a newer firmware (B11), and have the software needed to shift it to the board. However, it doesnt seem to recognise the board is connected over USB. In this situation, the cable is connected to the SIM800H board USB - is this correct?

Thanks.

title: How to correctly use SSL certs with the Adafruit SIM800H

Answers: 0


body:
I am trying to send AT commands to the modem to keep the modem always active. I tried the File > Examples > MKRNB > Tools > SerialSarapassThrough example, but that gave me a +CME ERROR: operation not supported. Here is the output for the commands I sent via serial monitor:
````
AT
OK
AT+UPSV=0
+CME ERROR: operation not supported
````
Is there a built in code or any other code which I could use to send that command?

title: How to send AT commands to the ubox modem on MKR NB 1500

Answers: 1

body:
You have to try SerialSARAPassthrough.ino from examples menu under MKRNB.
If it works properly, you can start writing AT in serial monitor line. You must see answer as OK. Then you can look at the u-blox commands document that is shared above


body:
I have a hm-10 module attached to Arduino Leonardo board, I'm using a bluetooth terminal app to send some text.

The problem is I can send data from the Serial monitor to my phone but when I send from my phone, there is no output in the serial monitor.

It works fine if I test it on Arduino Uno.
I'm struggling with something that should be simple.

Can someone please help me?

Here is my code:-

    #include <SoftwareSerial.h>

    SoftwareSerial BTSerial(4, 5);

    void setup(){
      Serial.begin(115200);
      Serial.println("Hello!");
      BTSerial.begin(115200);
    }

    void loop(){
      while (BTSerial.available()){
        byte data = BTSerial.read();
        Serial.write(data);
      }

      while (Serial.available()){
        byte data = Serial.read();
        BTSerial.write(data);
      }
    }

title: Leonardo with hm-10 doesn't work

Answers: 1

body:
I GOT IT!! It was problem with the pin settings.

According to SoftwareSerial library documentation, only pins 8,9,10,11,14,15,16 can be used for RX pin. But i used pin 4 for RX.


body:
I am using SDA1, SCL1 for my DS3232 with RTClib on Due. It works on a Mega2560 on SDA, SCL.
I ran I2c_test with success after I inserted
#define Wire Wire1
However with ds3231.ino this define doesnot work. Looking at RTClib.cpp it looks like I can pass a parameter to Wire.begin(). I have tried sda1, scl1 and Wire1. They didnot work.
Thanks for the help.

title: Second I2C on Due RTClib, can't start

Answers: 1

body:
The unmodified [RTCLib][1] DS3231 sample code running on Arduino Due defaults to the *Wire* I2C connection on pins 20 SDA and 21 SCL.
[![Due connection via Wire I2C pins][2]][2]
To enable the same sketch to connect to a device connected to the *Wire1* I2C connection on pins 70 SDA1 and 71 SCL1, I changed line 333 of RTClib.h to reference &Wire1 rather than &Wire.
[![Photo of code snippet in RTCLib.h][3]][3]
[![Due connection via Wire1 I2C pins][4]][4]
Successful test output from the Wire1 connection is shown.
[![Serial Monitor Output][5]][5]

**Update:**
OP @Marlin Turbett pointed out that adding `#define Wire Wire1` to RTClib.h also works. I agree. The modification of line 333 of RTClib.h which I suggested originally is I think the minimal change to get the desired behaviour. But using substitution to achieve the same change also works. A global change across the whole library may be a bigger hammer than might be desirable.

#define substitution works in single compilation units, so the #define needs to be in the same compilation unit as the text to be overwritten. In this case in the library, not the sketch.

The technique of using #define directives to overwrite which *Wire* port is referenced in RTClib is used selectively by the library depending on arduino architecture (see RTClib.cpp lines 46-73, below).

    #include "RTClib.h"
    #if defined(__AVR__) && !defined(TWCR) && defined(USICR)
    #include <TinyWireM.h>
    #define Wire TinyWireM
    #else
    #include <Wire.h>
    #endif

    #ifdef __AVR__
    #include <avr/pgmspace.h>
    #elif defined(ESP8266)
    #include <pgmspace.h>
    #elif defined(ARDUINO_ARCH_SAMD)
    // nothing special needed
    #elif defined(ARDUINO_SAM_DUE)
    #define PROGMEM
    #define pgm_read_byte(addr) (*(const unsigned char *)(addr))
    #define Wire Wire1
    #endif

    #if (ARDUINO >= 100)
    #define _I2C_WRITE write ///< Modern I2C write
    #define _I2C_READ read   ///< Modern I2C read
    #else
    #include <WProgram.h>
    #define _I2C_WRITE send   ///< Legacy I2C write
    #define _I2C_READ receive ///< legacy I2C read
    #endif

I don't know why the library code at lines 60 to 64 (for ARDUINO_SAM_DUE) was not effective, and I hope to do some more testing. Maybe others here can shed some light?

**Update 2:** Noting the link from @Edgar Bonet in the comments to the new example sketch `customWire_DS3231onSAMD21.ino` in RTClib 1.14.1 which specifically caters for multiple i2c ports. Nice one.

  [1]: https://github.com/adafruit/RTClib
  [2]: https://i.stack.imgur.com/dgjO5.jpg
  [3]: https://i.stack.imgur.com/cwngk.png
  [4]: https://i.stack.imgur.com/yoXqX.jpg
  [5]: https://i.stack.imgur.com/5Zphg.png


body:
I am trying to link the Bluetooth module to my arduino UNO in order to wirelessly program a robot. The only issue that I am having is that the bluetooth module does not seem to pick up the arduino.

Here is how the bluetooth module is wired up to my arduino:
[![enter image description here][1]][1]

The bluetooth module is paired to my PC via a bluetooth dongle. I know that the bluetooth module is working on port COM7. The LED then on the bluetooth module blinks quickly. After this I set the port to the correct port that the bluetooth module uses:

[![enter image description here][2]][2]

One thing that I found strange was that the name of the arduino board does not come up just like when I use a USB to upload the program.

When I open up the serial monitor the LED on the bluetooth module begins to blink more slowly possibly indicating it is connected. I afterwards try to send an AT command via the serial monitor to the arduino by typing in AT to the serial input at the top of the serial monitor and hitting enter and nothing happens. I then tried to send 3 different pieces of code separately to the arduino one at a time:

First code sample:

    void setup() {

     Serial.begin(9600);

    while (!Serial) {
       ; // wait for serial port to connect. Needed for native USB port only
     }

     Serial.println("ASCII Table ~ Character Map");
    }

    int thisByte = 33;

    void loop() {

     Serial.write(thisByte);

     Serial.print(", dec: ");
     Serial.print(thisByte);

     Serial.print(", hex: ");
     Serial.print(thisByte, HEX);

     Serial.print(", oct: ");
     Serial.print(thisByte, OCT);

     Serial.print(", bin: ");
     Serial.println(thisByte, BIN);

     if (thisByte == 126) {
       while (true) {
         continue;
       }
     }
     thisByte++;

    }

Second code sample:

    #include <SoftwareSerial.h>
    SoftwareSerial BTSerial (2,3);
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      Serial.println("Enter AT Commands");
      BTSerial.begin(9600);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      if(BTSerial.available()){
        Serial.write(BTSerial.read());
      }
      if(Serial.available()){
        BTSerial.write(Serial.read());
      }
    }

Third code sample:

    char inputByte;
    void setup() {
     Serial.begin(9600);
     pinMode(13,OUTPUT);

    }

    void loop() {
    while(Serial.available()>0){
      inputByte= Serial.read();
      Serial.println(inputByte);
      if (inputByte=='Z'){
      digitalWrite(13,HIGH);
      }
      else if (inputByte=='z'){
      digitalWrite(13,LOW);
      }
      }
    }

(The following situation occurs for all 3 samples of code I copied from online). When I set the port to COM7 and then click upload to the board, the IDE says "Uploading" and the LED begins to blink more slowly just like as I was mentioning before with the serial monitor. After a while eventually the following error messages came up:

    avrdude: stk500v2_ReceiveMessage(): timeout
    avrdude: stk500v2_getsync(): timeout communicating with programmer

I looked online for answers. The internet suggested to use a larger baud rate so I switched it from 9600 to 57600 and also at the same time switch from Newline to Both NL and CR. Still nothing happened and I got the following error message. One final suggestion I saw on the internet was to put a resistor divider/voltage divider across the RX pin (I haven't done this as I don't see how this could make a difference, I could be wrong about it though and it could make the whole difference).

  [1]: https://i.stack.imgur.com/VOiJl.png
  [2]: https://i.stack.imgur.com/p2Fro.png

title: avrdude: stk500v2_ReceiveMessage(): timeout error for bluetooth arduino

Answers: 1

body:
The Bluetooth range is small so the robot can't be far from the computer for upload.

----------

To solve the reset for the Bluetooth you could add a reset button on the robot and use it while avrdude attempts to upload the sketch. Baud rate on HC-05 must be set to 115200 baud.

----------

As an alternative you could have USB connector on the robot. You can use a short USB extension cable as internal cable from the USB connector of the Arduino to the outer shell of the robot.


body:
My initial question assumes it is possible to emulate the original GameBoy system using an Arduino board.

Additional information in non-technical terms: I am looking to create an Arduino based device that accepts cartridges as input devices (in some cases they will also function as output devices) I am interested primarily in the Hexadecimal/pixel based "logic" which gameboy games uses to display game data.

What is the simplest way to emulate the original gameboy's hexadecimal based pixel logic to fetch, decode, and execute data using Arduino?

Before flagging this question, please comment so that I may clarify as this is a complex question to ask and I am willing to re word it as necessary.

title: What is the simplest way to emulate the original gameboy's cpu using Arduino?

Answers: 1

body:
(Assembling an answer from the comments)

The consensus is that there is no "simple way to emulate the original gameboy cpu using Arduino". That a more powerful platform is required.

Multiple commenters expressed difficulty with the novel concept of "hexadecimal/pixel based logic". It is suggested that this concept may be without merit.


body:
    String abc ="0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff";

    const unsigned char displaydata={reinterpret_cast<const unsigned char*>(abc.c_str())};

    display.drawBitmap(displaydata, startX, startY, bmpWidth, bmpHeight, GxEPD_WHITE);

**Get error: invalid conversion from 'const unsigned char' to 'unsigned char' [-fpermissive]***

**When I write like this**

    String abc ="0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff";

    display.drawBitmap(reinterpret_cast<const unsigned char*>(abc.c_str()), startX, startY, bmpWidth, bmpHeight, GxEPD_WHITE);

**No error but black screen no display image**

**When I write like this**

    const unsigned char displaydata[]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};

    display.drawBitmap(displaydata, startX, startY, bmpWidth, bmpHeight, GxEPD_WHITE);

**It is working**

The string data coming from the server is returning to me as stirng, I am trying to reflect it on the screen. I want to convert a string data to const unsigned char with code

So I'm trying to convert

title: Convert String to const unsigned char

Answers: 1

body:
That string is literally the characters 0xff ... while the array is the bytes 0xff...

Where the string contains 4 bytes to say 0,x,f,f (followed by comma and space) the array will have 1 byte the 255 (and no need for a comma or space to delimit).

If you are looking to convert the text hex string to bytes, look at a combination of https://arduino.stackexchange.com/questions/39861/how-to-convert-an-hex-string-to-an-array-of-bytes and looping through the string.


body:
I want to convert hour to seconds but unsigned long is overflowing, here's the code:

    #include <Wire.h>
    #include <DS3231.h>

    RTClib myRTC;
    unsigned long seconds;
    char timestr[9];

    void setup() {
      Serial.begin(250000);
      Wire.begin();
    }

    void loop() {
      DateTime now = myRTC.now();

      snprintf(timestr, 9, "d:d:d", now.hour(), now.minute(), now.second());
      seconds = (now.hour() * 3600);
      Serial.println(timestr);
      Serial.println(seconds);
      delay(100);
    }

And the console output is:

    16:33:36
    4294959360

Why is this happening?

title: Why the unsigned long is overflowing?

Answers: 1

body:
It's not the unsigned long that's overflowing but the calculation that you're assigning to it.

3600 is a signed integer (by default), and `now.hour()` is an unsigned byte. The unsigned byte gets promoted to match the "largest" type in the calculation - a signed integer - and then the calculation is performed, resulting in a signed integer.

That signed integer is then assigned to an unsigned long and, if the result is negative (as it may well be - 10*3600 > 32767) you end up with a massive number.

The simple "cure" is to ensure that one value in the calculation is an unsigned long. And the best way of doing that is to make your constant an unsigned long: by appending "UL" to it:

    seconds = (now.hour() * 3600UL);


body:
I've often encountered WiFi networks that require you to sign in through a web page that automatically opens after connecting to the access point, such as hotels. I'd like to implement something similar with an ESP32, where a web page opens automatically after connecting to the AP. Is this doable? This seems to be difficult to Google, because I just get a bunch of introductory tutorials on setting up an AP.

Here's some project context in case it helps. I'm making an IoT device that needs to connect to the user's WiFi network, so the user needs to specify the login credentials. The solution I'm trying to implement is having the ESP32 set up a temporary AP, where the user can connect to that and enter their home WiFi credentials. As it stands now, the user has to manually type in the IP address of the ESP32 after connecting to the AP, but it'd be much more user friendly if the web page opened automatically like hotel WiFi networks sometimes do.

I've tinkered with this [WiFi Manager][1] library that appears to do what I want, but I'd like to implement mine from scratch.

  [1]: https://github.com/zhouhan0126/WIFIMANAGER-ESP32

title: ESP32 AP Automatic Web Page

Answers: 1

body:
Of course, as soon as I linked that WiFi Manager library in my question, I figured it out. The term I was missing was "captive portal" and I was able to figure it out from there. But I decided to post the question anyways, since it might help someone else stuck in the same situation.

Here's my understanding of how it works: when your device connects to a new network, it tries to ping a server to see whether it has internet access. With the ESP32, you can set up a DNS that redirects that ping to a web server running on the ESP32, which opens up the browser on the device.

I found this tutorial helpful for me to understand how that works, along with example code. This should be enough for me to get it working.

https://iotespresso.com/create-captive-portal-using-esp32/


body:
So I made a post yesterday running into an issue on my ESP32 using both cores on the microcontroller (with wifi enabled, incase that is important).

I'm using both cores to control two Neopixel strips individually. I'm making a music visualizer, and I want the neopixels to react to the change in music as quickly as possible, so I felt like having one for every individual core was the best way for that to happen. The issue I am running into is that when audio is playing, the Music Visualizer function either in the primary core (Core 1), or secondary core (Core 0) will just completely freeze. I tried troubleshooting with some Serial.Print statements to understand where the code breaks, and it seems to happen around the **setPixelColor** command. I think my code is being thread locked, and I wanted to know what I could do to make it thread safe.

    void musicVisualizer(void) {
      middle_strip.clear();
      upper_strip.clear();

      middle_strip.show();
      upper_strip.show();

      // Add code to tell Core 0 to wait until LED's are cleared.
      while (vu_meter) {
        tweeter_prev = tweeter;
        if (analogRead(tweeter_sample) <= 490)
          tweeter_adc = 0;
        else {
          tweeter_adc = (analogRead(tweeter_sample) - 490);
          if (tweeter_adc < 0)
            tweeter_adc = 0; // Filter for changing reference voltage
          else if (tweeter_adc > MIDDLE_LED_COUNT)
            tweeter_adc = tweeter_prev; // Filter for if there are intermittent spikes in the adc
        }
        tweeter_filter.Filter(tweeter_adc);
        tweeter = tweeter_filter.Current() * 6;  // 6 scaler is for when Alexa is at Volume Level 4

        //    /* Changing LED Number to improve efficency when turning on LED's */
        //    if (tweeter > 43)
        //      LED_COUNT = 65;
        //    else if (tweeter > 21)
        //      LED_COUNT = 43;
        //    else if (tweeter <= 21)
        //      LED_COUNT = 21;

        /* LED's turning on and off in response to audio */
        if ((tweeter > tweeter_prev) && (tweeter <= MIDDLE_LED_COUNT)) {
          for (int x = tweeter_prev; x < tweeter; x++) {
            //        middle_strip.setPixelColor(x, color);
            middle_strip.setPixelColor(x, 0, 0, middle_strip.gamma32(brightness));
            middle_strip.show();
          }
        }
        else if (tweeter_prev > tweeter) {
          for (int x = tweeter_prev; x >= tweeter; x--) {
            middle_strip.setPixelColor(x, 0, 0, 0);
            middle_strip.show();
          }
        }
      }

      /* Leaving VU Meter, returning to current lamp color set */
      if (led_on) {
        if (!color_white) {
          for (int i = 0; i < LOWER_LED_COUNT; i++) {
            lower_strip.setPixelColor(i, color);
            lower_strip.show();
          }
          for (int i = 0; i < MIDDLE_LED_COUNT; i++) {
            middle_strip.setPixelColor(i, color);
            middle_strip.show();
          }
          for (int i = 0; i < UPPER_LED_COUNT; i++) {
            upper_strip.setPixelColor(i, color);
            upper_strip.show();
          }
        }
        else {
          for (int i = 0; i < LOWER_LED_COUNT; i++) {
            lower_strip.setPixelColor(i, 0, 0, 0, lower_strip.gamma32(brightness));
            lower_strip.show();
          }
          for (int i = 0; i < MIDDLE_LED_COUNT; i++) {
            middle_strip.setPixelColor(i, 0, 0, 0, middle_strip.gamma32(brightness));
            middle_strip.show();
          }
          for (int i = 0; i < UPPER_LED_COUNT; i++) {
            upper_strip.setPixelColor(i, 0, 0, 0, upper_strip.gamma32(brightness));
            upper_strip.show();
          }
        }
      }
      else {
        upper_strip.clear();
        middle_strip.clear();
        lower_strip.clear();

        upper_strip.show();
        middle_strip.show();
        lower_strip.show();
      }
    }

    void vu_meter_sub(void * parameter) {
      while (true) {
        esp_task_wdt_init(30, false);
        if (vu_meter) {
          lower_strip.clear();
          lower_strip.show();
          while (vu_meter) {
            sub_prev = sub;
            sub_adc = analogRead(sub_sample);
            if (sub_adc > LOWER_LED_COUNT)
              sub_adc = LOWER_LED_COUNT-1;
            sub_filter.Filter(sub_adc);
            sub = sub_filter.Current();
            //        if (sub < 0)
            //          sub = 0;
            Serial.println(sub);
            if ((sub > sub_prev) && (sub <= LOWER_LED_COUNT)) {
              for (int x = sub_prev; x < sub; x++) {
                //            lower_strip.setPixelColor(x, color);
                lower_strip.setPixelColor(x, 0, lower_strip.gamma32(brightness), 0);
                lower_strip.show();
              }
            }
            else if (sub_prev > sub) {
              for (int x = sub_prev; x >= sub; x--) {
                lower_strip.setPixelColor(x, 0, 0, 0);
                lower_strip.show();
              }
            }
            Blynk.run();
          }
        }
      }
    }

title: How can I make my code Thread-Safe?

Answers: 1

body:
I am not sure this is related to thread-safety, but you should be aware
that `strip.show()` is a slow function that blocks while the data is
being sent. `setPixelColor()`, in contrast, is fast, as it only updates
the data in memory.

I suggest you modify `musicVisualizer()` in such a way that it only
`show()`s each strip once. The bulk of the function should be about
computing the colors you want and setting them with `setPixelColor()`.
Then, at the very end of the function, `show()` the three strips.


body:
I bought this ov2640 camera module with 18 pins and I don't have shield to insert it to. I am looking for a library or working code on this my camera sensor but all I kept getting was arducam examples or at most ov7670 example code. Can anybody help me out here?
The image of the module is at this link https://i.stack.imgur.com/tUVg0.jpg

PS: I am using an arduino due

(Edit: Added image of camera module)
[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/GTa9E.jpg

title: ov2640 with 18 pin and no arducam shield

Answers: 1

body:
There is a datasheet for the module at https://www.mpja.com/download/35647mpdata.pdf

It references the Arducam library at https://github.com/ArduCAM/Arduino/tree/master/ArduCAM.

The library specifically supports this camera type. By studying the camera specific code you may get a better idea of what is required. To connect the module directly to a Due, the work that was designed to be done by the intended shield would need to be replicated. Which seems non-trivial.


body:
My project is to use an Arduino to control two solenoid valves with PWM and receive an input signal from a sensor as feedback.

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

The valves direct the flow of water which cause a hydraulic actuator to move which is detected by an LVDT sensor.

What I want my program to do is to allow me to set a desired displacement as a goal which causes the Arduino to dynamically change the duty cycle of the pwm signal based off of the feedback input the Arduino receives. I am going to implement a PID to control it.

The circuit consist of the Arduino sending PWM signals to two logic level NPN mosfets to control the solenoids that are powered by 2 external 12V sources.

[![enter image description here][2]][2]

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

What I specifically need help with is how to write the part of the program that will let me produce 2 PWM signals that will allow me to change the frequency of the pwm waves so that the solenoids have enough time to switch and then also the ability to set the duty cycle.

I am a total novice programmer and its my first time working with electronics. I'm just hoping someone can point me in the right direction.

  [1]: https://i.stack.imgur.com/LH76m.jpg
  [2]: https://i.stack.imgur.com/CT8QG.jpg
  [3]: https://i.stack.imgur.com/n6X9D.jpg

title: I need help producing 2 pwm signals

Answers: 3

body:
You can try to use my [**AVR_Slow_PWM** Library](https://github.com/khoih-prog/AVR_Slow_PWM), which can provide these following features and generate 2 independent PWM signals to any GPIO pin. Certainly only if your hardware design can correctly use PWM signals.

>This library enables you to use ISR-based PWM channels on AVR-based boards, such as Mega-2560, UNO,Nano, Leonardo, etc., using AVR core to create and output PWM any GPIO pin. Because this library doesn't use the powerful purely hardware-controlled PWM with many limitations, the maximum PWM frequency is currently limited at 500Hz, which is still suitable for many real-life applications

body:
If you only need two PWM pins, I suggest using hardware PWM with
Timer 1. The [Timer 1][t1] library makes the process quite easy. It
supports frequencies from 0.12 Hz up to a few MHz, although the
resolution degrades above 7.8 kHz.

Compared to an interrupt-based solution, hardware PWM has less jitter
and it does not consume CPU cycles. The drawback is that you will be
limited to 2 channels operating at the same frequency, but this
doesn't seem to be an issue for your project.

[t1]: https://github.com/PaulStoffregen/TimerOne

body:
Tacking on this as a belated observation more than anything else.

Since there is no indication of an accumulator on the hydraulic circuit and the two valves are working in opposition, it might be necessary to maintain both complementary PWM ratios and consistent relative phase.

The TimerOne library appears- by eye- to maintain a consistent relative phase. The AVR_Slow_PWM library definitely doesn't.

If it is /not/ necessary to apply an offset to the PWM edges to accommodate the valves having different open and close times then it might be easiest to simply change the switching sense of one of the FETs with both driven from the same PWM signal (i.e. when one sees 75% on, the other sees 75% off).

If it /is/ necessary to apply an offset then it might end up being best to manually code something in a timer interrupt handler, particularly since I am told that typical valves should operate at about 10Hz but not much faster: this eliminates most of the standard PWM libraries.


body:
I wish to measure 14S battery voltage on each cell with single ADC.
I guess I need some ADC built-in or external (I2C), voltage divider and switch chip that will allow me to select one of 14 pins to measure.

Am I correct?

Could you advice what switch chip should I use?

or Should I build that curtuit myself with 2 74HC595 and mosfets? (not sure if that will ever work)

title: Measure voltage in 14 points 0 - 60 volts (14s LiPo battery) with single ADC

Answers: 1

body:
I would do it manually (but then I am a bit sadistic like that).

The circuit for one cell is pretty simple, and you just need to replicate it 14 times. A P+N pair of MOSFETs to switch a battery channel on and off, and a pair of resistors to make a voltage divider. You can keep the "lower" of the resistors common between all channels if you like to reduce the number of components and complexity, but once you have 14 channels the complexity will become pretty silly anyway.  Here's an example with just 3 channels:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/49hCQ.png)

<!-- End schematic -->

You would need to size RA|RL, RB|RL and RC|RL (etc) accordingly to get the right voltage ranges for the ADC input, and keep the output impedance low enough (<10k) for the ADC to handle it properly. You may want a couple of different load resistors (RL) for different groups of cells.

All the N-channel MOSFETs could be replaced by a 4-to-16 decoder with open-collector outputs (such as, if you can get it, the 74xx159), which would also protect against switching on multiple channels at once, which you *never* want to do.

Note that this arrangement gives you the voltage of the first cell, the voltage of the first two cells, the voltage of the first three cells, etc. To get the voltage of just the third cell (for example) you will need to subtract the voltage of the lower cells.


body: I want to power ESP32 with 230V AC and I don’t know how to do it. The requirement is that it must never overheat. What components should i use? The ESP will be in small space with no airflow. Will it be even possible?

title: How to power ESP32 with 230V AC

Answers: 1

body:
The folks over at [Random Nerd Tutorials][1] offer a solution for this exact scenario using a [HLK-PM03][2] Hi-Link 100-240V AC to 3.3V 1A DC converter. They add electrical and thermal fuses to mitigate some of the possible failure modes of over-temperature or over-current.

The specifications of the HLK-PM03 are [here][3]. I suspect there will be a few alternatives available that do a similar function.

My suggestion is to be hyper-aware of the safety issues of dealing with mains power, and to be realistic about your own capabilities.

  [1]: https://randomnerdtutorials.com/esp8266-hi-link-hlk-pm03/
  [2]: https://makeradvisor.com/tools/hi-link-hlk-pm03/
  [3]: http://www.hlktech.net/product_detail.php?ProId=59


body:
I am working on a project with Arduino MKR 1400 GSM and I would like to power the arduino board using an external power source (https://www.reichelt.de/raspberry-pi-netzteil-5-1-v-3-0-a-usb-type-c-eu-stecker-s-rpi-ps-15w-bk-eu-p260010.html?PROVID=2788&gclid=CjwKCAjwy7CKBhBMEiwA0Eb7ah0tvjJTgi1IruE69oZEm51ONn9dgkCZK45JE1EU5hNgoXfJ1CA8NBoCJLgQAvD_BwE) via the VIN pin without an additional 3.7V battery.

I have copied the code that I am using and the board resets and restarts every time the board tries to initiate GSM connection (gsmAccess.begin(PINNUMBER) == GSM_READY). According to the documentation, this operation needs more current and the board restarts when it does not get enough current for this operation and 5V 3A power supply should be enough to power the board for cellular transmission without the need for an additional battery. However, I am not able to start GSM connection with this power source. I have cut the micro USB end and connect GND from the power source to GND on the arduino board and VCC from the power source to 5V/VIN on the arduino board. As mentioned, the board is not able to initiate the GSM connection with this set up.

I have gone through all the suggestions on the forum and I have not been able to resolve this. Could you please let me know the best way to power the arduino MKR 1400 GSM via VIN such that GSM connection is initiated.

The board works with the additional 3.7V battery (https://www.amazon.de/VinCorp-2500mAh-Stecker-Empfänger-Quadrocopter/dp/B0863PZPSM/ref=asc_df_B0863PZPSM/?tag=googshopde-21&linkCode=df0&hvadid=447410901006&hvpos=&hvnetw=g&hvrand=1221952135560228729&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9044320&hvtargid=pla-925522392231&psc=1&th=1&psc=1)

Please let me know if you need more information from my side.

Please ignore the values given for the variables server and path

```
#include <MKRGSM.h>
#include <ArduinoHttpClient.h>
#include <ArduinoJson.h>
// PIN Number

const char PINNUMBER[]     = "";

const char GPRS_APN[]      = "";
const char GPRS_LOGIN[]    = "";
const char GPRS_PASSWORD[] = "";

GSMClient client;
GPRS gprs;
GSM gsmAccess;
String currentBarcode;

char server[] = "test.net";
char path[] = "/test";
int port = 80;

StaticJsonDocument<200> jsonBuffer;
HttpClient httpClient = HttpClient(client, server, port);
JsonObject root = jsonBuffer.to<JsonObject>();
int count = 0;

void setup() {
  Serial.begin(9600);
  boolean connected = false;
  while (!connected) {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
      connected = true;
    } else {
      delay(1000);
    }
  }
}

void loop() {
  root["boxid"] = "Test";
  root["gtin"] = "Test";
  if (client.connect(server, port)) {
    postToWia(root);
    delay(1000);
  } else {
  }

  if (!client.available() && !client.connected()) {
    client.stop();
    for (;;)
      ;
  }
}

void postToWia(JsonObject& data) {
  String dataStr = "";
  serializeJson(data, dataStr);
  httpClient.beginRequest();
  httpClient.post(path);
  httpClient.sendHeader("Content-Type", "application/json");
  httpClient.sendHeader("Content-Length", dataStr.length());
  //httpClient.sendHeader("Authorization", "Bearer " + String(device_secret_key));
  httpClient.beginBody();
  httpClient.print(dataStr);
  httpClient.endRequest();

}
```

title: Power Arduino MKR GSM 1400 via VIN

Answers: 0


body:
I have a Arduino code working on a Adafruit Feather STM32F405 Express, and as long as I test it with Arduino serial Monitor, everything works perfect. As I want to use a serial terminal (a C# application, or the "Terminal Br@y++") through the same COM port, then I can write my commands, there are executed (output pins send expected signal), but I don't received the serial feedback.

My Arduino code :

    void setup() {
      Serial.begin(115200); // initialise USB Serial Port
      pinMode(pumpP, OUTPUT);  // Pump Pin is an output
    }
    void loop() {
        if (Serial.available() > 0) {
          command = Serial.readStringUntil('\n');
        }
        if (command == "do-it"){
            digitalWrite(5, HIGH);
            Serial.println("did it!");
        }
    }

In my Arduino Serial Monitor, I write "do-it", and I recieved "did it!" and I can see the Pin 5 changing level.
In all serial application I could use, I can see the pin 5 changing level, but not the "did it!".

I configured Arduino as described on this Adafruit page :
https://learn.adafruit.com/adafruit-stm32f405-feather-express/arduino-ide-setup [ *summary: use STM32F4 library, board number = "Adafruit Feather STM32F405", USB support = "CDC ( Generic Serial supercedes USART)", upload method = "STM32CubeProgrammer (DFU)"* ]
And I connect the DFU pin to 3,3V during upload, and reset the board after it.

The worst in this story, is that at first time, it worked OK. Since a week or two, I don't get it to work again.

title: Serial Monitor in Arduino works, but other Serial Terminal work only one way

Answers: 1

body:
Thank you @Majenko, you gave the solution :
I checked the box "RTS/CTS" in the "handschake" section of Terminal by Bray, and I got all my serial message back from the STM32.

I guess this is a common think on more that stm32?
how did you know, is that somewhere written in Arduino documentation?

for people like me who do not know what is RTS/CTS, here you are: http://www.brainboxes.com/faq/items/what-is-rts--cts-hardware-flow-control-
or not so straight-forward https://en.wikipedia.org/wiki/RS-232#RTS,_CTS,_and_RTR

Funny to figure out that this "5 pin communication" is virtualise in USB.

@Majenko: if you want to "own" the solution, I let you do write it yourself, I will set your answer as solution.


body:
I am going to connect NodeMCU to a latching relay board like tis one (4 channel version): [LINK][1]

Both MCU board and relay board will be powered from the same 5V voltage regulator.

Now I have two problems to solve:

**Problem 1** - logic levels

NodeMCU logic level is 3.3V and relays board works in 5V levels.
I can either use logic level converters or simple transoptors. Because I am going to attach NodeMCU to a custom PCB, I think transoptors will be simpler to solder.

**Problem 2** - relay triggers with low pulse on the control pin

This relay boards works like this: every time the channel pin (T1 - T4) is connected to ground for few miliseconds - the relay flips to other state.
Here is the question: **when the MCU board resets/reboots on power cycle, how do I ensure that the control pins are HIGH from the beginning?** If they are not, the relay can flip randomly before my program starts and I will not know the initial state of relay.

What would be the best approch here ?

  [1]: https://www.wish.com/product/1pc-5v-12v-flip-flop-latch-relay-module-bistable-self-lock-io25c04-5ddc9180e799ac03db9d54d3?hide_login_modal=true&share=web

title: NodeMCU with a 5V latching relay - LOW triggers relay

Answers: 1

body:
Since ports commonly are configured as inputs at reset, you will need to add a pull-up resistor.

Then write your setup so that the pin is high before switching to output mode.

**EDIT:**

Some microcontrollers have internal pull-ups, that are even activated at reset, see the specific data sheet. (_Thanks, Juraj._ I don't know NodeMCU enough to go in details. Anyway, my answer might apply to other controllers and other loads, too.)

The value of the pull-up can be determined by the maximum input current for the relay module (or your adapting circuitry) and the respective voltages. To be sure, make it a bit smaller, for example to the next E-series value. Just an example: minimum supply voltage is 3.15V (3V minus 5%), the maximum input voltage to detect "high" is 2.4V and maximum input current is 10 µA. Then the resistor will need to be at most Rmax = (Vdd_min - Vin_max) / Iin_max = (3.15V - 2.4V) / 10 µA = 75kOhm. This value is part of the E24 series, but is can be 68kOhm that is in the E6 series.

However, it [seems as if the circuit of the modules contains a simple PNP BJT][1], a pull-up will not work here, because the input needs to be pulled up to the supply voltage of the module. You need a level converter, this could be a simple transistor. How to design that circuit, is another issue. There are lots of information in the web how to do this.

  [1]: https://arduinodiy.wordpress.com/2018/08/07/re-inverting-an-inverting-relay/


body:
I am trying to determine why my Arduino MKR NB 1500 code keeps crashing when the serial monitor is open and I look for data. I removed the string functions to prevent it from causing memory fragmentation, but does not seems to have helped.

```c++
#include <ArduinoMqttClient.h>
#include <MKRNB.h>

// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
const char PINNUMBER[]     = "";

// MQTT Broker and Port
const char broker[] = "test.mosquitto.org"; //
int        port     = 1883;

// Pub/Sub Topics - Make it something unique since we are using a public broker
const char subscribeTopic[]  = "channel";
const char publishTopic[]  = "channel";

// To connect with SSL/TLS:
// 1) Change NBClient to NBSSLClient.
// 2) Change port value from 1883 to 8883.
// 3) Change broker value to a server with a known SSL/TLS root certificate
//    flashed in the WiFi module.

NBClient client;
GPRS gprs;
NB nbAccess;
MqttClient mqttClient(client);

int LED = 6; // Onboard LED

// Publish interval
long previousMillis = 0;
long interval = 2000;

void setup() {
    pinMode(LED_BUILTIN, OUTPUT); // Set built in LED pinMode

    //Initialize serial and wait for port to open:
    Serial.begin(9600);
    /* while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
    }*/

    // attempt to connect to GSM and GPRS:
    Serial.print("Attempting to connect to GSM and GPRS");
    // connection state
    bool connected = false;

    // After starting the modem with GSM.begin()
    // attach the shield to the GPRS network with the APN, login and password
    while (!connected) {
        if ((nbAccess.begin(PINNUMBER) == NB_READY) &&
                (gprs.attachGPRS() == GPRS_READY)) {
            connected = true;
        } else {
            Serial.println("Not connected");
            delay(1000);
        }
    }

    Serial.println("You're connected to the network");
    Serial.println();

    Serial.print("Attempting to connect to the MQTT broker: ");
    Serial.println(broker);

    if (!mqttClient.connect(broker, port)) {
        Serial.print("MQTT connection failed! Error code = ");
        Serial.println(mqttClient.connectError());

        while (1)
            ;
    }

    Serial.println("You're connected to the MQTT broker!");
    Serial.println();

    // set the message receive callback
    mqttClient.onMessage(onMqttMessage);

    Serial.print("Subscribing to topic: ");
    Serial.println(subscribeTopic);
    Serial.println();

    // subscribe to a topic
    mqttClient.subscribe(subscribeTopic);

    Serial.print("Waiting for messages on topic: ");
    Serial.println(subscribeTopic);
    Serial.println();
}

void loop() {
    unsigned long currentMillis = millis();

    // call poll() regularly to allow the library to receive MQTT messages and
    // send MQTT keep alives which avoids being disconnected by the broker
    mqttClient.poll();

    // Enforce Interval
    if (currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;

        // Call a function that handles publishing message
        publishSensorVal();
    }
}

void publishSensorVal() {
    // read the first Analog pin
    int sensorVal = analogRead(0);
    //String speak = "The sensor val is " + String(sensorVal);
    char adc_sv[30] = { 'T', 'h', 'e', ' ', 'a', 'd', 'c', ' '' ', 'v', 'a', 'l', 'u', 'e', ' ', 'i', 's', ' ', '\0' }; //adc_step value
    // Publish our sensor value to the publish topic
    mqttClient.beginMessage(publishTopic);
    mqttClient.print(adc_sv);
    mqttClient.print(sensorVal);
    mqttClient.endMessage();
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(1400);                       // wait for a second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(100);                       // wait for a second
}

void handleCommand(String cmd) {
    if (cmd == "on") {
        digitalWrite(LED, HIGH);
    } else if (cmd == "off") {
        digitalWrite(LED, LOW);
    }
}

void onMqttMessage(int messageSize) {
    // we received a message, print out the topic and contents
    Serial.println("Received a message with topic '");
    Serial.print(mqttClient.messageTopic());
    Serial.print("', length ");
    Serial.print(messageSize);
    Serial.println(" bytes:");

    // We want to read each character into a useable String
    String content = "";
    char character;

    // use the Stream interface to print the contents
    while (mqttClient.available()) {
        character = (char)mqttClient.read();
        content.concat(character);
    }

    handleCommand(content); // This function does something with our incoming string

    Serial.println(content);
    Serial.println();
    Serial.println(); // double spacing
}
```

The output looks as follows when it gets stuck:[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/3SF3Y.png

title: Arduino crashing during serial print

Answers: 0


body:
I've got an ESP32 with an CO2 sensor attached. The Arduino script I'm using is quite old and worked for sending them over LoraWAN to TTN and is stable. I added an Wifi-Client to read data more frequently when an Wifi is near. The data get send over to my server via MQTT. Now after some time the device stops sending; I think it's just a few hours working. (I used libraries)

Now my question -  how do I find the problem? I mean it has something to be the memory, doesn't it? The code is quite long so I would prefer to find the actual problem on my own - but how? My idea was to send debug messages by MQTT, hooking up a client to save all the MQTT messages so I can view the last messages the device sent. (I'm not even sure if the device fully stops or just loses connection etc). This whole thing sound like a tedious problem as I'd have to wait a few hours after every code fix I'd have implemented..

Thank for any help!

title: How to debug an error which occures after a long time only?

Answers: 0


body:
I created a class for TFT buttons and messages when using a Wemos 2.4 tft touch display.

In a code I use about 12 buttons (3 different screens with 4 buttons in each screen ), for example in my home control code "Main Screen" has `Lights`, `Windows` `Alarms`, `Temperatures`, and each screen below has set of others.

Since button's life expectancy is only for current screen (also in `loop()` since it monitor press at defined location), and each button take no little resources as show below in lib's `.h` file (other class with touch function are not show here), I would like to know how to create a destructor to free up space, since main resources are used in `MessageTFT` class.

    #ifndef TFT_GUI_h
    #define TFT_GUI_h

    #include <SPI.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_ILI9341.h>
    #include <XPT2046_Touchscreen.h>

    extern XPT2046_Touchscreen ts; /* Touch screen */
    extern Adafruit_ILI9341 tft;   /* Graphics */

    const uint8_t _pos_corr_factor[3] = {3, 6, 9}; /* Center text inside a box */
    class MessageTFT
    {
    public:
      uint8_t a, b;
      int xc, yc;
      uint8_t txt_size = 1;
      uint8_t screen_rotation = 0;
      uint8_t border_thickness = 1;
      uint16_t face_color = ILI9341_GREEN;
      uint16_t border_color = ILI9341_RED;
      uint16_t txt_color = ILI9341_BLACK;

      char txt_buf[30];
      bool roundRect = false;

    public:
      MessageTFT(Adafruit_ILI9341 &_tft);
      void drawMSG();
      void text(char *txt);
    private:
      uint8_t _radius = 15;

    private:
      void _drawFace();
      void _drawBorder();
      void _put_text();
    };
    #endif

title: Use and definition of a destructor class

Answers: 1

body:
Destructors, despite their name, are not used to destroy the object. They are, instead, a "hook" that is called *when* the object is destroyed. Much like the "constructor" is called *when* the object is created - it doesn't *do* the creating.

A destructor is intended to "clean up" an object before it is deleted. That usually entails freeing any memory allocated at runtime (through `malloc()`, `new`, etc) by the object.

Since you don't do anything at runtime that needs to be cleaned up there is nothing for your destructor to do. All your variables are simple statically allocated memory as part of the object istelf, so those automatically get destroyed when the object is destroyed.

You can think of it as crushing a car. The seats, engine and steering wheel all get crushed without you having to worry about it. But first you want to take the dog out of the boot - you *really* don't want him in there when the car gets crushed, it'll get really really messy and the dog will be lost forever ... :(


body:
I am trying to convert 1.06 to 106 by multiplying by 100 but the answer comes 105, I do not know why. Variable ver can be any decimal in this format x.xx

    float ver = 1.06;
    int vers = ver * 100;
    vm[0] = (vers / 100U) % 10;
    vm[1] = (vers / 10U) % 10;
    vm[2] = (vers / 1U) % 10;
    Serial.println(vers);

Could  you let me know what I am doing wrong or maybe I have to do something else.

title: Convert float to int error

Answers: 1

body:
1.06 is not a float. The closest float is 1.059999942779541015625. If
you multiply that by 100 you get a number that, again, is not a float.
Rounding to the nearest float yields 105.99999237060546875, which is the
result of the expression `ver * 100`, and just one [ULP][] short of 106.
Yes, floating point computations do quite usually involve rounding
steps.

Casting to an `int` implicitly rounds towards zero, and you get 105,
which is the correct result. Correct according to the rules of IEEE 754
arithmetics.

You may want to `round()` to the nearest integer before the cast.

> Variable ver can be any decimal in this format x.xx

No, a `float` cannot be “any decimal” in this format. Floats are stored
in binary, and most decimal numbers (numbers that can be written with a
finite number of decimal digits) cannot be written in binary with a
finite number of bits.

Except for a few values (namely the multiples of 0.25), `ver` can only
store an _approximation_ of the decimal number.

[ULP]: https://en.wikipedia.org/wiki/Unit_in_the_last_place