body:
I've been reading a lot over the years why we should not use the notorious String class and how heap fragmentation is bad practice and not professional and we should never use it in our programs or we'll never enter the C hall of fame and get to be called programmers.

Fine, I get it, C string is pro, String is people toying with Arduino, but having read all that I still don't understand:

1. Where is the risk? If I use String and my heap gets fragmented, and there's still enough memory for the program to run for months without crashing, why should I not use String if it makes my work so much easier? Just because it's a bad habit is a very lame answer.

2. Is it possible to quantify the fragmentation and get a feel of what's safe and when it becomes risky? Are there any tools to measure / alert / help us know how close we are to fall off that cliff?

3. And really, what is potential harm, in practical terms not theoretically, what are the limits, does anyone know when a program will crash?

Happy coding!

title: Using String instead of C string, yet another attempt to touch a loaded issue

Answers: 6

body:
It's not that `String` itself is evil, it's more that it's *very* easy to abuse it and cause heap fragmentation. Used judiciously it's fine and a useful tool. Used in "bad" ways and you open the door to random crashes.

By "bad" ways I mean excessive (and not needed) data duplication and heap reallocation. The biggest pitfalls are:

* Using `.concat()` or "adding" strings together with `+`
* Passing `String` objects to functions by value instead of by reference

Basically anything where a new string is created and the old one thrown away leaves holes in the heap.

Those holes (fragmentation) themselves aren't a problem - the problem is the very tiny amount of RAM the typical low-end Arduino (i.e., ATMega328P based) has. When you have wasted space in your heap in the form of holes it's more and more likely that you will end up having the top of your heap meet the bottom of your stack, and *that* is when problems arise.

For transient operations `String` is fine. By "transient" I mean operations where *all* the data is discarded at the end. All temporary *and* source strings are destroyed and *all* the memory is returned to the pool, thus leaving no holes in the heap.

Also on microcontrollers with far more memory than a little Arduino UNO (such as ESP32, etc) heap fragmentation ceases to really be a problem. By the time the heap grows big enough to be noticeable any holes have got big enough that they start to get filled again.

body:
The short answer is that fragmentation crashes are infrequent because they require very specific conditions to arise—**and that's the problem.**

Imagine you have a crash that occurs once every few days and can't figure out why. It never happens while testing and doesn't seem to be caused by anything specific.

Then it turns out that your code is printing numbers to a string, usually 4 digits but sometimes 2 or 3. And it turns out that very specific sequences of the lengths of strings being allocated and deallocated trigger a crash. But there's no good way to analyse or predict the problem because it hinges on absolutely everything that's happened since boot. If there was a 3- instead of 4-digit number 8 hours ago, that completely changes what would need to happen *now* to trigger a crash.

While answering this question I tried to come up with some code that would leave memory very fragmented. It was very difficult. Memory fragmentation is very sensitive to what happens, in what order. Basically it's a highly chaotic system.

This is reminiscent of problems related to multithreading, where running a simple program multiple times can easily give different results. Problems like this are really, really frustrating to identify and diagnose. A lot of people have felt the pain and that is why there is such stigma about `String`.

To answer your questions:

> 1. why should I not use String if it makes my work so much easier?

As long as you understand the pitfalls and how to avoid them, sometimes `String`s are the best tool for the job.

The main goal of avoiding `String` is to prevent severe heap fragmentation. There are other ways to do that, though:

* Don't store lots of heap-allocated objects on a long-term basis. If you only have 3 global `String` variables then it's probably fine to allocate 100 small strings if you delete them before doing anything else
* If you have to store many heap-allocated objects long-term, try not to allocate them during a period of a lot of heap allocations, deallocations, and resizings (such as during a loop when a string is being built). You want to avoid these long-term objects being given "random" positions through memory.

If you want to use `String` in an application where reliable long-term operation is important, you really have to be thorough in understanding your memory usage patterns and why they are unlikely to trigger a problem.

I should add that each `String` adds several bytes of memory overhead, both for the string descriptor and for the invisible bookkeeping that the `malloc()` implementation does. They are also slower to access than `char []`s.

> 2. Is it possible to quantify the fragmentation and get a feel of what's safe and when it becomes risky?

This is difficult because of how sensitive things are to tiny differences in allocation history. There are a few simple analyses you can do, though.

If you have `n` heap-allocated objects, you have `n+1` fragments (although some fragments may be zero size.) The average fragment size will be ≤ the amount of free space divided by `n+1`. For example if you have 19 allocated objects and 2000 bytes of remaining space, your average fragment size will be 100 bytes. Mathematically this implies that at least one fragment is ≥ this size, and therefore you are guaranteed to be able to allocate anything smaller than 100 bytes. Keep in mind though that every allocated object consumes a few bytes of invisible bookkeeping data used by the runtime's implementation of `malloc()`, and there may be other hidden things floating around in the system, like some objects allocated by libraries. Also remember that on Arduino, SRAM is shared by stack and heap.

Now let's say you have 8KB of heap space and you allocate a lot of stuff, then deallocate a lot of stuff, leaving exactly 3 small objects allocated. This will divide your heap into 4 regions. The average size will be just under 2KB and so no matter how unlucky you are, one or more of the regions will be *at least* that size. So you should be able to allocate one large object of around 2KB, or, allocate hundreds of small objects, or allocate one object and keep resizing it anywhere up to 2KB. If you then free everything except for 3 small objects, you will be back in the same situation: you are guaranteed a region of at least 2KB.

There are two noteworthy conclusions:
 * If the maximum number of items that will ever be allocated at a time is `n`, and their maximum size is `s`, and your heap size is at least `(2n+1) × (s+4)`, you will never have a fragmentation problem. (3 is an architecture-dependent fudge factor to cover `malloc` bookkeeping and padding issues.)
 * If there are "checkpoints" in your code where only a few objects are allocated, this makes it easier to reason about what can happen between these checkpoints.

> Are there any tools to measure / alert / help us know how close we are to fall off that cliff?

Not for Arduino that I know of. The problem is, a program susceptible to severe fragmentation may only display signs for short periods once every few days or something.

The easiest technique you can use is to consume say 30% of your memory with `malloc()` at the start of your program to put more heap pressure on it, and see if it still works. This isn't guaranteed to bring the problems out of the woodwork, but it greatly boosts the chances that you will see something.

You can also write a function to try to allocate the largest objects possible over and over, slowly reducing the size, and see to what extent you are prevented from allocating large objects but can allocate small ones. I was going to post one but I decided it would be of limited benefit.

If you really want to see what is going on with your heap you can [look at the source of your `malloc()` implementation][1] and inspect its data structures from within your program. In this case it seems to be as simple as putting this at the start of your code

    struct __freelist {
      size_t sz;
      struct __freelist *nx;
    };
    extern struct __freelist *__flp;

and then you can traverse the contents of the [freelist][2] using `__flp`.

  [1]: https://github.com/XMegaForArduino/arduino/blob/master/cores/xmega/avr-libc/malloc.c
  [2]: https://en.wikipedia.org/wiki/Free_list

body:
As you already got good answers to most of your questions, I will try
to cover here only this one:

> Is it possible to quantify the fragmentation and get a feel of what's  safe and when it becomes risky?

A quick Web search for “Arduino free memory” finds a few code snippets
that can be used to measure, at run time, the amount of free memory:

* [Available Memory][], in the Arduino Playground, only works on AVR. It
  measures  the total amount of available RAM, including the holes in
  the heap.

* [Measuring Memory Usage][], an Adafruit tutorial, shows some portable
  (AVR and ARM) code that measures the available RAM between the heap
  and the stack. This does _not_ include the holes in the heap.

If you compare the AVR versions of these two code snippets, you can see
the difference is in the `freeListSize()` function of the Playground
version. This function returns the total memory residing in heap holes,
which could be a measure of the heap fragmentation.

The function is AVR-specific, but then AVR is where heap fragmentation
is most worrisome.

[Available Memory]: https://playground.arduino.cc/Code/AvailableMemory/
[Measuring Memory Usage]: https://learn.adafruit.com/memories-of-an-arduino/measuring-free-memory

body:
I'm not an Arduino programmer, but I am a C programmer.  And the problem of string types in C -- or, rather, the *absence* of a first-class string type in C -- is an old but important one.

The fundamental problem is this.  In C, you can say things like

    int a, b, c, d, f();
    a = b + c;
    d = f();

And you can say things like

    float q, r, s, t();
    q = r / s + t();

But you can *not* say

    string x, y, z();
    x = y + z();

C has no first-class string type.  In pure C, if you want to manipulate strings, you have to use some combination of `char []` arrays and `char *` pointers.  You have to remember to allocate enough memory to hold the strings you're working with today.  In many cases you can't assign strings; you may have to call `strcpy` or the like.  In most cases you can't directly compare strings; you usually have to call `strcmp` or the like.  This can all be a real nuisance, and if you get the details wrong, you get strange bugs and crashes.

So, especially if you're a beginning or casual programmer, It Would Be Nice if C had a true, first-class string type.  (And of course C++ does have such a type.)

But there's a very good reason that plain C doesn't have such a type.  Manipulating strings is just plain harder than manipulating ints or floats.  The reason it's harder is precisely because they're variable-length, and potentially rather large.  Under C's low-level philosophy, the best person to make good tradeoffs when it comes to deciding how to handle a particular program's strings is that program's author, *not* the compiler or library writer.

You can write a decently good, decently efficient, high-level, first-class string type.  *But*, it's never going to be *as* efficient, for every problem, as handcrafted `char []` and `char **` code would be.  Also, if there are a bunch of rules for how to use a first-class string type efficiently, avoiding fragmentation and the like, those rules are probably going to end up being almost as complicated as the rules for using `char []` and `char *` correctly -- but the whole point of introducing the first-class string type was so that programmers *wouldn't* have to worry about those low-level details all the time!  It's really rather a pretty pickle.

So when someone says, "you shouldn't use that high-level string type, it's wasteful and inefficient", the question to ask is, is it *unacceptably* wasteful or inefficient?

Once upon a time, people said we shouldn't use compiled languages, since they're wasteful and inefficient.  Those people thought we should all write everything in assembly language.  (And there are still a few people who say this.)  Most of the time, though, we've discovered that compiled code is adequately efficient, and its other advantages more than make up for any slight lingering inefficiencies.

And the question for C strings versus Strings is almost perfectly equivalent.  If your program is making significant use of strings, expending a large fraction of its time or a large fraction of the available memory towards them, the inefficiencies of Strings might well be unacceptable.  If there are relatively few strings, however, the convenience to the programmer of using a high-level String type (along with the absence of bugs) might be well worth it, and the costs might be inconsequential.

But there's no one right answer to the question of "Do or don't use Strings", because it's a subjective question, and different people under different circumstances will legitimately come to different conclusions.

body:
I'd like to answer your question without discussing the more technical side. This has been admirably covered by my learned colleagues in their own answers. I am going to address the cost-benefit side of using String.

Certainly, in the short term, it is almost certainly faster and easier to use String than to allocate buffers of characters, keeping track of how full they are, appending to the end of them, and so on.

For example, to read serial input, this is easy:

    String inputBuffer;

    void loop()
      {
      while (Serial.available () > 0)
        inputBuffer += Serial.read ();

      if (inputBuffer == "something")
        doSomething ();
      }  // end of loop

This, by the way, is the very sort of code that is likely to cause heap fragmentation and a crash. :)

So, you may well save an hour or two of coding by using the String class. So far, so good. You are ahead.

Then you start testing. Things go well for a while, but then after your code runs for an hour it mysteriously crashes, or probably, hangs. Your device stops doing what it is supposed to do, and you start looking for bugs. There is nothing *obviously* wrong, so you spend quite a bit of time trying to solve the issue. Heap fragmentation doesn't jump out and slap you in the face like, say, forgetting to add one variable to another.

So you look over the code, maybe post a question on Stack Exchange, maybe ask friends, maybe ask your teacher (where appropriate). Soon enough, time is mounting. You spend an hour debugging, two hours, four hours, and soon you have spent eight hours on it. Now you have wasted all the benefit you got from using the "easy" String class. Not only that, you are way behind, compared to allocating a fixed-size buffer and managing putting data into it yourself.

Sooner or later you identify that heap fragmentation is the culprit, and have to rewrite it. In other words, you eventually have to stop using the String class. So the whole episode has been a waste of time.

Certainly this won't always happen, and for the occasional use of fixed-length String objects, there won't be an issue. But if you look at the conditions mentioned in the other answers, you can see that it is easier, in fact, to "just don't use String" than to use them in very careful ways, and hope that your project doesn't break today, tomorrow, next week, or after three months "in the field".

>  why should I not use String if it makes my work so much easier?

Certainly you should, if it makes your work easier, *and if it doesn't crash*.

>  does anyone know when a program will crash?

No, probably not. If you are "lucky" it will crash soon after you start it, and you will at least know you have a problem. If you are unlucky your fish feeder will stop feeding your fish two weeks into your holiday and they will die.

body:
Mega point is: don't use String (or anything else that uses the heap) inside interrupts - even with objects created outside the interrupt. the underlying memory allocation functions cannot deal with it and you've got a good chance something will go boom.

As for the rest, so much of this is dependant on implementation

Nick's answer with the input buffer yes will crash, he never clears it! (j/k)
But even if he did after matching with something, i.e.

          if (inputBuffer == "something") {
                inputBuffer="";
                doSomething ();
          }

after we've hit this there will be no more (possible) fragmenting to do with this code, as the implementation for String on the copy (or a concatenation) there *does not reallocate the memory buffer unless it is too small*. So as we go round this whole loop after the first time, no heap allocations will happen.

We could also remove any reallocations during the initial building of the 'something' string in the inputBuffer by allocating enough space right at the beginning of the code with

        inputBuffer.reserve(9);

where 9 is the length of the string 'something' (reserve will add an extra byte on the buffer for the string terminator)

You can also use this to reserve space for doing multiple concatenations . Anything above 1 concat / += will save time because of not multiply reallocating space, plus stop the fragmentation.

        int newSize=a.length()+b.length()+c.length();
        a.reserve(newSize); // only memory realloc happens here
        a.concat(b);
        a.concat(c);

Similarly you could create a much bigger buffer to briefly handle something you're not sure the size of (say, reserve 512 bytes) but beware! because of the point above (.reserve() does not reallocate the buffer unless the requested size is larger) you are stuck with that buffer *until the string object is destroyed by going out of scope or being explicitly deleted*. Global objects are stuck with it. So if you need a global object that could get bigger or smaller, make it a pointer to a String then use new/delete as required.

Also we need to consider object lifetime. Even if you use a bunch of String objects in a function, if they are all destroyed at the end, and you haven't created any other heap objects within that function, when you have left and all the Strings are auto destroyed there should be no impact on the heap, it should return to its previous state as the memory is reclaimed

If you are creating String objects on the heap (via new) though it does compound any fragmentation problems you may have in your code anyway as you end up with 2 heap items, the String wrapper object and the data itself. If you're just using a local or global variable the wrapper won't be in the heap, either in global memory or on the stack.


body:
I am using the following circuit to measure the Li-ion 3.7V battery capacity.

[![Setup for 3.7V Batteries][1]][1]

*Figure 1 – Schematic for 3.7 V batteries.*

This setup works fine for the 3.7V batteries.

To be able to measure 9V batteries, I modified the circuit with a voltage divider so that the Arduino sees max 5v at the analog input. However Arduino reports 0V. I have measured the output of voltage divider with a DMM and it shows 5V. I wonder why doesn't Arduino report the correct voltage. Could you please help me fix it?

[![Modified schematic for 9 V batteries which doesn't work][2]][2]

*Figure 2 – Modified schematic for 9 V batteries which doesn't work.*

My code:

```cpp
#include "LCD5110_Graph.h"
LCD5110 myGLCD(5, 6, 7, 9, 8); // Setup Nokia 5110 Screen SCLK/CLK=5, DIN/MOSI/DATA=6, DC/CS=7, RST=9 Chip Select/CE/SCE=8,
extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];

#define gatePin 10
#define highPin A0
#define lowPin A1

boolean finished = false;
int printStart = 0;
int interval = 5000; // Interval (ms) between measurements

float mAh = 0.0;
float shuntRes = 1.0; // In Ohms – Shunt resistor resistance
float voltRef = 4.71; // Reference voltage
float current = 0.0;
float battVolt = 0.0;
float shuntVolt = 0.0;
float battLow = 2.9;

unsigned long previousMillis = 0;
unsigned long millisPassed = 0;

void setup()
{
 Serial.begin(9600);
 Serial.println("Battery Capacity Checker v1.1");
 Serial.println("battVolt current mAh");

 pinMode(gatePin, OUTPUT);
 digitalWrite(gatePin, LOW);

 myGLCD.InitLCD(); // initialize LCD with default contrast of 70
 myGLCD.setContrast(68);
 myGLCD.setFont(SmallFont); // Set default font size. tinyFont 4×6, smallFont 6×8, mediumNumber 12×16, bigNumbers 14×24
 myGLCD.clrScr();

 myGLCD.print("Battery", CENTER, 0);
 myGLCD.print("Check", CENTER, 12);
 myGLCD.print("Please Wait", CENTER, 24);
 myGLCD.print("AdamWelch.Uk", 8, 40);
 myGLCD.update();
 delay(2000);
 myGLCD.clrScr();
}

void loop()
{
 battVolt = analogRead(highPin) * voltRef / 1024.0;
 shuntVolt = analogRead(lowPin) * voltRef / 1024.0;

 if (battVolt >= battLow && finished == false)
 {
  digitalWrite(gatePin, HIGH);
  millisPassed = millis() – previousMillis;
  current = (battVolt – shuntVolt) / shuntRes;
  mAh = mAh + (current * 1000.0) * (millisPassed / 3600000.0);
  previousMillis = millis();

  myGLCD.clrScr();
  myGLCD.print("Discharge", CENTER, 0);
  myGLCD.print("Voltage:", 0, 10);
  myGLCD.printNumF(battVolt, 2, 50, 10);
  myGLCD.print("v", 77, 10);
  myGLCD.print("Current:", 0, 20);
  myGLCD.printNumF(current, 2, 50, 20);
  myGLCD.print("a", 77, 20);
  myGLCD.printNumI(mAh, 30, 30);
  myGLCD.print("mAh", 65, 30);
  myGLCD.print("Running", CENTER, 40);
  myGLCD.update();

  Serial.print(battVolt);
  Serial.print("\t");
  Serial.print(current);
  Serial.print("\t");
  Serial.println(mAh);

  delay(interval);
 }
 if (battVolt < battLow)
 {
  digitalWrite(gatePin, LOW);

  finished = true;

  if (mAh < 10)
  {
   printStart = 40;
  }
  else if (mAh < 100)
  {
   printStart = 30;
  }
  else if (mAh < 1000)
  {
   printStart = 24;
  }
  else if (mAh < 10000)
  {
   printStart = 14;
  }
  else
  {
   printStart = 0;
  }

  myGLCD.clrScr();
  myGLCD.print("Discharge", CENTER, 0);
  myGLCD.print("Voltage:", 0, 10);
  myGLCD.printNumF(battVolt, 2, 50, 10);
  myGLCD.print("v", 77, 10);
  myGLCD.setFont(MediumNumbers);
  myGLCD.printNumI(mAh, printStart, 21);
  myGLCD.setFont(SmallFont);
  myGLCD.print("mAh", 65, 30);
  myGLCD.print("Complete", CENTER, 40);
  myGLCD.update();

  delay(interval * 2);
 }
}
```

Circuit with modifications

[![Schematic for 9 V Batteries][3]][3]

*Figure 3 – Schematic for 9 V batteries.*

  [1]: https://i.stack.imgur.com/hcKtR.png
  [2]: https://i.stack.imgur.com/uJHVe.png
  [3]: https://i.stack.imgur.com/Iowen.png

title: Battery voltage measurement with voltage divider

Answers: 1

body:
The problem comes because you are powering your load through the voltage divider you use for reading your battery voltage.

You cannot do high-side current reading like that with a voltage higher than the ADC voltage. Instead you need to do the current sensing *before* your voltage divider and *then* divide that result down again.

Your circuit should look more like:

<!-- 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/v81u4.png)

<!-- End schematic -->


body:
Is it possible to connect more than one I2C device to an Arduino Uno? I know that the SCL and SDA pins are on analog pins A4 and A5 respectively, but there are also two pins labeled SCL and SDA located next to the AREF pin on the other side of the board. Does that mean I can connect multiple devices to the same board and, if so, how?

For context, I'm currently working on creating a robotic arm that matches its movements to the movements of my arm (I believe this is called a telepresence robot). To do so, I wanted to use a couple of IMUs (specifically the MPU-6050) to record the movements of my wrist and shoulder. Using the [TinyMPU6050][1] library by Gabriel Milan, I've already been able to establish communication with one IMU, but I'm struggling with the second one. I'm already communicating with the arm via the Uno's SPI interface so I can't use that to communicate with a second IMU, although I know it's possible.

I know that similar questions have been asked before, but none of the questions I could find had the exact answers that I needed, so I thought I would ask anyway. This code that I currently have works for one IMU, but I don't know where to begin to add a second one (if it's even possible). Any help that I can get would be greatly appreciated. Cheers!

  [1]: https://github.com/gabriel-milan/TinyMPU6050

```
#include <TinyMPU6050.h>

MPU6050 IMU_1(Wire);

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

  //initializing and calibrating `IMU_1`
  IMU_1.Initialize();
  Serial.println("Calibrating...");
  IMU_1.Calibrate();
  Serial.println("Calibrated");

  while (!Serial) {
    //empty while loop
  }
}

void loop() {
  IMU_1.execute();
  Serial.println();
  Serial.print("X angle = ");
  Serial.println(IMU_1.GetAngX());
  Serial.print("Y angle = ");
  Serial.println(IMU_1.GetAngY());
  Serial.print("Z angle = ");
  Serial.println(IMU_1.GetAngZ());

  delay(1000);
}
```

title: Multiple I2C devices connected to one Arduino Uno?

Answers: 1

body:
I2C is a *multi-drop bus*. That means that one set of I2C pins are *designed* to have multiple devices on it *as long as each device has a unique address*.

On an Uno the discrete I2C pins and the A4/A5 I2C pins are the same pins. The discrete pins are an attempt to provide a cross-platform standard location for the I2C signals for shields.


body:
I am working on a project for my brothers and anyone else who is interested in playing some LED Pong. I was just stuck on the software part. I don't really know what to do. But, I have an idea: I want to use the map() function to make my life easier, however, I am not sure how to use the map function with the Dot Matrix. All help would be appreciated. All of the stuff came in [this kit.][1]

Here is the test code:

    #include <LedControl.h>

    int DIN = 2;
    int CS =  3;
    int CLK = 4;

    const int playerOnePin = A0;
    const int playerTwoPin = A1;

    int playerOneValue;
    int playerOneValue2;
    int playerTwoValue;
    int playerTwoValue2;

    LedControl lc = LedControl(DIN, CLK, CS, 0);

    void setup() {

      lc.shutdown(0, false);      //The MAX72XX is in power-saving mode on startup
      lc.setIntensity(0, 15);      // Set the brightness to maximum value
      lc.clearDisplay(0);          // and clear the display

      pinMode(playerOnePin, INPUT);
      pinMode(playerTwoPin, INPUT);

    }

    void loop() {

      byte a[8] = {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
      printByte(a);

    }

    void printByte(byte character []) {

      int i = 0;
      for (i = 0; i < 8; i++)
      {
        lc.setRow(0, i, character[i]);
      }
    }

    void readPot() {

      playerOneValue = analogRead(A0);

      playerOneValue2 = map(playerOneValue, 0, 1023, 0, 180);
    }

Here is the other code:

    #include <LedControl.h>

    int DIN = 2;
    int CS =  3;
    int CLK = 4;

    byte displayImage[8] =     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    // considering a 2d co-ordinate system with origin (0,0) at bottom left corner
    int ballX = 3; //X position
    int ballY = 7; //Y position - top
    int speedX = 0; // no X movement, can be -1, 0 or 1
    int speedY = -1; // downward Y movement, can be -1, 0 or 1
    int paddleX = 4; // X position of center of paddle - can be 1 to 6. Paddle width is 3
    int score = 0;

    LedControl lc = LedControl(DIN, CLK, CS, 0);

    void setup() {
      pinMode (A0, INPUT);
      pinMode (A1, INPUT);
      lc.shutdown(0, false);      // Keep MAX72XX awake
      lc.setIntensity(0, 15);     // Set the brightness to maximum value
      lc.clearDisplay(0);         // and clear the display
    }

    void loop() {
      // update ball position
      ballX = ballX + speedX;
      ballY = ballY + speedY;

      // check for ball interaction with walls
      if (ballX == 0 || ballX == 7) {
        speedX = speedX * -1; // bouncing off walls in horizontal direction
      }

      // bouncing off ceiling
      if (ballY == 7) {
        speedY = speedY * -1; // bouncing off the ceiling
      }

      // bouncing off the paddle
      if (ballY == 0 && ballX >= (paddleX - 1) && ballX <= (paddleX + 1)) {
        speedY = speedY * -1;
        score++;    // player earns a point
      }

      // going past the paddle
      if (ballY == 0 && ballX < (paddleX - 1) && ballX > (paddleX + 1)) {
        // going past the paddle - player is out
        Serial.println(); Serial.print("Score: "); Serial.println(score);
        for (int i = 0; i < 8; i++) {
          displayImage[i] = 0x00;
        }
        displayImage[3] = 0xFF; displayImage[4] = 0xFF; // show a line
        renderByte(displayImage);
        while (1); // Freeze
      }
      // clearing the image variable
      for (int i = 0; i < 8; i++) {
        displayImage[i] = 0x00;
      }

      // generating new image
      addPixel(ballX, ballY); // adding the ball position to image
      addPixel(paddleX - 1, 0); addPixel(paddleX, 0); addPixel(paddleX + 1, 0);
      // adding paddle position to image
      renderByte(displayImage); // show the generated image

      // handling paddle control
      if (analogRead(A0) && paddleX > 0) {
        paddleX = paddleX - 1; // move paddle left
      }

      if (analogRead(A1) && paddleX < 7) {
        paddleX = paddleX + 1; // move paddle right
      }

      delay(200);
    }

    void addPixel(int xVal, int yVal) {
      int newRowval = 2 ^ (7 - xVal);
      int rowVal = displayImage[7 - yVal];
      displayImage[7 - yVal] = rowVal || newRowval;  // inserting a 1 at the required pixel
    }

    void renderByte(byte image [])
    {
      int i = 0;
      for (i = 0; i < 8; i++)
      {
        lc.setRow(0, i, image[i]);
      }
    }

Here is the picture of the wiring and the schematic:

[![This is the wiring picture][2]][2]

[![Wiring Pic][3]][3]

[![Wiring Pic][4]][4]

[![Wiring Pic][5]][5]

[![Schematic][6]][6]

  [1]: https://www.amazon.com/EL-KIT-008-Project-Complete-Ultimate-TUTORIAL/dp/B01EWNUUUA/ref=sr_1_1_sspa?dchild=1&keywords=arduino mega kit&qid=1626207537&sr=8-1-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUExR1NEMVNXUkpRS0ZDJmVuY3J5cHRlZElkPUEwODgxNjc5MzA2V1U5RFFLVEpBSSZlbmNyeXB0ZWRBZElkPUEwNTQyNzgzMllKVEdLM0pFNURRViZ3aWRnZXROYW1lPXNwX2F0ZiZhY3Rpb249Y2xpY2tSZWRpcmVjdCZkb05vdExvZ0NsaWNrPXRydWU=
  [2]: https://i.stack.imgur.com/NztGE.jpg
  [3]: https://i.stack.imgur.com/t6lbL.jpg
  [4]: https://i.stack.imgur.com/LsFrd.jpg
  [5]: https://i.stack.imgur.com/t9nGu.jpg
  [6]: https://i.stack.imgur.com/LJvnT.jpg

title: How do I recreate the Pong game with two pots and the map function?

Answers: 1

body:
First figure out the min and max values that paddleX can have.  I assume if the paddle is two dots wide then its min,max will be 0,6   Then figure out the min and max of your pot, typically 0,1023 for a a 10 bit adc.  Now to map your pot value to paddleX value you'd use the command :

    paddleX = map(analogRead(A0),0,1023,0,6);

here is the map documentation : https://www.arduino.cc/reference/en/language/functions/math/map/


body:
The [FireBeetle ESP32][1] advertises an input voltage of 3.3v-5v, with an operating voltage of 3.3v.

I tested this with an 18650 lithium-ion battery and can confirm this is true. For 3.3V < Vbat < 4.2V, there is a consistent ~3.295 volts at the 3V3 pin. For Vbat < 3.3V, 3V3 drops slightly under Vbat (approx. -.02V).

I found this odd because the onboard RT9080-33GJ5 regulator has a dropout of about 0.2V to 0.3V, so theoretically the output voltage should drop off steeply for Vbat < 3.6V.

Looking at the [schematic][2], I was unable to figure out exactly how this board is able to regulate to 3.3 volts with essentially no dropout. Is it using some sort of buck converter that isn't mentioned in the schematic, or some other clever circuit?

Any help understanding would be much appreciated!

  [1]: https://www.dfrobot.com/product-1590.html
  [2]: https://raw.githubusercontent.com/DFRobot/Wiki/master/DFR0478/[DFR0478]FireBeetle Board-ESP32(V4.0)生产检查图.PDF

title: How does the FireBeetle ESP32 regulate to 3.3v? (schematic provided)

Answers: 1

body: Answered my own question - I didn't realize that dropout voltage essentially goes to 0 for this regulator when current consumption is low. Pretty neat for low current applications with the ESP32.


body:
[![enter image description here][1]][1]Hello. Currently I'm working on creating an automatic dog food dispenser. I'm using a Arduino Uno R3, an L298N stepper driver, a DS1307 RTC breakout board, a Nema 17 stepper motor, and a breadboard to disperse the power to each board. I'm using a 9V battery to power it temporarily. I've tested motor control without it being determined by the current time and it works perfectly however when I have the motor run at a specific time (4:45 and 6:45 in the code) the motor doesn't move. How can I move the motor at these specific times?

    #include <RTClib.h>
    #include <Stepper.h>
    #include <SoftwareSerial.h>

    RTC_DS1307 rtc;

    Stepper myStepper(200 , 9 , 10 , 11 , 12);

    void setup() {
      Serial.begin(9600);
      rtc.adjust(DateTime(2021 , 7 , 14 , 4 , 44 , 0));
      myStepper.setSpeed(20);
    }

    void loop() {

      DateTime now = rtc.now();

      if ((now.hour() == 4 and now.minute() == 45) or (now.hour() == 6 and now.minute() == 45)) {
          Serial.println("testing");
          myStepper.step(10000);
          delay(1000);

    }

    }

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

title: Arduino Motor Control at a Specific Time

Answers: 2

body: You are pushing the limit of the L298N, probably will exceed it. A typical stepper motor like a NEMA 17 is probably rated at voltage of about 2.8 Volts and a maximum current of 1.68 Amps. This basically means if you hook it up to 2.8 Volts it will draw 1.68 Amps. If you try to run it at a higher voltage it will draw more current and get excessively hot. Driver Model: L298N has a Motor Supply Current (Maximum): 2A, Logic Voltage: 5V, Driver Voltage: 5-35V. The motor was rated at about 2.8V, powering it with more will very quickly exceed your bridge capacity. The Arduino will give you 5V and 3.3V but using either to power your motor will probably destroy the Arduino. The Arduino a power supply it is NOT! I suggest you use a seperate power supply for the motor. If you power the Arduino via Vin and use a buck converter from the 12V it should work fine.

body: I’m new at this but looks to me like your rtc is uses i2c comms.  I don’t see that you’ve included wire.h or issued the wire.begin to initiate communication between the rtc and arduino.  See other rtc examples and good luck!


body:
I am trying to write four values relating to energy (current, power, energy, and peak demand) via a SoftwareSerial connection from my Arduino UNO to my Raspberry Pi 4.  However, two things are occurring:

1.  All of the values should be different, but they are printing to the RPi terminal as if they're identical.

2.  It seems as if the values I'm writing are merging together(?), creating a nonsense value.  For example, if the values that I'm sending are 0.24, 28, 0.05, and 71, they appear in the RPI terminal looking like this:

Current:  54543878

Power:  54543878

Energy:  54543878

Peak Power:  54543878

This is a snip of my Arduino code that writes to the Bluetooth serial connection (uses HC-06):

      bluetoothSerial.write(RMSCurrent);
      bluetoothSerial.write(RMSPower);
      bluetoothSerial.write(kilos);
      bluetoothSerial.write(peakPower);

This is a snip of the Python script that receives it:

    while 1:
 try:
  received_data = bluetoothSocket.recv(1024)
  RMSCurrent = int.from_bytes(received_data,byteorder='big')
  RMSPower = int.from_bytes(received_data,byteorder='big')
  kilos = int.from_bytes(received_data,byteorder='big')
  peakPower = int.from_bytes(received_data,byteorder='big')

  print("Current (A): %d" % RMSCurrent)
  print("Power (W): %d" % RMSPower)
  print("Energy (kWh): %d" % kilos)
  print("Peak Demand: %d" % peakPower)

 except KeyboardInterrupt:
  print("keyboard interrupt detected")
  break
    bluetoothSocket.close()

Does anyone have any ideas of what is going on?  Two of my values are floats and two are integers.  I've tried to fix this for the past 12 hours, but to no avail.

title: Incorrect values arriving from Arduino to RPi over serial communication

Answers: 1

body:
You will save yourself a lot of headaches by sending the data in ASCII
instead of binary:

```c++
bluetoothSerial.print("RMSCurrent: ");
bluetoothSerial.println(RMSCurrent);
```

Of course, you will then have to _parse_ the data stream on the Python
side.

If you really want to send binary data, then be aware that the `write()`
method you are using is intended for sending single bytes. Every number
you `write()` is converted to an integer (truncated if it's a float),
reduced modulo 256 to the range [0, 255], then sent as a single
byte. You can loose quite a bit of information in this process.

To send a binary object larger than a byte, you have to use an overload
of `write()` that takes both a pointer (the address of the object) and a
number of bytes to send. For example:

```c++
bluetoothSerial.write((uint8_t *) &RMSCurrent, sizeof RMSCurrent);
```

But then, you have to be aware that some numeric types do not have the
same binary representation on the Arduino and on the Pi. For instance:

* an `int` is 2 bytes on the Arduino and 4 bytes on the Pi
* a `double` is 4 bytes on the Arduino and 8 bytes on the Pi

I recommend you only use fixed-size integer types (`uint16_t` and such)
and `float`.

Also, be aware that the Arduino is little-endian, like the Pi, and
unlike what your Python code currently assumes.

Oh, and the serial link does not have a notion of data packets. If there
happens to be some leftover crap in the serial buffer when you start
your Python program, it will get out of sync with the Arduino, and you
will only read garbage. There are ways around this problem (search for
“packet framing”) but they add quite a bit of complexity.

As I said, you will save yourself a lot of headaches by sending the data
in ASCII instead of binary.


body:
Good afternoon! This question is still relevant to me. I use the receiver module in conjunction with arduino. I want to use my own transfer protocol and now I need to accept it. I tried to use various libraries, but all without success. I need to somehow select a sequence of pulses and then determine their values (zero or one) by the duration of the pulses.
But first, I need to determine the beginning of the signal from the preamble (12 pulses at the beginning). I wrote a program that draws a graph where you can see the entire sequence.
Is it possible to define this preamble without using libraries, for example, to make a cycle that will measure the length of the pulses, and there are 12 times the duration of the pulses will be the same, then this is the preamble, followed by digital data.

    #define IN_PIN 2
    void setup()
    {
      Serial.begin(115200);
    }

    void loop()
    {
      bool s = digitalRead(IN_PIN);
      Serial.println(s);
    }

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

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

  [1]: https://i.stack.imgur.com/1TWvp.jpg
  [2]: https://i.stack.imgur.com/BNVAu.png

title: Decoding of data received using the WL-101 433 MHz radio module

Answers: 1

body:
It is not working because of:

**SPEED**

Consider the frequency of the 433Mhz device vs. the speed of the serial monitor. The device sends signals with pulse width in the range of tens of microseconds while the serial monitor can't display that fast.

Your code should analyze the signals, clean the noise (the output of the device is very noisy) and figure out the protocol. All that is done by dedicated libraries such as [rc-switch][1] which is very extensive and robust compared to just reading a pin and plotting the output.

**DIGITAL**

The recover device is outputting a digital pulse which based on it's pulse width changes one can figure out the sequence of numbers sent by the remote control. Each such ASK protocol has it's timing characteristics which you should follow in order to decode the code.

If you want to experiment with that vs. using a ready made library you should start with a code similar to the example below.

    void setup() {
      Serial.begin(6000000);
      attachInterrupt(digitalPinToInterrupt(1), handleInterrupt, CHANGE);
    }

    void loop() {
    }

    void handleInterrupt() {
      bool s = digitalRead(1);
      Serial.println(s);
    }

Just pay attention to the timing issue, this code will show a lot of data but not necessarily (almost for sure) not all the data, but you can avoid the serial print and use the data for analysis.

  [1]: https://github.com/sui77/rc-switch


body:
I am trying to send AT commands to esp-01 through serial monitor I have uploaded a blank sketch to Arduino , whatever command I send to ESP I get reply ERROR.
After reconnecting esp-01 I got some garbage vales then ready.
Can anyone help me what I am doing wrong.
This is what I got on serial monitor
 [![this is what I am getting on serial monitor][1]][1]

These are the connections I am using, I tried to use voltage divider but after using voltage divider, Esp's blue led turned on and nothing happened so I used just used the resistors in series between TX and TX of both devices

[![CONNECTIONS ][2]][2]

This is the voltage divider circuit I was using(that didn't worked)

[![voltage divider circuit][3]][3]

  [1]: https://i.stack.imgur.com/rI64i.png
  [2]: https://i.stack.imgur.com/rmqRk.png
  [3]: https://i.stack.imgur.com/h81d9.png

title: Arduino Uno Esp8266 AT commands

Answers: 1

body:
The hardware serial, pins 1 and 2, are used by the Arduino to communicate to the USB adapter to your computer.  When you connect another device to them, it interferes with the communication between your computer and the Arduino.

The solution is to connect the ESP-01 to another set of pins and use the `SoftwareSerial` library to create a second serial port for it.  The code then needs to listen on both serial ports and move data between them.

Also, you need to use the voltage divider or you risk burning out the input pin.  To make the voltage divider, connect the Arduino output to the top of the divider and the ESP-01 to the middle.  You appear to have those reversed in your schematic.


body:
This is my first time using EMG Sensor.
I'm trying to read EMG signals from Myoware Muscle Sensor.
When I use analogRead to read analog value, the value is almost same. There is not much change in the analog value.

EMG Sensor I'm using: Myoware Muscle sensor from Advancer Technologies.
Arduino Board: Arduino Mega.

When Sensor is turned ON, the Signal LED (Red LED) on the emg sensor is always ON. (I don't know if it is supposed to be always ON or not )
I have tried placing emg sensor on both forearm and biceps, but no change in the analog value.
I really dont know what is wrong here.

This is the code:

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

    void loop() {
      int sensorValue = analogRead(A5);
      //float millivolt = (sensorValue/1023)*5;

      Serial.print("Sensor Value: ");
      Serial.println(sensorValue);
      delay(1);
    }

[![Circuit][1]][1]

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

title: Not getting any signal from myoware EMG muscle sensor. The signal LED (Red LED) on the sensor is always ON

Answers: 0


body:
**************************1st code*********************

```cpp
int sensoroutput = 3; // the analog pin connected to the sensor
int sensorinput = A0;
int THRESHOLD = 100;

void setup()
{
 pinMode(3, OUTPUT);
 pinMode(A0, INPUT);   // this function is used to declare gsm connected pin as output
}

void loop()
{
 int value = analogRead(sensorinput);  // function to read analog voltage from sensor
 if (value >= THRESHOLD)                    // function to check voltage level from sensor
 {
  digitalWrite(3, HIGH);
  delay(100);
 }
 else
  digitalWrite(3, LOW);
}
```

*********2nd code*************

```cpp
#include <SoftwareSerial.h>

SoftwareSerial sim800l(0, 1); // RX,TX for Arduino and for the module it's TXD RXD, they should be inverted

#define button1 7 //Button pin, on the other pin it's wired with GND

bool button_State; //Button state

void setup()
{
 pinMode(button1, INPUT_PULLUP); //The button is always on HIGH level, when pressed it goes LOW
 sim800l.begin(9600);   //Module baude rate, this is on max, it depends on the version
 Serial.begin(9600);
 delay(1000);
}

void loop()
{
 button_State = digitalRead(button1);   //We are constantly reading the button State

 if (button_State == LOW) {            //And if it's pressed
  Serial.println("Button pressed");   //Shows this message on the serial monitor
  delay(200);                         //Small delay to avoid detecting the button press many times

  SendSMS();                          //And this function is called
 }

 if (sim800l.available()) {            //Displays on the serial monitor if there's a communication from the module
  Serial.write(sim800l.read());
 }
}

void SendSMS()
{
 Serial.println("Sending SMS...");               //Show this message on serial monitor
 sim800l.print("AT+CMGF=1\r");                   //Set the module to SMS mode
 delay(100);
 sim800l.print("AT+CMGS=\"+918707578617\"\r");  //Your phone number don't forget to include your country code, example +212123456789"
 delay(500);
 sim800l.print("SIM800l is working");       //This is the text to send to the phone number, don't make it too long or you have to modify the SoftwareSerial buffer
 delay(500);
 sim800l.print((char)26);// (required according to the datasheet)
 delay(500);
 sim800l.println();
 Serial.println("Text Sent.");
 delay(500);

}
```

title: i want to combine below two codes

Answers: 0


body:
I'm just curious as to why there are no brackets at the end of the ISR when attaching and assigning the interrupt command?

```
 attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
 ...
 void blink() {
    state = !state;
 }
```

In, attachInterrupt, I would have expected "blink" to be written as "blink()", with the brackets, not just the name of the function, sort of like how you would normally call the function blink() from your loop or setup functions (or elsewhere). So, what's going on here, and are there other scenarios where you might use a function without the brackets after it?

title: Why no brackets after Interrupt routine inside attachInterrupt

Answers: 1

body:
It is right, that you are putting brackets after the function name if you are **calling it**. But with `attachInterrupt()` you just want to give it the information, which function to call in case of an interrupt. With the brackets the compiler would think you want the function to be executed and the result/return value being given as parameter to `attachInterrupt()`. But the execution here should only happen in case of an interrupt. The `attachInterrupt()` function/the corresponding ISR need to know, what to call in case of an interrupt. Just the information/address of the function.

Maybe you have already heard of pointers. That are variables that hold the address of a different variable. They are pointing somewhere else in the memory. `blink` (without the brackets) is basically a function pointer. Leaving the brackets away tells the compiler, that you want the address of the function, not executing it. You are providing the function parameter by reference this way, providing the address, not the value.

If you like/need you can use that principle yourself by defining your own function pointer variable. For example this

    void (*myCallbackFunction)(int);

which is a function, that takes an int as parameter and returns nothing (void). You can then set the function pointer and call it as a normal function

    void blinkXTimes(int times){
        for(int i=0;i<times;i++){
            digitalWrite(pin, HIGH);
            delay(500);
            digitalWrite(pin, LOW);
            delay(500);
        }
    }

    void setup(){
        pinMode(pin, OUTPUT);
        myCallbackFunction = blinkXTimes;

    void loop(){
        myCallbackFunction(3);
        delay(5000);
    }

We are calling `myCallbackFunction()`, but it is a function pointer, that points to `blinkXTimes()`, so that will be executed.

> So, what's going on here, and are there other scenarios where you might use a function without the brackets after it?

The above principle is super useful for writing libraries with user callback functions. Another example (besides `attachInterrupt()`) is the `Wire` library. There the receive and request interrupts need to interact with the library user to deliver to or request data from him. For this the `Wire` library lets you set your own callback functions. Refer to the examples of that library.

Another application would be building a Finite State Machine with a function pointer (basically calling different functions on each loop iteration depending on the state, which is represented by the function pointer).

That are the two big application I know of. The first one is more common. Though function pointers are just a tool. They can be used for many things.


body:
I am very new to electronics (software engineer background).

I want to send an analog signal (5V) to one/many input wires. The input wires are connected to a 16 channel mutiplexer.
My arduino then reads all of the 16 channels.

Right now the issue is: If I connect only one pin to the 5V output of the arduino many other of the multiplexer input pins also read high voltage values even tho only one pin is actually connected.

I am pretty sure this issue is a duplicate - please point me to the right direction.

I have read about decoupling (if that is the case - please explain it for newbies without background).

title: Arduino Multiplexer Input voltage per pin not decoupled

Answers: 1

body:
As I understand it you have a multiplexer with one of the inputs connected to 5 volts and the rest are open. What you are reading is leakage in the IC and associated wiring. There are many reasons they tell us not to leave inputs open, you just found one. This is especially problematic with CMOS devices because of there extremely high impedance. The first thing the TI publication
SCBA004D–July 1994–Revised September 2016 tells you is power consumption is
becoming a major issue in today’s market. However, when designing systems using CMOS and BiCMOS devices, one must understand the characteristics of these families and the way inputs and outputs behave in systems. It is very important for the designer to follow all rules and restrictions that the manufacturer requires, as well as to design within the data-sheet specifications. Because data sheets do not cover the input behavior of a device in detail, this application report explains the input characteristics of CMOS and BiCMOS families in general. It also explains ways to deal with issues when designing with families in which floating inputs are a concern. Understanding the behavior of these inputs results in more robust
designs and better reliability.


body:
I am new to Arduino and I have ran into an issue. When I first tried to plug the arduino nano (after market, from ebay) into my computer (Macbook pro M1), nothing happened. Then I downloaded the cp210xVCP Driver. After that, when I plugged in the nano, the /dev/cu.usbserial- 1110 appeared. But when I try to get board info noting happens. It's like the computer recognize there is something, but does not know what. I believe Arduino is not fully compatible for M1 macbooks, but is there something I can do to fix this?

[![ fi][1]][1]

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

title: Arduino Nano not recognized by Mabook Pro M1

Answers: 1

body:
Majenko and Python Schlange have the right of it I think. This is a common and well documented phenomenon. Check out [the comments](https://forum.arduino.cc/t/unable-to-find-board-information-on-new-arduino-nano/525184) on the Arduino forum by the arduino team which explain PIDS and VIDS on USB equipment and why the clones appear differently. It shouldn’t (all going according to plan) make a difference other than the board information not being present as you’ve noted. That’s why Majenko is suggesting you go ahead and upload a sketch. The [Blink][1] example sketch is frequently used for this as a first board test when you receive something new.

See also https://arduino.stackexchange.com/questions/80794/usb-ft232-driver-on-m1-mini/80795#80795 for more information about checking USB ports on the Mac.

  [1]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/Blink


body:
I'm trying to receive a string from an Arduino to a Raspberry Pi via a Bluetooth socket connection (RFCOMM).  I'm using an HC-06 Bluetooth module, an Arduino UNO R3, and an RPi 4 Model B.  For the most part, everything is working well --except the first two data samples.  This is what my output generally looks like when I view it from the RPi terminal:

    0.
    06,21,0.01,64
    0.06,21,0.01,64
    0.06,21,0.01,64
    0.06,21,0.01,64
    0.06,21,0.01,64
    0.06,21,0.01,64

Is there any way I can get the first two lines to show the data properly?  This data is a singular string and I chose my buffer to be 32 bits, so I don't think buffer size is the issue.  I had to add time.delay(4) in my Py script or else every sample of the data would look messed up.  I've tried adjusting the time delay relentlessly, but I can't seem to get the first two samples to display correctly.  Below is a bit of my Python code:

    while 1:
    try:
            received_data = bluetoothSocket.recv(24)
            formatted_data = received_data.decode("utf-8")
            print("Received Data: ", formatted_data)
            time.sleep(4)

    except KeyboardInterrupt:
            print("keyboard interrupt detected")
            break
    bluetoothSocket.close()

title: Problem with first two samples of serial data received by RPi

Answers: 2

body:
You might want to try sending the data in a packet delimited by unique characters, e.g. `{` and `}`, similar to the [JSON format][1].

The [NMEA GPS][2] standard uses `$` and '\n' to delimit messages.

Here is an Arduino non-blocking C++ algorithm which builds upon [Majenko's `readline()` example][3] to read a packet. It returns true when incoming data has been accumulated into a valid packet. It should be fairly straightforward to convert it to Python.

```cpp
void setup()
{
 Serial.begin(115200);
 Serial.println(F("\n\nSerial Packet Test\n"));
 pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
 const static unsigned int INTERVAL = 200;
 static unsigned long previous_timestamp = millis();
 unsigned long current_timestamp = millis();
 static bool led_state = false;

 if (current_timestamp - previous_timestamp >= INTERVAL)
 {
  led_state = !led_state;
  digitalWrite(LED_BUILTIN, led_state);
  previous_timestamp += INTERVAL;
 }

 static char packet[100];

 if (ReadPacket(Serial, packet, sizeof(packet)))
 {
  Serial.print(F("Received packet >"));
  Serial.print(packet);
  Serial.println(F("<"));
 }
}

bool ReadPacket(Stream& stream, char *const packet, const unsigned int SIZE)
{
 const char FIRST = '{';
 const char LAST = '}';
 static bool read_until_last = false;
 static unsigned int i = 0;
 char ch;

 if (stream.available())
 {
  ch = stream.read();

  if (ch == FIRST)
  {
   Serial.println(F("Received FIRST."));
   i = 0;
   packet[0] = ch;
   read_until_last = true;
   return false;
  }
  if (read_until_last)
  {
   i++;
   if (i > SIZE - 2)
   {
    Serial.println(F("Buffer overrun. Resetting to look for next packet."));
    i = 0;
    read_until_last = false;
    return false;
   }
   if (ch == LAST)
   {
    Serial.println(F("Received LAST."));
    packet[i++] = ch;
    packet[i] = 0;
    read_until_last = false;
    return true;
   }
   else
   {
    Serial.print(F("Received char >"));
    Serial.print(ch);
    Serial.println("<");
    packet[i] = ch;
    return false;
   }
  }
 }
 return false;
}
```

  [1]: https://en.wikipedia.org/wiki/JSON
  [2]: https://www.gpsworld.com/what-exactly-is-gps-nmea-data/
  [3]: https://majenko.co.uk/blog/reading-serial-arduino

body: I don't know what the `time.sleep(4)` statement fixes, but you could try moving the  to the top of the loop instead of the bottom, so it precedes the first read. At the bottom of the loop, it's first execution comes *after* the first read.


body:
I have an Arduino Nano, and a local Java WebSocket server (ws://localhost:8888) run by a .jar file on my computer.

I'm wondering if it's possible to send data (text, numbers etc.) from the Arduino Nano to the WebSocket server via USB cable (USB-A to USB Mini, one that normally powers the Nano).

If so, what do I need to do it?

A quick Google for WebSocket Arduino libraries reveals:

[Websockets][1] and [Arduino Websocket Fast][2], but looking at the examples, the former uses Ethernet.h and the latter uses Wifi.h, and I'm unsure if my board is compatible with that without other modules.

  [1]: https://www.arduino.cc/reference/en/libraries/websockets/
  [2]: https://www.arduino.cc/reference/en/libraries/arduino-websocket-fast/

title: Can I pass data from an Arduino Nano to a Websocket Server via USB?

Answers: 3

body: No, you can't. The Arduino has a serial connection, not a network connection. If the Java program is of your own devising you would need to rewrite it to use serial instead of (or as well as) WebSockets. Either that or write a separate piece of software for your computer to go between the Arduino's serial connection and the WebSockets interface.

body:
As @Majenko already said the ATmega328 uses a serial connection to communicate. Another chip on the board translates the serial data to USB-Format and the other way around. This enables your computer to interact with the main chip on the Nano (ATmega328).
To solve your problem you might try using something like [this](https://github.com/RandomStudio/serial-to-websocket) simple serial-to-websocket node-server that listenes to data coming in from a serial port and sends it out over WebSocket.

body: I ended up using Python to bridge Serial to WebSocket. I wanted flexibility in sending from WebSocket back to Serial too, so I didn't try a prepackaged solution like https://github.com/RandomStudio/serial-to-websocket


body:
I have a Arduino Nano clone working fine with the CH340 drivers. It has a CH340C on it.

I made a custom PCB. CH340 chips are hard to come by these days, so I opted for the CH340K, From the datasheet, seems like it should work similar to the CH340C and CH340G that are quite common.

My PCB has a footprint for both the CH340K and CH340C/CH340G (Yes, I'm aware I'm missing the load capacitors for the CH340G). CH340C/N/K/E and CH340B have built-in clocks without external crystal oscillator. So no need for a crystal.

After soldering on the CH340K and USB port, I plugged the device in, and I'm getting an error in Windows 10 Device Manager:

> Unknown USB Device (Device Descriptor Request failed)
>
> Windows has stopped this device because it has reported problems.
> (Code 43)
>
> The USB set address request failed.

I've uninstalled and reinstalled the CH340 drivers several times. Tried to force the driver onto the device in device manager, and it didn't let me.

There's no short to ground or vcc.

Any help to get this recognized would be great! thanks!

**CH340K Pinout**

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

**PCB**

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

  [1]: https://i.stack.imgur.com/7YnCt.png
  [2]: https://i.stack.imgur.com/uzARR.jpg

title: CH340K - Unknown USB Device (Device Descriptor Request failed)

Answers: 2

body:
Needed a 100nf capacitor on the v3 pin, per Majenko's suggestion, and per datasheet.

I thought this was only needed if you were going to use the 3.3v output for other purposes. I was wrong!

Same requirement for the CH340C!

body:
on you Pcb the Footprint is not correct!
UD+ is on GND, UD- is on UD+ and GND is on UD- . The CH340K has a differnt Footprint.


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

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

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

  [1]: https://i.stack.imgur.com/wkaBo.jpg
  [2]: https://i.stack.imgur.com/064VT.jpg
  [3]: https://i.stack.imgur.com/EdLPt.jpg

Hi,am trying to communicate with power-factor controller [Selec APFC 148-312] using modbus RTU,am following example sketch from modbusmaster library. am able to get the raw data from the instrument but data structure seems to be in decimal format, can someone help me to convert this into float.thank you

    #include <ModbusMaster.h>

    #define MAX485_DE      3
    #define MAX485_RE_NEG  2

    // instantiate ModbusMaster object
    ModbusMaster node;

    void preTransmission()
    {
      digitalWrite(MAX485_RE_NEG, 1);
      digitalWrite(MAX485_DE, 1);
    }

    void postTransmission()
    {
      digitalWrite(MAX485_RE_NEG, 0);
      digitalWrite(MAX485_DE, 0);
    }

    void setup()
    {
      pinMode(MAX485_RE_NEG, OUTPUT);
      pinMode(MAX485_DE, OUTPUT);
      // Init in receive mode

      digitalWrite(MAX485_RE_NEG, 0);
      digitalWrite(MAX485_DE, 0);

      // Modbus communication runs at 9600 baud
      Serial.begin(9600);

      // Modbus slave ID 1
      node.begin(1, Serial);
      // Callbacks allow us to configure the RS485 transceiver correctly
      node.preTransmission(preTransmission);
      node.postTransmission(postTransmission);
    }

    void loop()
    {
      float result;

      result = node.readInputRegisters(0x30000, 10);
      if (result == node.ku8MBSuccess)
      {

        Serial.print("V1N: ");
        Serial.println(node.getResponseBuffer(0x01));

        Serial.print("V2N: ");
        Serial.println(node.getResponseBuffer(0x02));

        Serial.print("V3N: ");
        Serial.println(node.getResponseBuffer(0x03));

        Serial.print("Vavg: ");
        Serial.println(node.getResponseBuffer(0x04));

        Serial.print("V12: ");
        Serial.println(node.getResponseBuffer(0x05));

        Serial.print("V23: ");
        Serial.println(node.getResponseBuffer(0x06));

        Serial.print("V31: ");
        Serial.println(node.getResponseBuffer(0x07));

        Serial.print("L-L avg: ");
        Serial.println(node.getResponseBuffer(0x08));
      }
      delay(1000);
    }

title: Modbus rtu data decimal to float conversion

Answers: 1

body:
I'm not sure this can really be considered topical, but someone wanting to read floating point numbers over MODBUS with an Arduino might get something out of it.  Also I have no way to test this really.  But here goes:

Your MODBUS map shows V2N at 30002, and you notice 30003 is not mentioned in the map.  Your voltage from phase two to neutral appears to be encoded into two consecutive 16-bit registers, which is a somewhat normal scheme for conveying 32bit floats via MODBUS, from what I can tell.  So, your values of `17280` and `9830` are two halves of a 32-bit floating point number.  In hex, 0x4380 and 0x2666.  These seem to be taken together as 0x43802666 as the bit pattern for 32-bit float.

A function like this would allow you to extract your 32-bit float data from your separate 16-bit MODBUS register reads:

```c++
float modbus_16bit_register_pair_to_float(uint16_t a, uint16_t b) {
    uint32_t combined = ((uint32_t)a << 16) | b;
    float f;
    memcpy(&f, &combined, sizeof f);
    return f;
}
```

There are lots of ways you could do this.  This code assumes that the `float` type's endian matches the `uint32_t` type's endian, and that `float` is 32-bit, which is common but not strictly standard.

Running this on `17280` and `9830` gives 256.3 (rounded), which doesn't perfectly match other output, but I suspect that's just because the reading is varying.


body:
I am making an IR controlled helicopter and I have the very basic part of the code done, but I don't know how to make the motor gradually increase speed. I want the motor to gradually increase speed when you hold the button on the IR remote and hold its speed when you stop pushing the button. And the same for when the helicopter goes down.
Here is the code:

       #include <IRremote.h>
       #include <Servo.h>
       #define enA 9
       #define enB 11
       #define in1 6
       #define in2 7
       #define in3 4
       #define in4 5

       Servo ball1;

       int IR_RECEIVE_PIN = 2;
       IRrecv IrReceiver(IR_RECEIVE_PIN);
       decode_results results;

       void setup() {
         Serial.begin(9600);
         IrReceiver.enableIRIn();

         ball1.attach(10);

         pinMode(in1, OUTPUT);
         pinMode(in2, OUTPUT);
         pinMode(in3, OUTPUT);
         pinMode(in4, OUTPUT);
       }
       void loop() {
         if (IrReceiver.decode(&results)) {
           switch (results.value) {

             case 0xFFA857:
               Serial.println("case: UP");
               digitalWrite(enA, 255);
               digitalWrite(in1, HIGH);
               digitalWrite(in2, LOW);
               break;

             case 0xFFE01F:
               Serial.println("case: DOWN");
               digitalWrite(enA, 120);
               digitalWrite(in1, LOW);
               digitalWrite(in2, LOW);
               break;

             case 0xFF18E7:
               Serial.println("case: FORWARD");
               ball1.write(90);
               break;

             case 0xFF10EF:
               Serial.println("case: LEFT");
               digitalWrite(in3, LOW);
               digitalWrite(in4, LOW);
               break;

             case 0xFF5AA5:
               Serial.println("case: RIGHT");
               digitalWrite(in3, HIGH);
               digitalWrite(in4, LOW);
               break;

             case 0xFF48B5:
               Serial.println("case: BACKWARD");
               ball1.write( ? ); // I need help on the direction of the linear servo
               break;
           }

           Serial.println(results.value, HEX);
           IrReceiver.resume();
         }
       }

It is the same code I used to control a RGB LED (But modified). Would it be possible to upload this code to an IC? I already programmed my UNO as an ISP, but there seems to be a problem. Also, I am using a linear servo for the pitch of the helicopter, can someone please show me how to change the direction of a linear servo? I have one that is similar to the Pico linear servo.

title: How to gradually increase and decrease the speed of a motor using IR remote

Answers: 1

body:
You could separate reading the controls and taking actions and there are several ways of doing that, one example shown below where the switch() can be used to read all commands and according to the value call one or more atomic functions. For instance, one function to change speed and another one to change direction, and perhaps calling several functions in a row for more complex tasks like take off and land (I have no idea how those helicopter projects works).

On each case you do the validation, min and max allowed values, dependencies on other factors and alike.

    void loop() {

      if (IrReceiver.decode(&results)) {

        switch (results.value) {

          case 0xFFA857: // up
            verticalSpeed = verticalSpeed + verticalSpeedStep;
            if (verticalSpeed > maxVerticalSpeed) verticalSpeed = maxVerticalSpeed;
            setVericalMotor();
            break;

          case 0xFFE01F: //down
            verticalSpeed = verticalSpeed - verticalSpeedStep;
            if (verticalSpeed < 0) verticalSpeed = 0;
            setVericalMotor();
            break;

        }
      }
    }

    void setVericalMotor() {
      digitalWrite(in1, HIGH);
      digitalWrite(in2, LOW);
      digitalWrite(enA, verticalSpeed);
    }

As for your question regarding the servo, they usually run from 0 to 180 degrees, so tey anything in that range as the "reverse" for 90 degrees for Forward (normally that should be 0 or 180).


body:
I have created a ThingHTTP below:

    https://api.thingspeak.com/apps/thinghttp/send_request?api_key=BVLJ7A6KNK9VVAYK
In my browser I could see the reply. But I am unable to make this work in my ESP32. I understand that this is a https so I would have to declare the root cert details. I have tried to modify based on this tutorial:

    https://github.com/witnessmenow/arduino-sample-api-request/blob/master/ESP8266/HTTP_GET/HTTP_GET.ino

My code as follows:

    #include <WiFi.h>
    #include <WiFiClientSecure.h>

    //------- Replace the following! ------
    char ssid[] = "SSID";       // your network SSID (name)
    char password[] = "pass";  // your network key

    // For Non-HTTPS requests
    // WiFiClient client;

    // For HTTPS requests
    WiFiClientSecure client;

    // Just the base of the URL you want to connect to
    #define TEST_HOST "https://api.thingspeak.com/apps/thinghttp/send_request?api_key=BVLJ7A6KNK9VVAYK"

    const char *server_cert = "-----BEGIN CERTIFICATE-----\n"
                                      "MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\n"
                                      "RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\n"
                                      "VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\n"
                                      "DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\n"
                                      "ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\n"
                                      "VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\n"
                                      "mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\n"
                                      "IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\n"
                                      "mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\n"
                                      "XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\n"
                                      "dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\n"
                                      "jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\n"
                                      "BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\n"
                                      "DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\n"
                                      "9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\n"
                                      "jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\n"
                                      "Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\n"
                                      "ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\n"
                                      "R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n"
                                      "-----END CERTIFICATE-----\n";

    void setup() {

      Serial.begin(115200);

      // Connect to the WiFI
      WiFi.mode(WIFI_STA);
      WiFi.begin(ssid, password);
      Serial.println("");

      // Wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
      }
      Serial.println("");
      Serial.print("Connected to ");
      Serial.println(ssid);
      Serial.print("IP address: ");
      Serial.println(WiFi.localIP());

      //--------

      // Checking the cert is the best way on an ESP32
      // This will verify the server is trusted.
      client.setCACert(server_cert);

      // If you don't want to verify the server
      // Unlike the fingerprint method of the ESP8266 which expires frequently
      // the cert lasts years, so I don't see much reason to ever
      // use this on the ESP32
      // client.setInsecure();

      makeHTTPRequest();
    }

    void makeHTTPRequest() {
      delay(5000);
      // Opening connection to server (Use 80 as port if HTTP)
      if (!client.connect(TEST_HOST, 443))
      {
        Serial.println(F("Connection failed"));
        return;
      }

      // give the esp a breather
      yield();
      client.connect(TEST_HOST, 443);
      // Send HTTP request
      client.print(F("GET "));
      // This is the second half of a request (everything that comes after the base URL)
      client.print(""); // , == ,
      client.println(F(" HTTP/1.1"));

      //Headers
      client.print(F("Host: "));
      client.println(TEST_HOST);

      client.println(F("Cache-Control: no-cache"));

      if (client.println() == 0)
      {
        Serial.println(F("Failed to send request"));
        return;
      }
      //delay(100);
      // Check HTTP status
      char status[32] = {0};
      client.readBytesUntil('\r', status, sizeof(status));
      if (strcmp(status, "HTTP/1.1 200 OK") != 0)
      {
        Serial.print(F("Unexpected response: "));
        Serial.println(status);
        return;
      }

      // Skip HTTP headers
      char endOfHeaders[] = "\r\n\r\n";
      if (!client.find(endOfHeaders))
      {
        Serial.println(F("Invalid response"));
        return;
      }

      // This is probably not needed for most, but I had issues
      // with the Tindie api where sometimes there were random
      // characters coming back before the body of the response.
      // This will cause no hard to leave it in
      // peek() will look at the character, but not take it off the queue
      while (client.available() && client.peek() != '{')
      {
        char c = 0;
        client.readBytes(&c, 1);
        Serial.print(c);
        Serial.println("BAD");
      }

      // While the client is still availble read each
      // byte and print to the serial monitor
      while (client.available()) {
        char c = 0;
        client.readBytes(&c, 1);
        Serial.print(c);
      }
    }

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

    }

the program was able to compile, and was able to run until it shows it connect to the network. But then it returned "Connection failed!" I believe it stuck at this line :

    if (!client.connect(TEST_HOST, 443))

I am not sure what is the problem here. Comments appreciated.

title: ESP 32 unable to connect to https website and return the data using GET

Answers: 2

body:
Things wrong with your GET request (which are nothing to do with Arduino - just learn the basics of the protocol you are trying to use *before* you use it):

* You are trying to open a socket to a URL not to a server. That can never work. Connect to the server instead (hint: the server, or "FQDN", is the bit between the `https://` and the next `/`).
* You aren't providing any path in your `GET` request, only a comment that says what you should provide.  Hint: the path is everything that comes after (and including) the `/` following the FQDN.
* Your `Host:` header should contain just the FQDN, not the whole URL. By now you should know what the FQDN is.
* You should also include `Connection: close` in your headers to inform the server you won't be keeping the socket open.

Correct those problems and you might begin to see something useful happening.

body:
The piece of code below is from a firmware code I've been programming lately to use on Tensilica's Xtensa LX6/7 compatible MCUs (ESP32). The code below makes an HTTPS request using WIFIClientsecure library.

    String GetInfoFromDataverse(String url) {
      //Check WiFi connection status

      if(WiFi.status() != WL_CONNECTED){
        mserial.printStrln("WiFi Disconnected");
        if (connect2WIFInetowrk()){
          GetInfoFromDataverse(url);
        }
      }

      int str_len = SERVER_URL.length() + 1; // Length (with one extra character for the null terminator)
      char SERVER_URL_char [str_len];    // Prepare the character array (the buffer)
      SERVER_URL.toCharArray(SERVER_URL_char, str_len);    // Copy it over

      client.stop();
      client.setCACert(HARVARD_ROOT_CA_RSA_SHA1);

      if (!client.connect(SERVER_URL_char, SERVER_PORT)) {
          mserial.printStrln("Cloud server URL connection FAILED!");
          mserial.printStrln(SERVER_URL_char);
          int server_status = client.connected();
          mserial.printStrln("Server status code: " + String(server_status));
          return "";
      }

      mserial.printStrln("Connected to the dataverse of Harvard University");
      mserial.printStrln("");

      // We now create a URI for the request
      mserial.printStr("Requesting URL: ");
      mserial.printStrln(url);

      // Make a HTTP request and add HTTP headers
      // post header
      String postHeader = "GET https://" + SERVER_URL + url + " HTTP/1.1\r\n";
      postHeader += "Host: " + SERVER_URL + ":" + String(SERVER_PORT) + "\r\n";
      //postHeader += "X-Dataverse-key: " + API_TOKEN + "\r\n";
      postHeader += "Content-Type: text/json\r\n";
      postHeader += "Accept: text/html,application/xhtml+xml,application/xml,application/json,text/json;q=0.9,*/*;q=0.8\r\n";
      postHeader += "Accept-Encoding: gzip,deflate\r\n";
      postHeader += "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n";
      postHeader += "User-Agent: AeonLabs LDAD Smart DAQ device\r\n";
      postHeader += "Keep-Alive: 300\r\n";
      postHeader += "Connection: keep-alive\r\n";
      postHeader += "Accept-Language: en-us\r\n";

      // request tail
      String tail = "\r\n--" + boundary + "--\r\n\r\n";

      // content length
      int contentLength = tail.length();
      postHeader += "Content-Length: " + String(contentLength, DEC) + "\n\n";

      // send post header
      int postHeader_len=postHeader.length() + 1;
      char charBuf0[postHeader_len];
      postHeader.toCharArray(charBuf0, postHeader_len);
      client.print(charBuf0);

      mserial.printStrln("======= Headers =======");
      mserial.printStrln(charBuf0);
      mserial.printStrln("======= End of Headers =======");

      // Read all the lines of the reply from server and print them to mserial
      String responseHeaders = "";

      mserial.printStr("Waiting for server response...");
      long timeout= millis();
      long ttl=millis()-timeout;
      while (client.connected() && abs(ttl) < 30000) { // 30 sec.
        ttl=millis()-timeout;
        responseHeaders = client.readStringUntil('\n');
        if (responseHeaders == "\r") {
          break;
        }
      }
      if (abs(ttl) < 30000){
        mserial.printStrln("OK");
      }else{
        mserial.printStrln("timed out.");
      }

      String responseContent = client.readStringUntil('\n');
      client.stop();

      return responseContent;
      }


body:
I messed up when designing my PCB and just assumed that I could use software slave I2C with ATTiny84.

The reason I did so is - I needed to use all of the analog inputs.

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

The pins I have on my connector are:

PB0 (pin 2), PB1 (pin 3), PB2 (pin 5) and PA0 (pin 13)

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

Is there an alternative to I2C or a different communication protocol I could use to connect multiple of these slave boards to a master (ATMEGA328 etc.)?

Thanks a lot, I can provide any further information.

title: I am in need of a usable communication library on 1-4 pins of ATTiny84 instead of I2C

Answers: 1

body:
That is a lot of pins, so this really boils down to your application and what you want to optimize for.

You could do a bit-banged software I2C slave on these pins. "Bit-bang" means you just write a program to flip the bits on the pins rather than handing the bytes off to the hardware which would do the same thing (although sometimes faster or without using up CPU cycles). This would require either finding some existing code to implement the protocol, or sitting down with the documentation for the protocol and writing it yourself. Depending on your goals, the second option might be a great learning experience and take away some of the magic from this stuff. It is all just 1s and 0s and once you really internalize that, you realize that you can do almost anything with these little chips regardless of hardware or library support.


body:
Has anyone noticed that if calling `analogRead()` in a consecutive way that the value drops by a bit as opposed to just doing a single read?

And is this to be expected?

I am using a Seeeduino XIAO.

title: consecutive analogRead()

Answers: 1

body:
You need a short delay between analog reads due to the time it takes to complete a reliable ADC reading. In depth technical explanations can be found [here][1], note that it refers to AVR architecture.

  [1]: https://www.quora.com/Why-is-a-little-delay-needed-after-analogRead-in-Arduino


body: I have built a arduino midi octapad with a Clone of arduino nano that contain a ch340 chip but hairless midi says FTDI driver doesn't installed i installed that driver but it still show that error so can i replace the ch340 chip with a FTDI chip to resolve this Problem... ?

title: Replace CH340 With FTDI

Answers: 1

body:
When you search for "FTDI" in one of the hairless-midiserial repos on github (I looked at [this][1] and [this one][2]), you find what looks like your error message (though you didn't actually put it in your question:

    ./src/PortLatency_win32.cpp:        emit debugMessage("FTDI drivers don't seem to be installed. Not attempting any FTDI latency tricks.");

Also the repos have a class in PortLatency.h with the description:

    A simple class to manage latency reduction of FTDI-based serial ports.

This gives us some information:

- The message above is not an error message, but a debug message. It might work despite not having an FTDI
- The class description suggests, that the program wants to use some tricks to reduce the latency in the communication. These tricks seem to be FTDI specific. When the above debug message appears, these tricks are not used. Thus your performance may be significantly worse than with an FTDI chip. Also one of the repos has an [open issue][3] about problems with the CH340, which states, that it just doesn't work correctly. It was updated in May and still has no solution. I would not bet on getting help there. (Also the ground repo, that the other was forked off, wasn't updated since 5 years.)
- You cannot fix that debug message by installing the FTDI drivers, because you don't use an FTDI chip.

As we are on Arduino SE here, we cannot really help you with that program running on your PC.

Of course you can use an extra FTDI chip/board and connect it to the RX and TX lines of the Arduino (not using the CH340 USB serial chip on the Arduino itself). But I support Majenkos comment about just migrating to an Arduino with native USB connection (means the USB communication is done by the Arduinos microcontroller directly, not by an extra chip) (for example the Micro, but there are a lot more Arduinos with native USB). That enables you to manipulate the type of USB connection, thus you can let the Arduino directly appear and work as an USB midi device. Then you don't need the hairless-midiserial program anymore.

  [1]: https://github.com/rhargreaves/hairless-midiserial
  [2]: https://github.com/projectgus/hairless-midiserial
  [3]: https://github.com/projectgus/hairless-midiserial/issues/68


body:
I am programming a RaspberryPi Pico with the Arduino IDE. Works pretty well, but now I try to control an nrf24l01 module.

My code compiles but I do not know on which pins the SPI bus has to be hocked up. I tried to connect to different pins according the pinout
https://datasheets.raspberrypi.org/pico/Pico-R3-A4-Pinout.pdf
(for example 2 sck, 3 miso, 4 mosi), but nothing worked so far.

Does anybody know what the default pins are or how to control them? I also would like to control other SPI hardware, for example a display.

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

const uint64_t address = 0x1;
byte sendData[1];

#define CSN_PIN  5
#define CE_PIN   6
RF24 radio(CE_PIN, CSN_PIN);

byte counter = 0;

void setup()
{
  Serial.begin(115200);
  Serial.println(“radio starting");

  if (!radio.begin())
  {
    Serial.println("radio hardware is not responding!!");
    while (1) {}
  }
  radio.openWritingPipe(address);
}

void loop()
{
  Serial.print("Counter: ");
  Serial.println(counter);

  sendData[0] = counter;

  radio.write( sendData, sizeof(sendData));

  counter++;
}
```

title: RaspberryPi Pico SPI and nrf24l01

Answers: 1

body:
1. For Arduino-pico core

   ** MISO - pin GP16

   ** MOSI - pin GP19

   ** CS   - pin GP17

   ** SCK  - pin GP18

2. Arduino-mbed core

   ** MISO - pin GP4

   ** MOSI - pin GP3

   ** CS   - pin GP5

   ** SCK  - pin GP2


body: I am trying to implement websockets for MKR1500 and I am having trouble finding a perfect example to implement it. Can someone guide me to an example that works with MKR1500?

title: Arduino MKR NB 1500 websockets

Answers: 0


body:
*So, I've just started programming Arduino (and also in general), so I'm doing basic things, like switching on and off LED's.*

I've made them light in a sequence and then turning them off (in the same sequence), and now I wanted to use 2 buttons, one to make them do the same thing as before (light and turning LED's off in sequence) repeatedly, and the other to turn them off.

The problem is that curently they only light up once, and not repeatedly, I think I would've needed another loop, but i found out that you can't use 2 of them.

Can anyone help me? here's the code

    int LED1 = 2;
    int LED2 = 3;
    int LED3 = 4;
    int LED4 = 5;
    int LED5 = 6;
    int buttonON = 7;
    int buttonOFF = 8;

    void setup()
    {
      pinMode(LED1, OUTPUT);
      pinMode(LED2, OUTPUT);
      pinMode(LED3, OUTPUT);
      pinMode(LED4, OUTPUT);
      pinMode(LED5, OUTPUT);
      pinMode(buttonON, INPUT_PULLUP);
      pinMode(buttonOFF, INPUT_PULLUP);
    }

    void loop ()
    {
      if (digitalRead(buttonON)== LOW)
      {
        delay(300), digitalWrite(LED1, HIGH);
        delay(50), digitalWrite(LED2, HIGH);
        delay(50), digitalWrite(LED3, HIGH);
        delay(50), digitalWrite(LED4, HIGH);
        delay(50), digitalWrite(LED5, HIGH);
        delay(300), digitalWrite(LED1, LOW);
        delay(100), digitalWrite(LED2, LOW);
        delay(100), digitalWrite(LED3, LOW);
        delay(100), digitalWrite(LED4, LOW);
        delay(100), digitalWrite(LED5, LOW);
      }
     if (digitalRead(buttonOFF)== LOW)
     {
      digitalWrite(LED1, LOW);
      digitalWrite(LED2, LOW);
      digitalWrite(LED3, LOW);
      digitalWrite(LED4, LOW);
      digitalWrite(LED5, LOW);
     }
    }

P.S. if anyone has other general tips I would really apreciate them

title: How do I make another action repeat inside a loop?

Answers: 3

body:
You simply need to save the state of the LEDs in a new variable ...

    void loop ()
    {
      if (digitalRead(buttonON)== LOW)
          ledEffectON = true;

      if (digitalRead(buttonOFF)== LOW)
          ledEffectON = false;

      if(ledEffectON)
      {
        delay(300), digitalWrite(LED1, HIGH);
        delay(50), digitalWrite(LED2, HIGH);
        delay(50), digitalWrite(LED3, HIGH);
        delay(50), digitalWrite(LED4, HIGH);
        delay(50), digitalWrite(LED5, HIGH);
        delay(300), digitalWrite(LED1, LOW);
        delay(100), digitalWrite(LED2, LOW);
        delay(100), digitalWrite(LED3, LOW);
        delay(100), digitalWrite(LED4, LOW);
        delay(100), digitalWrite(LED5, LOW);
      }
    }

body:
By using `delay()` it blocks the rest of the code. The programme needs to keep track of two buttons and update the lightshow at appropriate times, therefore a non-blocking style of coding is needed similar to the [Blink Without Delay example][1] where the `delay()` is replaced with a timer using `millis()` that is checked periodically. This allows other things to be checked periodically as well, e.g. the buttons.

Also the button contacts tend to bounce several times for several milliseconds when they change state sending a train of on/off pulses to the MCU, so they need to be debounced. You can find many debouncing algorithms online, but here's a [simple debouncer][2] that I put on GitHub.

```cpp
void loop ()
{
  static bool doLightshow = false;

  static Debouncer buttonOn(buttonON);
  static Debouncer buttonOff(buttonOFF);

  buttonOn.Update();
  buttonOff.Update();

  if (buttonOn.Fall())
  {
    Serial.println("buttonOn falling edge.");
    doLightshow = true;
  }
  else if (buttonOff.Fall())
  {
    Serial.println("buttonOff falling edge.");
    doLightshow = false;
  }

  if (doLightshow)
  {
    // Do lightshow.
    . . .
  }
  else
  {
    digitalWrite(LED1, LOW);
    digitalWrite(LED2, LOW);
    digitalWrite(LED3, LOW);
    digitalWrite(LED4, LOW);
    digitalWrite(LED5, LOW);
  }
}
```

Due to the way you've neatly written your code, you can probably pick out a pattern in the lightshow.

| State | Delay time | LED pin | LED state |
| :---: | :---:      | :---:   | :---:     |
| 0     |   300      | LED1    | HIGH      |
| 1     |    50      | LED2    | HIGH      |
| 2     |    50      | LED3    | HIGH      |
| 3     |    50      | LED4    | HIGH      |
| 4     |    50      | LED5    | HIGH      |
| 5     |   300      | LED1    | LOW       |
| 6     |   100      | LED2    | LOW       |
| 7     |   100      | LED3    | LOW       |
| 8     |   100      | LED4    | LOW       |
| 9     |   100      | LED5    | LOW       |

This lends itself well to creating a Finite State Machine that can be stored in an array of structures:

```cpp
typedef struct LightshowData
{
  unsigned int delayTime;
  byte ledPin;
  bool ledState;
};

const byte numStates = 10;

const LightshowData lightshowData[numStates] =
{
  { 300, LED1, HIGH },
  {  50, LED2, HIGH },
  {  50, LED3, HIGH },
  {  50, LED4, HIGH },
  {  50, LED5, HIGH },
  { 300, LED1, LOW },
  { 100, LED2, LOW },
  { 100, LED3, LOW },
  { 100, LED4, LOW },
  { 100, LED5, LOW }
};
```

The state machine can now cycle through the array in a non-blocking manner:

```cpp
    // Do lightshow.
    static byte state = 0;
    unsigned long currentTimestamp = millis();
    static unsigned long previousTimestamp = currentTimestamp;

    if (currentTimestamp - previousTimestamp >= lightshowData[state].delayTime)
    {
      previousTimestamp += lightshowData[state].delayTime;
      digitalWrite(lightshowData[state].ledPin, lightshowData[state].ledState);
      state = ++state % numStates;
      Serial.print("state = ");
      Serial.println(state);
    }
```

You may want to reset `state` to 0 after a negative edge on `buttonOff`, otherwise the lightshow will continue where it left off after being stopped and restarted.

Here's the Wokwi simulation of the lightshow with 250 Ω protection resistors for the LEDs.

[Wokwi simulates button bounce by default][3] to more accurately model the real world, so it's advisable to have some form of button debouncing.

  [1]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay/
  [2]: https://github.com/TimMathias/Arduino-Debouncer
  [3]: https://docs.wokwi.com/parts/wokwi-pushbutton#bouncing

body:
You have written your question beautifully.
In your case, according to your logic, the button has to be kept pressed, so that the LEDs are lit in the order you desire. The single loop() function is part of the Arduino sketch but it is never a limitation.

One way to solve your problem is to make the LED drive logic independent of the button press state.

 - Once you detect the button press, store the event in one variable.
 - Let us call it `ButtonStatus`.
 - So, soon after the keypress is detected, update the `ButtonStatus` variable to TRUE.
 - Your LED drive logic can check this variable value to decide whether to drive the LEDs or not
 - Soon after you detect another press of the second button, you can update the variable value to FALSE.
Here is the Arduino simulation output for your code and the code suggested by @cat

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

below is after adapting the solution from cat
[![enter image description here][2]][2]

The simulation links are here:
[Original problem][3]
[solution 1][4]
```
int LED1 = 2;
int LED2 = 3;
int LED3 = 4;
int LED4 = 5;
int LED5 = 6;
int buttonON = 7;
int buttonOFF = 8;
int ledEffectON;
void setup()
{
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(buttonON, INPUT_PULLUP);
  pinMode(buttonOFF, INPUT_PULLUP);
}

void loop ()
{
  if (digitalRead(buttonON)== LOW)
      ledEffectON = true;

  if (digitalRead(buttonOFF)== LOW)
      ledEffectON = false;

  if(ledEffectON)
  {
    delay(300), digitalWrite(LED1, HIGH);
    delay(50), digitalWrite(LED2, HIGH);
    delay(50), digitalWrite(LED3, HIGH);
    delay(50), digitalWrite(LED4, HIGH);
    delay(50), digitalWrite(LED5, HIGH);
    delay(300), digitalWrite(LED1, LOW);
    delay(100), digitalWrite(LED2, LOW);
    delay(100), digitalWrite(LED3, LOW);
    delay(100), digitalWrite(LED4, LOW);
    delay(100), digitalWrite(LED5, LOW);
  }
}
```
Link to docs on [Pushbuttons][5]. Wokwi Arduino simulator simulates debounce by default - just like real-world switched. Debounce is a very important technique that you should consider adding to the code. To disable the "bounce" option, use the below trick!

    { "bounce": "0" }

  [1]: https://i.stack.imgur.com/DOZms.gif
  [2]: https://i.stack.imgur.com/XvLyY.gif
  [3]: https://wokwi.com/arduino/projects/304627808095699521
  [4]: https://wokwi.com/arduino/projects/304626706673566272
  [5]: https://docs.wokwi.com/parts/wokwi-pushbutton


body:
I want to know if bool variable can be null, or it must have to be true or false:

Base on Arduino description:
A bool holds one of two values, true or false. (Each bool variable occupies one byte of memory.)

title: Can bool variable be NULL

Answers: 2

body:
A bool is literally that - a boolean value. So either 1 or 0 - true or false.

In C only pointers can be NULL. Every other primitive type is a value, and NULL is not a value.

body:
A `bool` value must be either `0` or `1`, or `false` and `true` respectively. It is [*undefined behavior*](https://stackoverflow.com/questions/54120862/does-the-c-standard-allow-for-an-uninitialized-bool-to-crash-a-program) for it to be any other value. When assigning a value to a `bool`, the compiler will automatically force it to be 0 if it is already 0, or 1 if it is not.

However, as it is a full byte, it is possible to store another value. As mentioned before, however, this is undefined behavior. This means that if it ever happens, or will absolutely happen, the program can do *anything*: for example, crash the program, output random data, or act like it's truthy, falsy, or both! In fact, that *can* (again, no guarantees) happen if you store the value 2:

```cpp
#include <cstdio>

int main() {
    union b_c {
        unsigned char c;
        bool b;
    };
    b_c c;
    c.c = 2;

    if(c.b) puts("true!");
    if(!c.b) puts("false!");
}
```

(this is designed to run on a computer, but the same thing could happen on an Arduino). [Check out what happens](https://cpp.godbolt.org/z/eM14v7srM) when you run it: it outputs both `true!` and `false!`! This obviously doesn't make sense, but because we violate the rules by making a `bool` `2`, we loose all guarantees.

---

So, how is this relevant to your question? There's no valid value a `bool` can store other than `true` and `false`. In C++, `null` is defined as "an integer literal with value zero". So, if you were to assign `null` to a `bool`, it would be stored as false. If you want a separate null value, you're better off using another type that takes up a single byte (e.g. `unsigned char` or `uint8_t`, same thing) and storing e.g. `0` for `false`, `1` for `true`, and `2` for null.