body:
We're working with these very odd driver chips which are sort of like shift registers except rather than latch the data at the end, the latch needs to happen over the last 'n' clock cycles in parallel with the data being shifted out.  Depending on the value of 'n', the data is 'latched' into different registers. Like I said, it's an odd protocol.

Here's an example sending six bytes of data (top row) synced to the latch (bottom row).  The latch is HIGH for the last two bits of the data as it's being shifted out.

    Time-->
    11001100 01010101 10011010 11001011 01001010 10010101
    00000000 00000000 00000000 00000000 00000000 00000011

In this example, the latch is synced to the fifth and sixth bit of that last frame (as opposed to the 7th and 8th in the first example) which tells the chip to load this data into a different register.

    Time-->
    11001100 01010101 10011010 11001011 01001010 10010101
    00000000 00000000 00000000 00000000 00000000 00001100

Like I said, it's an odd design, but it basically lets you shoot out data non-stop without having to pause to latch.

Because of having to 'sync' the latch with certain clock cycles in the data, we can't use the standard SPI bus and have to use normal GPIO pins, which of course are substantially slower.

BUT... if I could set up the data for a second SPI bus, then use a buffer to define where the latch is high/low accordingly, that would work.

The issue is I don't know how to, or if it's even possible to sync SPI busses together.

Only thing I can think of is to use one SPI bus as the master and another SPI bus (on the same processor) as a slave, then try to leverage the bi-directional nature of it.  But this is just a guess.

I was considering looking into DMA too, but I'm starting with SPI since I know my chip has four SPI busses on it. (Update: I'm starting to think DMA is the way to go here since I now know it is possible to sync two DMA controllers to the same clock.)

title: Is it possible to synchronize two SPI busses to send data out in parallel on the same clock signal?

Answers: 1

body:
As [the Wikipedia page on SPI][1] shows (as introductory material), the SPI **main** device generates the clock. The SPI **sub** device waits for the leading edge on its `CS` (chip select) to start transmitting its data on the following clock edges.

So you can set up one of the senders as main device, and the other sender as sub device. Use MOSI of main as the first data output, and MISO of sub as the second data output, like this:

<!-- 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](http://i.stack.imgur.com/dioSI.png)

<!-- End schematic -->

You can add more SPI sub devices, if you need more synchronized outputs.

  [1]: https://en.wikipedia.org/wiki/Serial_Peripheral_Interface


body:
My circuit connection is like: (I am following [this tutorial][1])
[![enter image description here][2]][2]

Code uploaded to Arduino:

    #include <SoftwareSerial.h>
    #include <ArduinoJson.h>
    SoftwareSerial s(5,6);

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

    void loop() {
      StaticJsonBuffer<1000> jsonBuffer;
      JsonObject& root = jsonBuffer.createObject();
      root["data1"] = 100;
      root["data2"] = 200;
      if(s.available()>0){
        root.printTo(s);
      }
    }

Code uploaded to NodeMCU:

    #include <SoftwareSerial.h>
    int D5 = 14, D6 = 12;
    SoftwareSerial s(D6,D5);
    #include <ArduinoJson.h>

    void setup() {
      // Initialize Serial port
      Serial.begin(9600);
      s.begin(9600);
      while (!Serial) continue;
    }

    void loop() {
     StaticJsonBuffer<1000> jsonBuffer;
     JsonObject& root = jsonBuffer.parseObject(s);
     if (root == JsonObject::invalid())
       return;

     Serial.println("JSON received and parsed");
     root.prettyPrintTo(Serial);
     Serial.print("Data 1 ");
     Serial.println("");
     int data1=root["data1"];
     Serial.print(data1);
     Serial.print("   Data 2 ");
     int data2=root["data2"];
     Serial.print(data2);
     Serial.println("");
     Serial.println("---------------------xxxxx--------------------");
    }

Arduino sends JSON data and NodeMCU parses it as expected.

--------Till this everything is fine. ---------

But my requirement is vice versa. When I create JSON object in nodeMcu and try to parse in arduino, JSON not received.

This time I wrote this code in nodeMcu:

    #include <SoftwareSerial.h>
    #include <ArduinoJson.h>

    int D5 = 14, D6 = 12;
    SoftwareSerial s(D6,D5);

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

    void loop() {
     StaticJsonBuffer<1000> jsonBuffer;
     JsonObject& root = jsonBuffer.createObject();
     root["data1"] = 100;
     root["data2"] = 200;
     if(s.available()>0){
       root.printTo(s);
     }
    }

And code in Arduino:

    #include <SoftwareSerial.h>
    #include <ArduinoJson.h>
    SoftwareSerial s(5,6);

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

    void loop() {
      StaticJsonBuffer<1000> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject(s);
      if (root == JsonObject::invalid())
        return;

      Serial.println("JSON received and parsed");
      Serial.print("Data 1 : ");
      int data1=root["data1"];
      Serial.println(data1);
      Serial.print("Data 2 : ");
      int data2=root["data2"];
      Serial.println(data2);
      Serial.println("---------------------xxxxx--------------------");
     }

This code doesn't work. I don't receive anything in serial monitor of arduino.
The circuit connection remains the same as before.

Anymore information should I provide ? What modification do I need?

  [1]: https://mybtechprojects.tech/serial-communication-between-nodemcu-and-arduino/
  [2]: https://i.stack.imgur.com/uD6hR.png

title: Serial communication from Arduino to ESP8266 NodeMCU works, but from NodeMCU to Arduino isn't working

Answers: 1

body: The problem may stem from Arudino boards being 5v logic pins while ESP boards are 3.3v logic pins.  3.3v high might not be enough for Arduino to see the data.


body:
i want to make a 3-axis gimbal with arduino but brush-less motors seem incredibly hard so would stepper motors work for this purpose?

if their is a way if not, is how can i connect 3 gimbal motors to one arduino board and control them seperately? (links if possible)

title: Could i use a stepper motor?

Answers: 2

body:
A stepper motor might work, but it is certainly not the best choice for what you try.

Instead you should use brushless motors. There are not so hard to use, as you think. Driving them directly is difficult, but no one does that. Instead just buy an ESC (Electronic Speed Control) (one for each brushless motor). That is an extra chip/board, where you need to connect a PWM signal and ground from the Arduino and the power source of the motor. Then connect the motor to the ESC and you will be able to control the brushless motor with a simple PWM signal.

For further information you can read [this post][1] in the Arduino forum, or you just google. There is plenty of information the web about ESCs.

  [1]: https://forum.arduino.cc/index.php?topic=270309.0

body:
DC Motors with a feedback line (so called PID Controller; https://en.wikipedia.org/wiki/PID_controller) would be the best way to do it. You need the motor as an actor and some sensors that sense the direction of the axis's of the gimbal. The PID controller should be very fast for smooth operation. (Perhaps an ESP32 is a better MCU for this purpose).

The PID controller uses a motion sensors.

It's good to have strong motors that do not react "nervous" on on voltage changes. You probably will have to use motors with gears. Even fast PID controller won't be able to keep your camera from turning cartwheels if a 10.000 cycles per minute racing motor gets full voltage applied.

I searched the internet for videos of such a setup but the only thing I found, are the commercial (?) gimbal "alexmos" "how to" videos. I'm with you that it is hard to build such a gimbal without much knowledge of how PIDs work. I'm also not sure if there is an arduino that's fast enough to realize a PID that gets its feedback from motion sensors and drives dc motors with this information, then get's feedbach of the motor movements (from the motion sensors) and so on.

And probably a better/stronger servo and and very fast PID setup might eventually smooth the gimbals movements.

Here is a link that might help you as a start point for PID (if you are not discouraged yet):
https://www.youtube.com/watch?v=9TTDmWiMg_Y

And even professional setups can make problems: (It's a matter of the PID parameters)
https://www.youtube.com/watch?v=UeeTXH2Qv2o


body:
ive used one DS1820B sensor in a AVR bread board circuit and it works there, now i tried attaching it to a arduino mega board with the code below and also another library below that.

currently the data pin is connected to pin 10 on the arduino board, but i also tried pin 2 as in this picture:

https://lastminuteengineers.com/wp-content/uploads/2018/12/Wiring-Multiple-DS18B20-Temperature-Sensors-With-Arduino.png

i changed: #define ONE_WIRE_BUS 10   accordingly.

So after that i put the chip back onto the bread board and it still works.
I also tried it with the 4.7k resistor on the data line as pullup....still -127.

Any ideas?

    #include <SPI.h>
    #include <SD.h>
    /********************************************************************/
    // First we include the libraries
    #include <OneWire.h>
    #include <DallasTemperature.h>
    /********************************************************************/
    // Data wire is plugged into pin 2 on the Arduino
    #define ONE_WIRE_BUS 10
    /********************************************************************/
    // Setup a oneWire instance to communicate with any OneWire devices
    // (not just Maxim/Dallas temperature ICs)
    OneWire oneWire(ONE_WIRE_BUS);
    /********************************************************************/
    // Pass our oneWire reference to Dallas Temperature.
    DallasTemperature sensors(&oneWire);
    /********************************************************************/

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

    void loop() {

      Serial.print("Temperature is: ");
     Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"?
       // You can have more than one DS18B20 on the same bus.
       // 0 refers to the first IC on the wire
       delay(1000);

    }

second code:

    #include "DS18B20Events.h"

    // Pin for DS18B20
    #define ONE_WIRE_BUS 10

    /********************************************************************/
    // Setup a oneWire instance to communicate with any OneWire devices
    // (not just Maxim/Dallas temperature ICs)
    OneWire oneWire(ONE_WIRE_BUS);

    // Init DallasTemperature
    DallasTemperature dallasTemperature(&oneWire);

    //Init thermometer with index 0 (default)
    DS18B20Events thermometer(0);

    // the setup function runs once when you press reset or power the board
    void setup() {
      Serial.begin(9600);
      DS18B20Events::setup(&dallasTemperature); // Link DS18B20Events to DallasTemperature object
      DS18B20Events::setInterval(5000); // Set min interval in milliseconds between 2 measurements. Default 10000 set in setup() method.

      // subscribe to temperature changed event
      thermometer.onChange = temperatureChanged;
    }

    // the loop function runs over and over again until power down or reset
    void loop() {
      thermometer.loop(); // Mandatory to measure temperature and fire an event if needed

      Serial.print(thermometer.getTempC()); // Get last measured tempC if needed.
      Serial.print(" measured ");
      Serial.print((millis() - thermometer.getMillis()) / 1000);
      Serial.println(" seconds ago.");

      delay(1000);
    }

    void temperatureChanged(uint8_t index, float tempC)
    {
      Serial.print(tempC);
      Serial.print(" new tempC at index ");
      Serial.println(index);
    }

title: DS1820B only returns -127

Answers: 1

body:
127 error is a **connection error**, check the wiring:

[![][1]][1]

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


body: I want to attach multiple servos to Arduino but all them must receive same command. If it possible to connect all servos to one command pin (I don't want to use "for" in code to minimize processor time for operation)?

title: Controlling multiple servos as one

Answers: 1

body:
IMHO it is possible to connect more than one server PWM control inputs to a Arduino output pin.

The Servo input is something like a comparator with an very high resistance. So the servos should not influence each other in any way, nor will the output pin be overloaded.

Because of the input capacities of the servos, there might be a limit of the count of the servos.

And if you supply the servos with power from the arduino then, there is of cause a limit.

EDIT:

It is always a good idea to use buffers in a servo control circuit, to keep a sharp square wave signal. Parasitic capacities can reshape the signal even to a sinus signal.

That might confuse the servo control unit which works well only with a square wave (i.e a PWM-Signal).

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

<!-- End schematic -->


body:
I'm using arduino with analog pressure sensor, temperature sensor and a relay to control water pump. The simple code I wrote works, but I want better control.
 ```
#include <OneWire.h>
#include <DallasTemperature.h>

  const int pinCidlaDS = 2;
  int pinA0 = A0;
  int teplota;
  int rele;
  float tlak = 0;  //ideal 290+-

OneWire oneWireDS(pinCidlaDS);
DallasTemperature senzoryDS(&oneWireDS);

void setup() {
  senzoryDS.begin();
  rele = 3;
  pinMode(3, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  tlak = analogRead(A0);
  teplota = (senzoryDS.getTempCByIndex(0));
   if ((tlak < 285) && (teplota < 30)) {
    digitalWrite(rele, LOW);
    delay(7000);
  }
    else {
    digitalWrite(rele, HIGH);
    delay(500);
  };
  Serial.print("Tlak: ");
  Serial.println(tlak);
  Serial.print("Teplota: ");
  senzoryDS.requestTemperatures();
  Serial.print(senzoryDS.getTempCByIndex(0));
  Serial.println(" stupnu Celsia");
  teplota = (senzoryDS.getTempCByIndex(0));
  delay (200);

}
```
So now I'm using delay to get away from the treshold value. And I wanted to write a code that would work like:

**Pressure is lower than 'x', relay ON.
Pressure rises to 'Y', relay OFF until Pressure is lower than 'x'.**

What should I use? Could you please give me a example, if there is?
Thank you very much! :)

title: Water pump control hysteresis

Answers: 1

body:
Implementing hysteresis turns out to be quite straight-forward:

```c++
float pressure = read_pressure();
if (pressure < x)
    turn_relay_on();
else if (pressure >= y)
    turn_relay_off();
```


body:
Dears,

I have a problem that I could not solve for a while, I tried the code below but it did not work.
There will be 4 buttons controlling 4 relays but in a way that button one will turn relays 1&3 on, if button 2 is pressed only relay 2 turns on, if button 3 is pressed relays 1,2 and 3 will turn on, if button 4 is pressed it is supposed to toggle relays 1&4. one more thing: I need to be able to pass from any button to any of the others and the corresponding relays will be activated while the others will go off.

        #include <Bounce2.h>

        const int     BUTTON_COUNT = 4;
        const int16_t DEBOUNCE_DELAY = 50;
        const uint8_t buttonPins[BUTTON_COUNT] = {28, 29, 30, 31};
        const uint8_t ledPins[BUTTON_COUNT] = {34, 35, 36, 37};

        Bounce buttons[BUTTON_COUNT];
        uint8_t ledStates[BUTTON_COUNT];

        void setup() {
        for (int i = 0; i < BUTTON_COUNT; i++) {
        buttons[i].attach(buttonPins[i], INPUT);
        buttons[i].interval(DEBOUNCE_DELAY);
        pinMode(ledPins[i], OUTPUT);
        ledStates[i] = HIGH;
        digitalWrite(ledPins[i], ledStates[i]);
         }
        }

        void loop() {

    // Update the debouncers.
    for (int i = 0; i < BUTTON_COUNT; i++)
        buttons[i].update();

    // When the first "laban" button is pressed:
    if (buttons[0].rose()) {

        // Light up the first LED.
        digitalWrite(ledPins[1], LOW);
        digitalWrite(ledPins[3], LOW);

        // and turn off all the others.
        for (int i = 0; i < BUTTON_COUNT; i++) {
            ledStates[0] = HIGH;
            ledStates[2] = HIGH;
            digitalWrite(ledPins[i], ledStates[i]);
        }
    }

    // When the first button is released:
    if (buttons[0].fell()) {

        // turn off relays.
        digitalWrite(ledPins[1], HIGH);
        digitalWrite(ledPins[3], HIGH);

    }

    // When the first "Soda" button is pressed:
    if (buttons[1].rose()) {

        // Light up the first LED.
        digitalWrite(ledPins[2], LOW);

        // and turn off all the others.
        for (int i = 0; i < BUTTON_COUNT; i++) {
            ledStates[0] = HIGH;
            ledStates[1] = HIGH;
            ledStates[3] = HIGH;
            digitalWrite(ledPins[i], ledStates[i]);
        }
    }

    // When the first button is released:
    if (buttons[1].fell()) {

        // turn off the first LED.
       digitalWrite(ledPins[2], HIGH);

    }

    // When the first "labanUP" button is pressed:
    if (buttons[2].rose()) {

        // Light up the first LED.
        digitalWrite(ledPins[1], LOW);
        digitalWrite(ledPins[2], LOW);
        digitalWrite(ledPins[3], LOW);

        // and turn off all the others.
        for (int i = 0; i < BUTTON_COUNT; i++) {
            ledStates[0] = HIGH;
            digitalWrite(ledPins[i], ledStates[i]);
        }
    }

    // When the first button is released:
    if (buttons[0].fell()) {

        // turn off the first LED.
         digitalWrite(ledPins[1], HIGH);
         digitalWrite(ledPins[2], HIGH);
         digitalWrite(ledPins[3], HIGH);
    }

    // When circulation button is pressed:
     if (buttons[3].rose()) {

        // Toggle its state.
        ledStates[3] = !ledStates[3];
        digitalWrite(ledPins[3], ledStates[3]);
        digitalWrite(ledPins[0], ledStates[0]);
         }
        }

title: Multiple buttons to control relays

Answers: 1

body:
Below code is an simple example of what you described, each button will turn on the relays defined for them and turn off other relays. except for button 4 which will toggle relay 1 and 4.

    int relay1 = 2;
    int relay2 = 3;
    int relay3 = 4;
    int relay4 = 5;
    int sw1 = 6;
    int sw2 = 7;
    int sw3 = 8;
    int sw4 = 9;
    int sw1Status, sw2Status, sw3Status, sw4Status;
    int order = 1; // default is to set all relays off.

    void setup() {
      pinMode(relay1, OUTPUT);
      pinMode(relay2, OUTPUT);
      pinMode(relay3, OUTPUT);
      pinMode(relay4, OUTPUT);
      // input pull-up, so default state of buttons is HIGH.
      pinMode(sw1, INPUT_PULLUP);
      pinMode(sw2, INPUT_PULLUP);
      pinMode(sw3, INPUT_PULLUP);
      pinMode(sw4, INPUT_PULLUP);
    }

    void loop() {
      // read the buttons status
      sw1Status = digitalRead(sw1);
      sw2Status = digitalRead(sw2);
      sw3Status = digitalRead(sw3);
      sw4Status = digitalRead(sw4);

      if (sw1Status == LOW) { // if button 1 pressed
        order = 2; // go to case 2
      }
      if (sw2Status == LOW) {
        order = 3;
      }
      if (sw3Status == LOW) {
        order = 4;
      }
      if (sw4Status == LOW) { // button 4 toggle
        if (order != 5) { // if order is not equal 5 turn on relay 1 & 4
          order = 5;
        }
        else { // else go to case 1, which will turns off all relays
          order = 1;
        }
      }

      switch (order) {
        case 1: // if order equals 1
          digitalWrite(relay1, LOW);
          digitalWrite(relay2, LOW);
          digitalWrite(relay3, LOW);
          digitalWrite(relay4, LOW);
          break;

        case 2: // if order equals 2
          digitalWrite(relay1, HIGH);
          digitalWrite(relay2, LOW);
          digitalWrite(relay3, HIGH);
          digitalWrite(relay4, LOW);
          break;

        case 3: // if order equals 3
          digitalWrite(relay1, LOW);
          digitalWrite(relay2, HIGH);
          digitalWrite(relay3, LOW);
          digitalWrite(relay4, LOW);
          break;

        case 4: // if order equals 4
          digitalWrite(relay1, HIGH);
          digitalWrite(relay2, HIGH);
          digitalWrite(relay3, HIGH);
          digitalWrite(relay4, LOW);
          break;

        case 5: // if order equals 5
          digitalWrite(relay1, HIGH);
          digitalWrite(relay2, LOW);
          digitalWrite(relay3, LOW);
          digitalWrite(relay4, HIGH);
          break;

        default: // if none of above cases is valid go to case 1
          order = 1;
          break;
      }
    }

Having a tidy code format and using simple coding style (if possible) will help to debug/edit/improve the code more easily.

*Don't forget to de-bounce the buttons.*


body: I am using different codes which set different values of baud rate through the Serial.begin() function. Do I need to change the baud rate of the serial monitor to match the initialized value on the code I am running every time, or can I just leave the serial monitor baud rate set at the highest frequency of all my sketches (115200)?

title: Matching baud rate on serial monitor

Answers: 2

body:
If your sketch has

      ...
    void setup() {
      Serial.begin(115200);
      // ... other stuff here;
    }
      ...

And you run the IDE serial monitor at 9600, you will get gibberish. The same happens the other way round. You need to match the monitor to the baud rate you've defined on the `Serial.begin();` call.

body:
Sometimes yes, and sometimes no.

The majority of Arduino boards are connected to your computer through a USB connection (there are some rare outside cases that use other connections like bluetooth or RS485...).  That USB connection can fall into two broad categories:

1. A USB to UART adaptor that then connects to a UART on the Arduino's main MCU, and
2. A direct USB connection to the main MCU

Type 1 are such boards as the Uno, Mega and Nano. Basically any board that has both a main MCU and a secondary chip that lies between the USB connection and that MCU.

In this case the baud rate in the serial monitor is communicated to the USB interface chip and tells that chip "You are to communicate with the main MCU at this speed".  You also then have to have the main MCU communicate with the USB chip at that same speed. So it is *imperative* that those two speeds match.

In the second case this isn't true. USB itself has no real concept of "baud rate". Instead the baud rate you set is merely a piece of configuration information the device at the end of the USB connection can use for something if it sees fit (what that "something" is, is entirely up to the device).  Changing that baud rate has no real effect on the communication.  Boards like the Leonardo and the Mini fall into this category.  They all have a "U" chip, like the ATMega32U4, which directly talk USB.

So, in short:

* If you have a "Non-U" chip based board with a USB interface chip you *must* match the baud rates, and
* If you have a "U" chip based board (or some other make of board with a direct USB interface) then the whole concept of baud rate is meaningless1 and it really doesn't matter what the numbers are you choose to use where.

----

1. 1200 baud is a special case in Arduino USB boards as it is used to trigger the bootloader for uploading new code.


body:
I want to control 4 digital outputs (d0, d1, d2, d3) with one switch. When the Arduino starts, they should all be in state LOW.

Now, after pressing the button once, d0 should get HIGH. Another push brings d0 to LOW and d1 to HIGH. So actually the 4 outputs shall behave like a bitmask. After every push the bitmask shall increment by one.

    d0 LOW
    d1 LOW
    d2 LOW
    d3 LOW

push

    d0 HIGH
    d1 LOW
    d2 LOW
    d3 LOW

push

    d0 LOW
    d1 HIGH
    d2 LOW
    d3 LOW

Is there an easy way to implement this, without typing every case in the code?

I am glad for any hints.
Cheers and thanks.

title: Control 4 digital outputs with one switch

Answers: 1

body:
As usual with programming, there are many solutions, for example:

1. You can use a bitmask, put 4 variables in an array with binary values 1000, 0100, 0010 and 0001 and when the switch is pressed, you store the value into each LED pin by comparing the value.
2. However, a more simpler solution is just use a counter from 0 to 4, if the value is 1, the first LED should be one, then after a switch increase the value, and use modulo 5 (% 5) to go back to 0.

To check if a button is clicked, use a boolean, which check against the previous value. Also implement the debounce algorithm which can be found at the Arduino site.

Without debouncing it could look like this:

    #include "stdlib.h"

    int buttonPin    =   7;
    int buttonState  = LOW;

    int led1Pin      =   8;
    int led2Pin      =   9;
    int led3Pin      =  10;
    int led4Pin      =  11;
    int ledMode      =   0; // All off, 1-4 means LED 1-4 is on

    void setup()
    {
    }

    void loop()
    {
       // Add debouncing yourself
       if ((buttonState == LOW) && (digitalRead(buttonPin) == HIGH))
       {
          buttonState = HIGH;
          ledMode = (ledMode + 1) % 5;
       }
       else if ((buttonState == HIGH) && (digitalRead(buttonPin) == LOW))
       {
          buttonState = LOW;
       }

       digitalWrite(led1Pin, ledMode == 1 ? HIGH : LOW);
       digitalWrite(led2Pin, ledMode == 2 ? HIGH : LOW);
       digitalWrite(led3Pin, ledMode == 3 ? HIGH : LOW);
       digitalWrite(led4Pin, ledMode == 4 ? HIGH : LOW);
    }

If you put the LEDs on subsequent pins, you can use the following code which is more simpler and works for any number of LEDs:

    #include "stdlib.h"

    int buttonPin    =   7;
    int buttonState  = LOW;

    int nrOfLeds     =   4;
    int startLed     =   8;
    int ledMode      =   0; // All off, 1 means led on pin startLed, 2 means led on pin startLed + 1 etc.

    void setup()
    {
    }

    void loop()
    {
       // Add debouncing yourself
       if ((buttonState == LOW) && (digitalRead(buttonPin) == HIGH))
       {
          buttonState = HIGH;
          ledMode = (ledMode + 1) % (nrOfLeds + 1);
       }
       else if ((buttonState == HIGH) && (digitalRead(buttonPin) == LOW))
       {
          buttonState = LOW;
       }

       for (int led = 0; led < nrOfLeds; ledPin++)
       {
           digitalWrite(startLed + led, ledMode == led + 1 ? HIGH : LOW);
       }
    }


body:
I bought this on the store near us. Here is the PDF for it.

https://www.e-gizmo.net/oc/kits documents/new LCD with converter/LCD IF pin adapter.pdf

I followed the instructions below and uploaded the code and all I've got is this
[![Uploaded][1]][1]

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

   I've reconnected it and used a different jumper wires, still the same result.

    #include <LiquidCrystal.h>

    LiquidCrystal lcd(12,11,5,4,3,2);

    void setup(){
      lcd.begin(16,2);
      lcd.print("ntest");
    }

    void loop(){

      lcd.setCursor(0,1);
      lcd.print(millis()/1000);

    }

title: Why is my LCD I/F PIN ADAPTER won't work

Answers: 0


body:
I've got a 50k potentiometer connected to an Arduino Uno. The user should adjust the hue of an Adafruit NeoPixelStrip.

I've got the following code inside the loop function:

    int hue = analogRead(poti1);
    int mappedHue = map(hue, 0, 1023, 0, 65535);

    neoPixelStrip.fill(neoPixelStrip.gamma32(neoPixelStrip.ColorHSV(mappedHue, 255, 255)));
    neoPixelStrip.show();

If I turn the potentiometer knob, the colors are updating correctly and reflect the correct hue.
But if I let go of the knob, the LEDs are flickering a little (changing their hue values ever so slightly). If I print the potentiometer values to the console, they are changing a little. If I turn the potentiometer all the way to the left, the values range from 0 ... 13 or something. This change affects the hue of the pixels.

**How do I ignore those value variations? I want the user to constantly change the color, so I have to read the value constantly.**

**Any ideas?**

title: ignoring potentiometer value variations

Answers: 2

body:
There are many ways to remove noise, below are some ways:

- Only change the value when it differs enough. Assume the range is 0-1023. Than only change the value if the input value differs more than a constant value (like 5 or 10, experiment with this to find a good value for your pot meter).
- Another way is to use the average of the last x readings,  You can also combine this with the previous approach. There might be a small delay because of the averaging.

There are many more solutions, from reasonably easy to very complicated, search for removing noise in sensor data.

body:
You have two issues going on - noise pickup, and a potentiometer with imprecise stops at one or both ends.

The pot is the easiest to fix: What are the lowest low reading and highest high reading you can reliably get when you turn it to its stops? Use those in place of '0' and '1023' in your `map()` function.

Improving the noise is only slightly more involved. An exponential average is an easy filter to write and quite effective at quieting noisy data, as long the signal to noise ratio is fairly low. The basic idea is you add only a fraction of each new value and keep (1 - that fraction) of the old average; so if your chosen fraction is 0.1, you only consider 10% each new datum, keeping 90% of the current average.

`avg = f*avg + (1-f)*new_value`

The output of this averaging filter can be slow to respond to changes if your fraction is too small, but less effective at quieting noise if your fraction is too large.

I usually use .25, or 25% of each new point and 75% of the current average, when I'm just trying to clean up minor noise, which is what you probably have.

Here is my 25% averaging filter:

    int16_t xpavg(int16_t newdat, int16_t avg){

       // (3 * avg + 1 * newdat) / 4
       return( (((avg<<2) - avg + newdat) + 2) >> 2 );
    }

As you can see, I do the arithmetic in Fixed Point - just like integer arithmetic, but with an assumed binary point 2 places to the left during the computation. And I choose a fraction that represents "nicely" in binary - 1/4 in this case - to keep the arithmetic faster (since multiplication and division can be replaced by shifting).

The function just multiplies the current average by 4 and subtracts the old average (effectively multiplying by 3), adds the new value, and divides the sum by 4. (That extra "+2" rounds the fractional bits just before we shift them away). The end result is:<br> (3*avg + newData)/4 (== 3/4*avg + 1/4*newData).

If you were to only sample the pot every second or two, you could probably observe the delay as the filter falls behind while you turn the pot and catches up when you stop. If you're sampling at 10x/sec or less, you shouldn't be able to notice.

Update:

You need to add the function `xpavg()` to your code, and call it each time you read a new pot value (that is "newdat"), passing it the old average as well. It returns a new average pot value, now less affected by noise. You use that new average value instead of the raw number you just read from the pot, in your hue calculation. As Duncan offered, you can - and I do - initialize the average with a raw value from the pot. You could also start it at zero but it will take a few samples to converge on the current actual pot reading. The downside of using one raw sample to start it is that if that one value is terribly noisy, i.e. way different from the pot reading, it will *still* take a few samples to converge.

    unsigned int AvgPot = analogRead(poti1);        // initialize pot average

    // Exponential averaging functions
    int16_t xpavg(int16_t newdat, int16_t avg)
    {
       // (3 * avg + 1 * newdat) / 4
       return( (((avg<<2) - avg + newdat) + 2) >> 2 );
    }

    void setup()
    {
       ;    // initializations go here
    }

    void loop()
    {
       int hue = analogRead(poti1);
       hue = xpavg(poti1, PotAvg);
       int mappedHue = map(hue, 0, 1023, 0, 65535);

       neoPixelStrip.fill(neoPixelStrip.gamma32(neoPixelStrip.ColorHSV(mappedHue, 255, 255)));
       neoPixelStrip.show();
    }


body:
I am using an ESP32 (without arduino board and using arduino IDE ) with bluetooth and communicating with other hardware via serial communication.
Serial communication speed is high (1382400) but it works and I can read few bytes normally. I need to read a large number of bytes (541) in loop to be able to flush the memory of the hardware in question.
Using the following code I can read the bytes and can even perform a number of iterations but usually get the following error after a few iterations:
**Guru Meditation Error: Core 1 panic'ed (InstrFetchProhibited). Exception was unhandled.**

    #include "BluetoothSerial.h"

    #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
    #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
    #endif

    #define RXD2 16
    #define TXD2 17

    BluetoothSerial SerialBT;
    HardwareSerial SerialPIC(2); // using esp32 port2

    byte recebidoPIC[542];
    byte recebidoBT[50];

    bool conectado;
    int pagina;
    bool coletaftp;
    bool enviar;

    void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
      if (event == ESP_SPP_SRV_OPEN_EVT) {
        // pin set to high enable communication to other hardware
        digitalWrite(2, HIGH);
        digitalWrite(5, HIGH);
        conectado = true;
      }

      if (event == ESP_SPP_CLOSE_EVT) {
        digitalWrite(2, LOW);
        digitalWrite(5, LOW);
        conectado = false;
      }
    }

    void setup() {
      pinMode(5,OUTPUT); // Control pin to enable hardware
      Serial.begin(19200);
      SerialPIC.begin(1382400,SERIAL_8N1,RXD2,TXD2);
      SerialBT.begin("ESP32test"); //Bluetooth device name
      Serial.println(F("The device started, now you can pair it with bluetooth!"));
      SerialBT.register_callback(callback);
    }

    int leStringSerialBT()
    {
         int cont=0;
         while ( SerialBT.available() > 0 ) {
           recebidoBT[cont++] = SerialBT.read();
           yield();
         }
      return cont;
    }

    int leStringSerialPIC()
    {
      int cont = 0;
       while ( SerialPIC.available() > 0 ) {
         recebidoPIC[cont++] = SerialPIC.read();
        // delay(0);
         yield();
        }
        return cont;
    }

    void loopcoleta()
    {
      if (SerialPIC.available()) {
         int cont=0;

        cont = leStringSerialPIC();

          if (cont < 541)
          {
            Serial.print(F("Nao completou - "));
            Serial.println(cont);

          }
          else{
            Serial.print(F("Completou - "));
            Serial.println(cont);
            Serial.print(F("Iteracao :"));
            Serial.print(pagina);
            pagina++;
          }

      }
    }

    void loop() {
     // digitalWrite(5,HIGH);

      if (Serial.available()) {
        SerialBT.write(Serial.read());
      }

      if (SerialBT.available()) {
        int cont=-1;
        cont = leStringSerialBT();
        if ( conectado )
        {

           if ((recebidoBT[0]=='$') && (recebidoBT[1]=='f'))
           {
              coletaftp = true;
              enviar = true;
              //recebidoBT = "";
              pagina = 1;
           }
           else
           {

               SerialPIC.write(recebidoBT,cont);

           }

           if ( (coletaftp) && (enviar)  )
           {
              char comando[11];
              int looppagina = pagina;
              int contcoleta=0;
              unsigned int timeinit = millis();
              while ( pagina < 8191 )
              {
               sprintf(comando, "$rd 00x", pagina);
               SerialPIC.println(comando);

               loopcoleta();
               delay(0);
              }
              Serial.println(millis() - timeinit);

           }

        }

      }

      if (SerialPIC.available()) {
         int cont=0;

        unsigned int timeprevious = millis();
        cont = leStringSerialPIC();

        Serial.println(millis() - timeprevious);
        Serial.println("");
        Serial.write(recebidoPIC,cont);
        Serial.println("");
        Serial.println(cont);
        SerialBT.write(recebidoPIC,cont);

         cont=0;
     }

     // delay(20);
    }

The above code is complete and after some iterations I get the following message (copied from serial monitor)

    Iteracao :1 Completou - 541
    Iteracao :2 Completou - 541
    Iteracao :3 Completou - 541
    Iteracao :4 Completou - 541
    Iteracao :5 Completou - 541
    Iteracao :6 Completou - 541
    Iteracao :7 Completou - 541
    Iteracao :8 Completou - 541
    Iteracao :9 Completou - 541
    Iteracao :10 Completou - 541
    < list goes ok here >
    Iteracao :67 Completou - 541
    Iteracao :68 Completou - 541
    Iteracao :69 Completou - 541
    Iteracao :70 Nao completou - 4
    Guru Meditation Error: Core  1 panic'ed (InstrFetchProhibited). Exception was unhandled.
    Core 1 register dump:
    PC      : 0x17335c40  PS      : 0x00060330  A0      : 0x800d18bf  A1      : 0x3ffc89d0
    A2      : 0x3ffc50f0  A3      : 0x3f40152f  A4      : 0x0000000a  A5      : 0x0000ff00
    A6      : 0x00ff0000  A7      : 0xff000000  A8      : 0x800d240f  A9      : 0x3ffc89b0
    A10     : 0x3ffc50f0  A11     : 0x00060320  A12     : 0x400908ef  A13     : 0x3ffc8990
    A14     : 0x00050323  A15     : 0x3ffba470  SAR     : 0x0000001b  EXCCAUSE: 0x00000014
    EXCVADDR: 0x17335c40  LBEG    : 0x4000c28c  LEND    : 0x4000c296  LCOUNT  : 0x00000000

    Backtrace: 0x17335c40:0x3ffc89d0 0x400d18bc:0x3ffc89f0 0x400d18d8:0x3ffc8a10 0x400d1a26:0x3ffc8a30 0x400d2c05:0x3ffc8a60 0x4008e0bd:0x3ffc8a80

    Rebooting...

Already tried to put a longer delay () between each iteration, reduce the size of the array and did not solve ...
What could cause this problem in the code I'm using? If you need more details just tell me.

title: Error while receiving large amount bytes on loop using esp32 ( 541 bytes )

Answers: 0


body:
I am trying to create a library called "LED" for LED Sequencer in Arduino IDE,where the user has to configure the LED pins using an array and pass it to  LED constructor in program and then will be able to use BlinkAll(),LeftToRight() and RightToLeft() Functions which lights the LED from Left to Right or Right to Left based on the sequence mentioned in the array. The problem is when I initiate the array and pass it to the constructor Pins 4,5,7 are not working at all , Please help me find what is the possible issue
the code in LED.cpp file is shown below

    #include <Arduino.h>
    #include "LED.h"

    LED::LED(int channel, int* a){
      _channel = channel;
      for(int i = 0 ; i < channel; i ++)
      {
        _pins[i] = a[i] ;
        pinMode(_pins[i],OUTPUT);
      }
    }
    void LED :: BlinkAll(int delay_ms)
    {
       for (int i = 0 ; i<_channel;i++)
       {
        digitalWrite(_pins[i],HIGH);
       }
       delay(delay_ms);
       for (int i = 0 ; i<_channel;i++)
       {
        digitalWrite(_pins[i],LOW);
       }
       delay(delay_ms);
    }
    void LED :: LeftToRight(int numberofLEDs, int delay_ms)
    {
      for(int i =0 ;i<_channel; i++)
      {
        digitalWrite(_pins[i], LOW);
      }
      for(int i =0 ;i<_channel; i++)
      {
    //    if (i > 0)
    //    {
    //     digitalWrite(_pins[i-1], LOW);
    //    }
      for(int i =0 ;i<_channel; i++)
      {
        digitalWrite(_pins[i], LOW);
      }
        digitalWrite(_pins[i], HIGH);
        delay(delay_ms);
      }
    }
    void LED :: RightToLeft(int numberofLEDs,int delay_ms)
    {
        for(int i =_channel ;i>0; i--)
      {
        digitalWrite(_pins[i], LOW);
      }
      for(int i = _channel ;i>0; i--)
      {
        if (i < _channel)
        {
         digitalWrite(_pins[i+1], LOW);
        }
        digitalWrite(_pins[i], HIGH);
        delay(delay_ms);
      }
    }
LCD.h

    #ifndef LED_h
    #define LED_h

    #include <Arduino.h>

    class LED
    {
    public:
      LED(int channel, int* pins);
      void BlinkAll(int delay_ms);
      void LeftToRight(int numberofLEDs, int delay_ms);
      void RightToLeft(int numberofLEDs, int delay_ms);
      void BlinkAlternate(int delay_ms);
    private:
      int _channel;
      int _pins[16];
    };

    #endif
Sample Code

    #include "LED.h"

    int const LED_pins[8]={5,6,7,8,9,10,11,12};
    int const No_of_LED = 8;

    LED led(8,LED_pins);

    void setup()
    {
      Serial.begin(9600);
    }
    void loop()
    {
      led.LeftToRight(1,500);
      led.RightToLeft(1,500);
    }

title: How to dynamically set pinMode and dynamically write value to pins in Arduino using arrays?

Answers: 1

body:
It seems in the `LeftToRight` method, you didn't comment out enough (or too much), because  you use a for loop inside another for loop which is probably unintended.

In the `RightToLeft' method I will try to fix the problem, so you can change the `LeftToRight` method similarly.

    void LED :: RightToLeft(int numberofLEDs,int delay_ms)
    {
      for(int i =_channel ;i>0; i--)
      {
        digitalWrite(_pins[i], LOW);
      }
      for(int i = _channel ;i>0; i--)
      {
        if (i < _channel)
        {
         digitalWrite(_pins[i+1], LOW);
        }
        digitalWrite(_pins[i], HIGH);
        delay(delay_ms);
      }
    }

The first for loop is to switch off the LEDs, I would make this a separate method, so it can be reused in both the `LeftToRight` and `RightToLeft` method, so you get:

    void LED::RightToLeft(int numberofLEDs, int delay_ms)
    {
      switchAllLedsOff();

      for(int i = _channel; i > 0; i--)
      {
        if (i < _channel)
        {
         digitalWrite(_pins[i + 1], LOW);
        }
        digitalWrite(_pins[i], HIGH);
        delay(delay_ms);
      }
    }

    void LED::SwitchAllLedsOff()
    {
      for(int i = _channel; i > 0; i--)
      {
        digitalWrite(_pins[i], LOW);
      }
    }

The problem is also, that you always write HIGH to a pin, since it overwrite the possible LOW assignment within the if statement. To correct this you get:

    void LED::RightToLeft(int numberofLEDs, int delay_ms)
    {
      switchAllLedsOff();

      for(int i = _channel; i > 0; i--)
      {
        digitalWrite(_pins[i + 1], i >= _channel ? HIGH : LOW);
        delay(delay_ms);
      }
    }

You also can use an `if` statement, but in this case the ternary (? :)  statement is more clear since the assignment is for a single destination (_pins[i + 1]). So in case i >= channel, it is set to HIGH, otherwise set to FALSE. I also inverted the operator, but you can keep it inverted too.

Third, _channel seems to be the number of elements in the array, if you use it in an index it should start with _channel - 1, so you get:

    void LED::RightToLeft(int numberofLEDs, int delay_ms)
    {
      switchAllLedsOff();

      for(int i = _channel - 1; i >= 0; i--)
      {
        digitalWrite(_pins[i + 1], i >= _channel - 1 ? HIGH : LOW);
        delay(delay_ms);
      }
    }

There might be more problems, but the above are at lest some of them.

Also I changed your way of using spaces, although it's a matter of personal style, yours I never saw before (which doesn't mean it's incorrect of course).

(note I have not tested the program).


body:
I have a 9v water pump that i want to turn on\off from the arduino,
What module should i use to turn it on and off?

I am using now a mosfet for my 5v pump, can a mosfet be used for 9v as well? Or is there some better solution?

title: Need a component to connect a 9v water pump

Answers: 1

body:
Yes, a MOSFET should work just fine. As others have said in the comments, you just need to make sure that it's rated for your desired voltage and current, and that it's threshold voltage is low enough (around 2.5V) that the Arduino is able to drive it to saturation with a logic level 1 (5V).

I've used this one (rated at 60V and 30A) in various projects:

https://www.sparkfun.com/products/10213


body:
I have a problem with my NodeMCU v2 board and my WS2812B led matrix with 256 (32x8) LEDs.

The Board cannot be able to turn on the 191th led and stops working after the 190th without changing the color of the rest of the strip.

I'm using an external power supply 5V 20A and the strip is connected as shown below

[![ODE][2]][2]

I tested the problem with the FastLED library.

    #include <Arduino.h>
    #include <FastLED.h>
    #define NUM_LEDS 256
    #define DATA_PIN 2

    CRGB leds[NUM_LEDS];

    void setup() {
      Serial.begin(9600);
      FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);
    }

    void loop() {
      for(int dot = 0; dot < NUM_LEDS; dot++) {
          leds[dot] = CRGB::Red;
      }
      FastLED.show();
      delay(10000);
      for(int dot = 0; dot < NUM_LEDS; dot++) {
          leds[dot] = CRGB::Black;
      }
      FastLED.show();
      delay(10000);
    }

The result is this
------------------

[![sad problem][1]][1]

How I can solve this?

  [1]: https://i.stack.imgur.com/6absH.jpg
  [2]: https://i.stack.imgur.com/WI2FL.png

title: WS2812B not fully working with NodeMCUv2 [ESP8266]

Answers: 0


body:
I'm trying to build a thermistor that will flash an LED when the temperature is above 30 C. My set-up appeared to be reporting the room temperature correctly to the Serial Monitor, but then I noticed that exposing the thermistor to a hot object causes the reported temperature to drop, whereas exposing it to a cold object causes the reported temperature to rise.

I'd built a simpler thermistor circuit earlier with a similar approach and everything seemed to function correctly. I'm not sure what I broke here:

```
const int WarningLED = 7;
const int Thermistor = 0;

/* Thermistor information:
 * P/N: BC2301-ND
 * MFG P/n: NTCLE100E3103JB0
 * DESC: THERMISTOR NTC 10KOHM 3977K BEAD, IDX: 1 */

int Vo; // voltage between thermistor and R1
float R1 = 10000; //10 KOHM resistor used for voltage divider
float TR; // resistance of negative temperature coefficient (NTC) thermistor
float beta;  //beta will later equal ln( TR / Rref )
float Tk, Tc, Tf;

/* Steinhart-Hart equation coefficients via data table at
 * http://www.vishay.com/docs/29049/ntcle100.pdf
 * Bead used: 3977K (refer to #9 values on Nominal R table) */
float A = 3.354016e-03,B = 2.569850e-04;
float C = 2.620131e-06,D = 6.383091e-08;

void setup() {
  pinMode(WarningLED, OUTPUT); //sets the warning LED pin as a digital output
  Serial.begin(9600);          //  setup a serial port to enable comms with the computer.
 }

void loop() {

  Vo = analogRead(Thermistor);
  Serial.print("Vo: ");
  Serial.print(Vo);
  Serial.println(" mV");

  //Voltage divider equation: R2 = R1 * [Vo / (Vi - Vo)]
  //where R2 = TR, Vi = 1023.0 :
  TR = R1 * ((float)Vo / (1023.0 - (float)Vo));
  Serial.print("Thermistor resistance: ");
  Serial.print(TR);
  Serial.println(" ohms");

  beta = log(TR/10000); // As per extended Steinhart-Hart equation,
  //  where Rref = 10,000 (refer to page 10 of the PDF linked above)
  Tk = (1.0 / (A + B*beta + C*beta*beta + D*beta*beta*beta));
  Tc = Tk - 273.15;
  Tf = (Tc * 9.0)/ 5.0 + 32.0;

  Serial.print("Temperature: ");
  Serial.print(Tk);
  Serial.print(" K; ");
  Serial.print(Tf);
  Serial.print(" F; ");
  Serial.print(Tc);
  Serial.println(" C");
  Serial.println();

  if (Tc > 30.0) digitalWrite(WarningLED, HIGH);
  else if (Tc < 30.0) digitalWrite(WarningLED, LOW);
  delay(1000);
}
```
On the Serial Monitor, this reports:
```
Vo: 550 mV
Thermistor resistance: 11627.91 ohms
Temperature: 294.74 K; 70.86 F; 21.59 C
```

Exposing this to a warmer temperature incorrectly reports:
```
Vo: 597 mV
Thermistor resistance: 14014.08 ohms
Temperature: 290.61 K; 63.43 F; 17.46 C
```

I notice that, among other issues, this is reporting increased resistance in the thermistor despite that I'm using an NTC, but I'm not sure why this is occurring.

Notable parts used in this circuit:

 - Thermistor: NTCLE100E3103JB0
 - R1: 10 KOHM
 - R2: 1 KOHM
 - C1 & C2: 33 nf

[![circuit diagram][1]][1]

[![arduino][2]][2]

  [1]: https://i.stack.imgur.com/ooxHA.jpg
  [2]: https://i.stack.imgur.com/3Vx7b.jpg

title: Why are my thermistor readings backward?

Answers: 2

body:
The voltage Vo is not the voltage over the thermistor, it is the voltage over R1! Switch the place of the thermistor and R1.
/Mikael

body:
In addition, note that the Vo is definitely not expressed in mV (millivolts), but in ADC steps , i.e. 1024th of the Vref, that is here 5V (default). And the reference is there that it should be 512 for 25deg.

Also, don't be fooled with the precision of the numbers given. Tolerance is 2% to 5% on the R25 value, which means up to ~25 "steps" (Vo). Assuming that reversing the R1 and TR gives you 450 at 22 deg, it means that your real threshold of 30 deg could be anywhere between 28 and 32 (roughly).

You can get better results by calibrating your TR: at 25deg, measuring its real resistance and using that instead of 10000 in your calculation is a first option. Calibrating for other temperatures is already way more complicated.


body:
I followed the tutorial I found here https://techtutorialsx.com/2019/03/29/esp32-arduino-controlling-a-dc-motor/
On the very interesting topic controlling a DC motor with the esp32 and Arduino I have some questions:

The first one: Where in the world did the guy find out the pin numbers for the Arduino IDE for this board? I have no idea how to find them!?

> Taking in consideration that the digital IO pins of the ESP32 can only
> source a maximum current of 40 mA [1], we cannot directly use them to
> control a DC motor.
>
> Instead, we are going to use a ULN2803A integrated circuit to actually
> provide the current to the motor, while the ESP32 will simply control
> if the motor is running or stopped.
>
> The connection diagram to control a DC motor from the ESP32 using an
> ULN2803A can be seen below at figure 1. for controlling a DC motor
> with the ESP32, using a ULN2803A integrated circuit
>
> The controlling of the DC motor with the ESP32 and a ULN2803A IC. In
> short, the ULN2803A will act as a switch, which will turn on / off the
> connection of the motor to GND, depending on the state of the input
> pin labeled as In 1. So, when the GPIO of the ESP32 is at a digital
> high value (VCC), the ULN2803A will connect the motor to GND, and thus
> the motor will be on. When the GPIO is at a digital low value (GND),
> then the motor will be disconnected from GND, and thus it will be off.
> Furthermore, the ULN2803A can be controlled by 3.3 V inputs and
> provide higher voltages, allowing us to control a 5 V DC motor with
> the ESP32.
>
> The code
>
> The code for this tutorial will be very simple, since we basically
> only need to control the status (high or low) of a digital pin of the
> ESP32.
>
> So, we will start by declaring as a global variable the number of the
> pin that will be connected to the DC motor.
>
> In my case I’ll be using GPIO 13. Note that for the Beetle ESP32
> board, which is the one I’m using, this maps to the pin labeled as D7.
>
>     int motorPin = 13;
>
> After that, we need to initialize the pin as output, in the Arduino
> setup function. To do that, we simply need to call the pinMode
> function.
>
> This function receives as first argument the number of the pin and as
> second argument a constant indicating the operating mode. So, we will
> pass the as first argument the value of the pin stored in our
> previously declared global variable and as second argument the
> constant OUTPUT.
>
>
>     void setup() {
>
>       pinMode(motorPin, OUTPUT);
>
>     }
>
> We will write the rest of our code in the Arduino main loop. We will
> first turn on the motor, wait some seconds, turn it off, wait some
> more seconds and then repeat.
>
> So, to turn the motor on, we simply need to set the value of the ESP32
> digital pin to high, which will make the motor run at full speed. We
> can set the digital level of a pin with a call to the digitalWrite
> function.
>
> This function receives as first argument the number of the pin and as
> second argument a constant indicating the digital level to which the
> pin should be set.

title: find out the pin numbers for the Arduino IDE for a certain board - the esp 32

Answers: 1

body:
An Arduino boards package with configuration for your board has constants for pins which correspond to labels on the PCB. The constants are defined in [pins_arduino.h file][1], which is applied only if you choose the corresponding board in Tools menu. In code you should use this constants as values for your constants, like for example `const uint8_t LED1_PIN = D2;`.

If the boards package doesn't have the board and you use generic settings, the you can study the schematics of the board to see which PCB pin goes to which MCU pin. Usually the logical pin numbers are labeled in schematics additionally to physical pin numbers of the chip.

Note: The linked pins_arduino.h is for FireBeetle ESP32. The Beetle ESP32 is not defined in ESP32 boards package yet.

The schematics is on [the Wiki page][2].

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

  [1]: https://github.com/espressif/arduino-esp32/blob/91e095f5a76ec35f06c86689a87892425395b8db/variants/firebeetle32/pins_arduino.h#L15
  [2]: https://wiki.dfrobot.com/Beetle_ESP32_SKU_DFR0575#target_4
  [3]: https://i.stack.imgur.com/ZVYzE.jpg


body:
I'm trying to make a menu through serial monitor, but it always on a infinite loop... My question is where i call this function? On Setup or on Loop?

The menu:

      int controle_opera = 0;

      void menu() {

   int i = -1;
   do {
  char opcao = '\0';
  Serial.println("\nQual operação deseja realizar?");
  Serial.println("\n1 - Cadastro");
  Serial.println("\n2 - Validação");
  Serial.println("\n3 - Deletar");
  Serial.println("\n4 - Apagar database");
  if (Serial.available()) {opcao = Serial.read();}
  switch (opcao) {
    case '1': controle_opera++;
    i++;
    break;
    case '2': controle_opera += 2;
    i++;
    break;
    case '3': controle_opera += 3;
    i++;
    break;
    case '4': controle_opera += 4;
    i++;
    break;
    default: Serial.println("Opção desconhecida, tente novamente!");
            delay(100);
            break;
  }
   } while(i != 0);
 }

title: Menu on Serial Monitor

Answers: 0


body:
EDIT: have solved the problem. It was missing the quotation marks around each letter. Thanks for your help, st2000!

------------

I am very new to Arduino and C++ (coding in general!). Have copied an example code, only modifying the notes to make my own tune. But when I click 'verify', I am getting the error above, and I can't for the life of me, work out what is wrong! I've searched and read several forums and FAQs, but am just coming up blank. This is the code I have, where the error is occuring:

      int melody[]={
        a,C,D,
        a,a,C,D,D,C,
        C,C,D,D,C,
        C,D,E,F,E,D,C};

Any help would be greatly appreciated!

title: expected primary-expression before ',' token

Answers: 1

body:
To answer your question we will assume your project is based on [the Melody example][1] at www.arduino.cc.

Likely you wanted to enter the [ASCII][2] values of these letters into an array of [type][3] char (type int would work as well.  But, in some cases, char would be more efficient).  To do this you need to place single quotes around each letter.  Specifically, you need to change your code:

    int melody[]={ a,C,D, a,a,C,D,D,C, C,C,D,D,C, C,D,E,F,E,D,C};

...so that your line of code look like this:

    int melody[]={'a','C','D','a','a','C','D','D','C','C','C','D','D','C','C','D','E','F','E','D','C'};

  [1]: https://www.arduino.cc/en/tutorial/melody
  [2]: https://en.wikipedia.org/wiki/ASCII
  [3]: https://en.wikipedia.org/wiki/C_data_types


body:
I have come across the following SPI slave code at [this][1] site:

    #include <SPI.h>

    char buf [100];
    volatile byte pos;
    volatile bool process_it;

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

      // turn on SPI in slave mode
      SPCR |= bit (SPE);

      // have to send on master in, *slave out*
      pinMode (MISO, OUTPUT);

      // get ready for an interrupt
      pos = 0;   // buffer empty
      process_it = false;

      // now turn on interrupts
      SPI.attachInterrupt();

    }  // end of setup

    // SPI interrupt routine
    ISR (SPI_STC_vect)
    {
    byte c = SPDR;  // grab byte from SPI Data Register

      // add to buffer if room
      if (pos < sizeof buf)
        {
        buf [pos++] = c;

        // example: newline means time to process buffer
        if (c == '\n')
          process_it = true;

        }  // end of room available
    }  // end of interrupt routine SPI_STC_vect

    // main loop - wait for flag set in interrupt routine
    void loop (void)
    {
      if (process_it)
        {
        buf [pos] = 0;
        Serial.println (buf);
        pos = 0;
        process_it = false;
        }  // end of flag set

    }  // end of loop

How to modify the above code so that it responds to input clock signal just like in [this][2] SSI protocol? Uno or Nano can be used.

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

Basically I want to let an arduino  act as an absolute encoder so that it will transmit 13-bit binary data(it can be any random fixed binary data) as shown in the above SSI protocol. So the Arduino will output 13-bit binary data along with with start bit and tm taken into account as shown in the document above without parity.

**The master's code I plan to use:**

    const int CLOCK_PIN = 2;
    const int DATA_PIN = 3;
    const int BIT_COUNT = 16;
    void setup() {
        pinMode(DATA_PIN, INPUT);
        pinMode(CLOCK_PIN, OUTPUT);
        digitalWrite(CLOCK_PIN, HIGH);
        Serial.begin(115200);
      }
    void loop() {
        float reading = readPosition();
        Serial.println(reading,2);
        delay(25);
      }

    //read the current angular position
    float readPosition() {
     unsigned long graysample = shiftIn(DATA_PIN, CLOCK_PIN, BIT_COUNT);
     delayMicroseconds(100); // Clock must be high for 20 microseconds before a new sample can be taken
    unsigned long binarysample = grayToBinary32(graysample);
     return ((binarysample * 360UL) / 65536.0); // ouptut value from 0 to 360 with two point percision
    }
    //read in a byte of data from the digital input of the board.
    unsigned long shiftIn(const int data_pin, const int clock_pin, const int bit_count) {
     unsigned long data = 0;
     for (int i=0; i<bit_count; i++) {
     data <<= 1; // shift all read data left one bit.

     //digitalWrite(clock_pin,LOW);
     PORTD &= ~(1 << 5); // clock pin goes low
     delayMicroseconds(1);
     //digitalWrite(clock_pin,HIGH);
     PORTD |= (1 << 5); // lock pin goes high
     delayMicroseconds(1);
     data |= digitalRead(data_pin); // cat the new read bit to the whole read data.
     }
     return data;
    }
    unsigned int grayToBinary32(unsigned int num)
    {
     num = num ^ (num >> 16);
     num = num ^ (num >> 8);
     num = num ^ (num >> 4);
     num = num ^ (num >> 2);
     num = num ^ (num >> 1);
     return num;
    }

  [1]: http://www.gammon.com.au/spi
  [2]: https://www.posital.com/media/posital_media/documents/AbsoluteEncoders_Context_Technology_SSI_AppNote.pdf
  [3]: https://i.stack.imgur.com/3bQ9c.png

title: How to modify this code to simulate a binary encoder?

Answers: 1

body:
You may try to bit-bang the protocol using [direct port access][]. This
is less convenient, but way faster than `digitalWrite()`. Below is an
example, untested program. I am assuming the pinout is

* data = PB0 = digital 8
* clock = PB1 = digital 9
* pins PB2 – PB5 (10 – 13) are unused

**Edit**: This updated program uses the clock as an input, and the data
as an output. The previous version used both lines as outputs, which was
due to a misunderstanding of mine.

```c++
#include <avr/io.h>

int main(void)
{
    uint16_t data = 0x155;

    DDRB  |= _BV(PB0);
    PORTB |= _BV(PB0);
    TCCR1B = _BV(CS10);  // start timer 1 @ F_CPU
    loop_until_bit_is_clear(PINB, PB1);

    for (;;) {
        loop_until_bit_is_set(PINB, PB1);
        PORTB = data & 1;
        data >>= 1;
        TCNT1 = -304;        // 20 us * 16 MHz - 16 cycles
        TIFR1 |= _BV(TOV1);  // clear overflow flag
        while (bit_is_set(PINB, PB1)) {
            if (bit_is_set(TIFR1, TOV1)) {  // timer overflowed
                PORTB = 1;  // data high
                data = 0x155;
                loop_until_bit_is_clear(PINB, PB1);
                break;
            }
        }
    }
}
```

This should be able to operate at frequencies up to about
200 – 250 kHz. There is a delay of about 0.5 µs
between the rising edges of the clock and the data been sent out, with a
jitter of 3 clock cycles.

The data word is sent least significant bit first, contrary to what the
protocol diagram shows. However, if you send arbitrary data, this should
not be an issue.

Note that this is a pure avr-libc program, which does not use the
Arduino core. It uses polling to check the inputs and the timer. The
interrupts are never enabled.

[direct port access]: https://www.arduino.cc/en/Reference/PortManipulation


body:
Disclaimer: I'm a total novice to Arduino so please forgive me if the question may seem trivial, I'm trying my best to learn :)

I'm working on a small project where I have a fingerprint sensor, a servo and an OLED display. The goal is to be able to register a fingerprint and then use the fingerprint to move the servo, whilst the OLED display gives instruction / messages to the user.

I noticed a few days ago an issue whereby my OLED wouldn't simply stop working if I had some Serial.println in my code. Without understanding the root cause, by trial and error I got to the conclusion that the issue was with that specific function, so I proceeded to remove it and everything went ok.

Then I noticed that the display stopped working also by adding extremely simple pieces of code that should not be related in ANY way to how the OLED works (at least to the best of my very limited knowledge).

The code below works as expected, each and every call to the oledPrint function yields the expected result on the OLED itself.

    #include <EEPROM.h>
    #include <Wire.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    #define OLED_RESET -1
    Adafruit_SSD1306 display(OLED_RESET);

    #include <Adafruit_Fingerprint.h>
    #include <SoftwareSerial.h>

    #define ISPRESSED LOW
    #define BASE_MAX 200
    #define MASTER_MAX 200

    SoftwareSerial mySerial(2, 3);

    Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

    uint8_t id;

    const int buttonRegisterPin = 8; // the number of the pushbutton pin - NOTE: RED BUTTON
    const int buttonRegisterMasterPin = 7; // the number of the pushbutton pin - NOTE: GREEN BUTTON
    const int buttonClearPin = 6; // the number of the pushbutton pin - NOTE: BLACK BUTTON
    const int buttonClearMasterPin = 12; // the number of the pushbutton pin - NOTE: YELLOW BUTTON

    const int baseState = HIGH;
    int ledStatus = HIGH;

    int baseCount;
    int masterCount;

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

      //initialize counters
      initializeCounters();

      //initialize buttons
      initializeButton(buttonRegisterPin);
      initializeButton(buttonRegisterMasterPin);
      initializeButton(buttonClearPin);
      initializeButton(buttonClearMasterPin);

      //initialize the fingerprint sensor
      initializeFingerPrintSensor();

      //initialize the OLED display
      initializeOledDisplay();

    }

    void loop() {

      bool skip = false;
      oledPrint("Welcome to your fingerprint locker");
      //base registration case
      if(digitalRead(buttonRegisterPin) == ISPRESSED && skip == false){

        while(!baseRegistration());
        skip = true;
      }

      //master registration case
      if(digitalRead(buttonRegisterMasterPin) == ISPRESSED && skip == false){

        while(!masterRegistration());
        skip = true;
      }

      //base clear case
      if(digitalRead(buttonClearPin) == ISPRESSED && skip == false){
        clearRegistrations(false);
        //do stuff for base clear
        skip = true;
      }

      //master clear case
      if(digitalRead(buttonClearMasterPin) == ISPRESSED && skip == false){

        //do stuff for master clear
        skip = true;
      }
    }

    /**
     * Initializes a button
     * @Param: buttonPin = number of the pin used by the button
     */
    void initializeButton(int buttonPin){
      pinMode(buttonPin, INPUT_PULLUP);
    }

    /**
     * Initializes the OLED display
     */
    void initializeOledDisplay(){
      Wire.begin();
      if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
        Serial.println(F("SSD1306 allocation failed"));
        for(;;);
      }
      delay(2000);
      display.clearDisplay();

      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(0, 10);
    }

    /**
     * initializes the fingerprint sensor
     */
    void initializeFingerPrintSensor(){
      finger.begin(57600);

      if (finger.verifyPassword()) {
        Serial.println("Found fingerprint sensor!");
      }
      else {
        Serial.println("Did not find fingerprint sensor :(");
        while (1) { delay(1); }
      }
    }

    boolean baseRegistration(){
      boolean check = false;
      int tempBaseCount = baseCount + 1;
    /*
      if(tempBaseCount > BASE_MAX){
        oledPrint("Too many users already registered");
        return true;
      }*/
      oledPrint("Starting registration");
      while(check == false){

        oledPrint("Please put your finger on the reader");

        id = tempBaseCount;
        if (id == 0) {// ID #0 not allowed, try again!
           return;
        }

        if(getFingerprintEnroll(tempBaseCount, false)){
          check = true;
        }
      }
      return check;
    }

    boolean masterRegistration(){
      boolean check = false;
      int tempMasterCount = baseCount + 1;
    /*
      if(tempMasterCount > MASTER_MAX){
        oledPrint("Too many master keys already registered");
        return true;
      }
      */
      oledPrint("Starting master key registration");

      while(check == false){

        oledPrint("Please put your finger on the reader");

        id = tempMasterCount;
        if (id == 0) {// ID #0 not allowed, try again!
           return;
        }

        if(getFingerprintEnroll(tempMasterCount, true)){
          check = true;
        }
      }
      return check;
    }

    boolean clearRegistrations(bool master){
      if(master){
        //to do
      }
      else{
        //increaseBaseCounter(0);
        id = 900;
        int p = finger.deleteModel(id);
        if(p == FINGERPRINT_OK){
         // Serial.println("success");
         // Serial.println(p);
          return true;
        }
       // Serial.println("FAIL");
       // Serial.println(p);
        return false;
      }
    }

    // returns -1 if failed, otherwise returns ID #
    int getFingerprintIDez() {
      uint8_t p = finger.getImage();
      if (p != FINGERPRINT_OK)  return -1;

      p = finger.image2Tz();
      if (p != FINGERPRINT_OK)  return -1;

      p = finger.fingerFastSearch();
      if (p != FINGERPRINT_OK)  return -1;

      // found a match!
      oledPrint2Lines("Match found, ID #", finger.fingerID);
     /* Serial.print("Found ID #");
      Serial.print(finger.fingerID);
      Serial.print(" with confidence of ");
      Serial.println(finger.confidence);*/
      return finger.fingerID;
    }

    uint8_t getFingerprintEnroll(int count, bool master) {
      int p = -1;
      while (p != FINGERPRINT_OK) {
        p = finger.getImage();
        switch (p) {
        case FINGERPRINT_OK:
          //oledPrint("Image taken");
          break;
        case FINGERPRINT_NOFINGER:
          break;
        case FINGERPRINT_PACKETRECIEVEERR:
          oledPrint("Communication error");
          break;
        case FINGERPRINT_IMAGEFAIL:
          oledPrint("Imaging error");
          break;
        default:
          oledPrint("Unknown error");
          break;
        }
      }

      // OK success!

      p = finger.image2Tz(1);
      switch (p) {
        case FINGERPRINT_OK:
          //oledPrint("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          oledPrint("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
          oledPrint("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
          oledPrint("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
          oledPrint("Could not find fingerprint features");
          return p;
        default:
          oledPrint("Unknown error");
          return p;
      }

      oledPrint("Remove finger");
      delay(2000);
      p = 0;
      while (p != FINGERPRINT_NOFINGER) {
        p = finger.getImage();
      }
      p = -1;
      oledPrint("Place the same finger again");
      while (p != FINGERPRINT_OK) {
        p = finger.getImage();
        switch (p) {
        case FINGERPRINT_OK:
          //oledPrint("Image taken");
          break;
        case FINGERPRINT_NOFINGER:
          break;
        case FINGERPRINT_PACKETRECIEVEERR:
          oledPrint("Comunication error");
          break;
        case FINGERPRINT_IMAGEFAIL:
          oledPrint("Imaging error");
          break;
        default:
          oledPrint("Unknown error");
          break;
        }
      }

      // OK success!

      p = finger.image2Tz(2);
      switch (p) {
        case FINGERPRINT_OK:
          //oledPrint("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          oledPrint("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
          oledPrint("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
          oledPrint("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
          oledPrint("Could not find fingerprint features");
          return p;
        default:
          oledPrint("Unknown error");
          return p;
      }

      // OK converted!

      //oledPrint2Lines("Creating model number:", count);

      p = finger.createModel();
      if (p == FINGERPRINT_OK) {
        //oledPrint("Prints matched!");
      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        oledPrint("Communication error");
        return p;
      } else if (p == FINGERPRINT_ENROLLMISMATCH) {
        oledPrint("Fingerprints did not match");
        return p;
      } else {
        oledPrint("Unknown errro");
        return p;
      }

      p = finger.storeModel(id);
      if (p == FINGERPRINT_OK) {
        if(master == false){
          oledPrint2Lines("Registered with id number:", count);
          increaseBaseCounter(count);
        }
        else{
          oledPrint2Lines("Registered master key number:", count - 50);
          increaseMasterCounter(count);
        }
        return 1;
      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        oledPrint("Communication error");
        return p;
      } else if (p == FINGERPRINT_BADLOCATION) {
        oledPrint("Could not store in that location");
        return p;
      } else if (p == FINGERPRINT_FLASHERR) {
        oledPrint("Error writing to flash");
        return p;
      } else {
        oledPrint("Unknown error");
        return p;
      }
    }

    uint8_t readnumber(void) {
      uint8_t num = 0;

      while (num == 0) {
        while (! Serial.available());
        num = Serial.parseInt();
      }
      return num;
    }

    void oledPrint(char* text){

      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.println(text);
      display.display();
      delay(2000);
    }

    void oledPrint2Lines(char* text, int val){

      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.print(text);
      display.print(val);
      display.display();
      delay(2000);
    }

    void initializeCounters(){
      //address 0 is BASE
      baseCount = EEPROM.read(0);
      Serial.println(baseCount);
      //address 1 is MASTER
      masterCount = EEPROM.read(1);
      if(masterCount < 50)
        masterCount = 50; //will get to 51 once first registered - 51 = master key #1
      Serial.println(masterCount);
    }

    void increaseBaseCounter(int count){
      baseCount = count;
      EEPROM.write(0, baseCount);
    }

    void increaseMasterCounter(int count){
      masterCount = count;
      EEPROM.write(1, masterCount);
    }

However, if I uncomment the code in the baseRegistration and/or masterRegistration functions (see code snippet below), the display starts to act up: some text is displayed, some other isn't, some other again is displayed partially. I just can't find a sensible explanation anywhere, and being used to work on much higher abstraction levels this is to me completely absurd :D

    boolean baseRegistration(){
      boolean check = false;
      int tempBaseCount = baseCount + 1;
    //PART THAT CAUSES ISSUES - STARRT
      if(tempBaseCount > BASE_MAX){
        oledPrint("Too many users already registered");
        return true;
      }
    //PART THAT CAUSES ISSUES - END
      oledPrint("Starting registration");
      while(check == false){

        oledPrint("Please put your finger on the reader");

        id = tempBaseCount;
        if (id == 0) {// ID #0 not allowed, try again!
           return;
        }

        if(getFingerprintEnroll(tempBaseCount, false)){
          check = true;
        }
      }
      return check;
    }

Even more oddly, if I remove the part above from those two functions and I had one more simple call to the fingerprint sensor in the loop function, the OLED just stops working altogether (and again, absolutely crazy for me :P).
See below the loop function with the addition of the line that breaks the OLED altogether:

    void loop() {

      bool skip = false;
      oledPrint("Welcome to your fingerprint locker");
      //base registration case
      if(digitalRead(buttonRegisterPin) == ISPRESSED && skip == false){

        while(!baseRegistration());
        skip = true;
      }

      //master registration case
      if(digitalRead(buttonRegisterMasterPin) == ISPRESSED && skip == false){

        while(!masterRegistration());
        skip = true;
      }

      //base clear case
      if(digitalRead(buttonClearPin) == ISPRESSED && skip == false){
        clearRegistrations(false);
        //do stuff for base clear
        skip = true;
      }

      //master clear case
      if(digitalRead(buttonClearMasterPin) == ISPRESSED && skip == false){

        //do stuff for master clear
        skip = true;
      }

      int fingerprintID = getFingerprintIDez(); //THIS IS THE LINE
      delay(50);

    }

I just don't know how to proceed, if any of you would be so kind to help a novice out I'd be extremely grateful!
Thanks in advance to anyone who could point me in the right direction!!

For the sake of completeness, I'm using the adafruit libraries for the fingerprint sensor as well as the oled.

title: OLED display hectic behavior - interference with other parts of the code?

Answers: 1

body:
Your program seems to fit well inside the Arduino Uno memory. If your output is displaying correctly through the serial monitor, there also seems nothing wrong with your data sent to the display.
Have you tried connecting pull-up resistors to the SDA and SCL lines? Resistors around 3.9k work fine for me when using OLED displays.


body:
I'm wondering if Arduino is able to not just measure sound and work based on hearing a sound that is "loud enough", but if it is able to identify a specific sound (say the first few seconds of a song). Is this possible, and how would one go about doing so?

If identifying the first few seconds of a song isn't really feasible, is it at least possible to do so with a consistent (but particular) pitch (rather than a general loudness threshold)?

title: Arduino recognize specific sound?

Answers: 3

body:
It sounds like you need to do Fourier analysis on the sound. (Breaking up the sound into its component frequencies.) Most Arduinos are based on AVR chips, which do not have hardware support for floating point math. They use software to do floating point, which makes them a poor choice for this sort of thing.

There are FFT libraries for Arduino, but they will be slow and fairly crude. You'd probably be better off using a board like a Raspberry Pi that has an ARM processor for signal processing like this.

body:
No, you cannot recognize a song with an Arduino. It doesn't have enough computing power. I think most solutions, that recognize a song, are based on some kind of machine learning or similar, which is totally out of scope for an Arduino. For this you need a real processor like on a Raspberry Pi or similar Single Board Computers.

Identifying a specific pitch/frequency in a sound signal is possible, but you shouldn't expect great accuracy. As Duncan already wrote in his answer, you need a Fourier transformation for this. It transforms the audio signal (voltage level dependent on time) into the frequency domain (amplitude dependent on frequency). So, if you do a fourier transformation on a short audio signal, you get data about, what frequencies are in that signal with which amplitudes. You can then wait for a peak in a specific frequency range.

Doing a FFT (Fast Fourier Transformation) on an Arduino is slow and not accurate. You also only have very limited memory. So your analysed audio signals will be rather short.

---

There is another way to detect a specific pitch/frequency, which is more a hardware task. You can feed the audio signal into an RC resonator circuit, which is tuned to the frequency, that you are interested in. The circuit will amplify the frequency, that it is tuned to, and dampen all other frequencies (of course it is not really one specific frequency, but a small range of frequencies). The resulting signal can then be checked for threshold values, since it only contains frequencies around the tuning frequency.

body:
As stated in other answers, sound recognition is completely out of the
realm of what an Arduino can do, but recognizing a specific pitch is
possible.

However, contrary to previous answers, I would recommend _against_ using
an FFT. The FFT is the right tool when you need to get _all_ the
frequency components. It is, however, overkill when you want to look at
a single frequency. Given the low processing power at your disposal, I
suggest you try instead an [homodyne detection][] scheme. An Arduino
Uno, or similar board, has enough resources to sample an input at
9.6 kHz, and extract in real time a specific frequency component.
See for example this [homodyne detection program][program].

[homodyne detection]: https://en.wikipedia.org/wiki/Homodyne_detection

[program]: https://gist.github.com/edgar-bonet/0b03735d70366bc05fc6


body:
I have an Arduino Pro Micro, with atmega32u4 chip and a caterine bootloader. However, every time I (successfully) flash some program over the USB port, the `/dev/ttyACM0` device disappears, and I cannot flash it any more over USB.

So I connect it to my stk500v2-compatible ISP programmer (MISO/MOSI/SCK go to pins 14,16 and 15 on the board; VCC,GND,RST to their counterparts). With this setup, I can flash a new Caterina bootloader onto it. The problem with flashing over the board's USB port stays, though.

So I tried to set the lock byte with the ISP programmer, which writes successfully, but then fails at verification:
```
> avrdude -p m32u4 -P /dev/ttyUSB0 -c stk500v2 -b 115200 -U lock:w:0x0F:m
...
avrdude: verification error, first mismatch at byte 0x0000
         0xcf != 0x0f
```

Is my assumption correct that the disappearing bootloader is caused by the wrongly set (un-)lock bits? If yes, why can't I set the lock byte via ISP?

title: Cannot write lock byte on Arduino Pro Micro

Answers: 1

body:
Meanwhile, I managed to solve this problem.
The reason for the verification error is that the two most significant bits of the Lock Byte are read-only on my variant of the Arduino Pro Micro. Which means that, if you (try to) write a value of `0x00 = 0b0000 0000`, it will result in a value of `0b1100 0000 = 0xC0` on the hardware.
The solution, then, was to simply ignore those two bits.
```
> avrdude -p m32u4 -P /dev/ttyUSB0 -c stk500v2 -b 115200 -U lock:w:0xCF:m
```


body:
I have a project where I need to use multiple load cells (6-8), with individual HX711 for each load cell, which need to be powered simultaneously. I am not sure if I can power all the HX711 with 5V and GND pins of Arduino Mega or I need to use a separate 5V DC power supply and connect the VCC and GND of HX711 pins to it and connect the DT and SCK pins to the digital pins of the Mega. Will such an arrangement work?  Thanks for your time in advance. The link to the HX711 datasheet is [here][1].

  [1]: https://cdn.sparkfun.com/datasheets/Sensors/ForceFlex/hx711_english.pdf

title: Advice needed for powering Multiple HX711 with Arduino Mega

Answers: 0


body:
I'm using an Arduino MKR WiFi 1010, a SAMD ARM Cortex M3 board. I rely on the standard library a lot, using things like `std::vector<>` and `std::string`. I also want to use `std::cout`. I've managed to do this on an UNO R3 using the ArduinoSTL library, but that library neither works nor is necessary on the MKR WiFi 1010, because it has all the standard library stuff built in to the platform.

However, on MKR WiFi 1010, I cannot get `std::cout` to produce any output. I'm guessing its not really hooked up to anything.

I want `std::cout` to write to `Serial` (which is aliased to `SerialUSB` which is of type `Serial_`).

Is there a way of making `std::cout` write to the `Serial` stream?

title: How can I make std::cout write to Serial?

Answers: 1

body:
The ARM gcc libraries offer a simple way to redirect standard outputs. It is enough to implement function `_write(int fd, char *ptr, int len)` and it will replace the default implementation used in library to direct the standard outputs to debugger semihosting. The function must be compiled as  C to match.

    #include <Arduino.h>
    #undef max
    #undef min
    #include <stdio.h>
    #include <iostream>

    using namespace std;

    extern "C" {
    int _write(int fd, char *ptr, int len) {
      (void) fd;
      return Serial.write(ptr, len);
    }
    }

    void setup() {

      Serial.begin(115200);
      while (!Serial);

      Serial.println("START");

      printf("HERE WE ARE\r\n");

      cout << "TEST COUT\r\n";
      cerr << "TEST ERR\r\n";
    }

    void loop() {

    }

the `#undefs` undefine the Arduino macros, which are in conflict with includes used in `<iostream>`


body:
I am relatively new to adruino and this whole space. I am currently trying to power a DC motor using an ESP12E motor shield and an ESP8266 Module

Motor Shield - https://www.amazon.com/gp/product/B078CPZDW1/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

ESP8266 - https://www.amazon.com/gp/product/B010O1G1ES/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

DC Motor - https://www.amazon.com/gp/product/B07MTT7B88/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

Here is my code

    #define DIRA 0
    #define PWMA 5
    #define LED 2

    void setup() {
      Serial.begin(9600);
      Serial.println();
      Serial.println("Starting...");

      Serial.println("Preparing motor...");
      pinMode(DIRA, OUTPUT);
      pinMode(PWMA, OUTPUT);
      analogWrite(PWMA,0);
      digitalWrite(DIRA,1);
      delay(5000);

      Serial.println("Starting motor...");
      analogWrite(PWMA,5);
      delay(5000);

    }

    void loop() {
    }

Here is how I have wired it up

[![schematic][1]][1]

**Note: This setup is similar to what I have but not exactly, I have 4 AA batteries connected and only 2 motors**

I am expecting the motor to start once I upload this code but nothing is happening. If I change the analogWrite to digitalWrite, the motor runs but I want to be able to control the speed, rather than just having it run at one speed.

I have tested using analogWrite by changing the intensity of an LED and it was working, although the output pin was not the same as the one I use for the motor.

Would greatly appreciate any help as I have already gone through pages of google searches without any luck. I have been using this example as a reference, https://hackaday.io/project/8856-incubator-controller/log/29291-node-mcu-motor-shield.

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

title: ESP12E motorshield analogWrite issue when powering DC motor

Answers: 1

body:
This answer is the summary of the comments of the question. The idea of the solution was originally mentioned by @Majenko.

You powered the shield with about 6 Volts. The statement `analogWrite(PWMA, 5);` gives you (5/1024) ~ 0.5% of this 6 Volts at the output pin PWMA. This 0.03V are not enough to drive the motor.

You should use at least 3 Volts to drive the motor (as of the specs).
This can be achieved by using a duty cycle of the PWM signal of about 50%.  `analogWrite(PWMA, 512);` should do the trick.


body:
the project i'm working on is a weather station out door and for that i need to to give arduino at least some sort of protection from moisture.

https://www.instructables.com/id/Arduino-Weather-Station-AWS/

putting arduino in a box might work but the humidity where i live is very high it's rain a lot but the cold is not much. looking for ideas to waterproof arduino board please.

also can arduino work everyday of year without problem?

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

title: Waterproofing Arduino

Answers: 1

body: You can just solder everything you need to the Arduino (I would recommend using an Arduino Mini since it has no communication port) and coat it with Silicon Conformal Coating. It creates a silicon layer on top of the PCB that would not let any moisture through. Or you can just put it in a case and cover it with epoxy, that will be even more protection, but there will be no more access to the board unless you foresee it.


body:
I am using a mosfet (IRFZ44N) to control a dc motor, and a separate one to control a led strip. Both are using the same circuit running to different pwm pins on the arduino.

The light strip is working fine (can be turned on an off as expected), but the motor runs at a low level when the pin sends a LOW state, and revs up when it is sent a HIGH state.

They are both receiving power from the VIN pin of the arduino which in turn in plugged into a 12v 6a dc adaptor.

Any ideas what could cause this behavior?

(Apologies if this is a messy schematic, I am a beginner)

[![schematic][1]][1]

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

title: Mosfet controlled motor runs while LOW

Answers: 1

body:
There are some mistakes in the provided schematic:

  - the nmos has to be connected to motor-

  - the freewheeling diode has to be the other way around

  - the resistor doesn't make sense. If it's meant to be a pulldown is has to connect the gate with ground and have a much higher value (~10kOhm). If it's meant to be an inrush limiter it has to be in series with the gate

Actually I don't trust you schematic at all, because I wonder why the motor runs at all without damaging your arduino. Have a look at the low-side transistor configuration [here][1] to see how it is done.

As I mentioned in a comment, this mosfet is a bad choice because it has a too high gate-source threshold voltage Vgs,th (that's the gate voltage at which the transistor **starts** to conduct. The voltage at which it has the specified on-resistance Rds,on is several times higher than this. Choose a device with a Vgs,th below 1V or go for a logic-level mosfet.

  [1]: https://www.baldengineer.com/low-side-vs-high-side-transistor-switch.html


body:
I've done a simple aurduino sketch, I have this code, and this don't work:

    #define voltageInput A0
    int qntR;
    float mr;
    float qr;
    float Distanza;
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(voltageInput,INPUT);
      mr=(130-20)/float(1023-205);
      qr=20-mr*205;
      Serial.print(mr,4);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      qntR=analogRead(voltageInput);
      Distanza=mr*qntR+qr;
      Serial.print("Distanza: ");
      Serial.print(Distanza);
      Serial.print(" cm");
      Serial.println("");
    }

And the I have this code:

    #define voltageInput A0
    int qntR;
    float mr;
    float qr;
    float Distanza;
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(voltageInput,INPUT);
      mr=(130-20)/(1023-205);
      qr=20-mr*205;
      Serial.print(mr,4);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      qntR=analogRead(voltageInput);
      Distanza=mr*qntR+qr;
      Serial.print("Distanza: ");
      Serial.print(Distanza);
      Serial.print(" cm");
      Serial.println("");
    }

In which I have delete the `float` from `mr=(130-20)/float(1023-205)`;,and if I delete the float the code stop working (`mr` is always equal to 0), why?

title: Cannot understand why this code work but this not

Answers: 1

body:
Your problem is that you are doing integer maths.

    mr = (130-20)/(1023-205)

reduces to:

    mr = 110/818

Which normally equates to:

    mr = 0.135

But since all those numbers are integers the result is an integer, and is truncated at the decimal point, which means that `mr` is assigned:

    mr = 0

You can force floating point maths by either including a decimal point in one of the numbers, or adding the suffux `f`:

    mr = (130-20)/(1023-205.0)

or

    mr = (130-20)/(1023-205f)

Or casting a portion of the sum to a float as your other code does.


body:
Apparently, this combination of hardware won't accept anything other than WiFiEsp.h together with SoftwareSerial.h (if anyone knows something better/newer than these two, please let me know).
Thing is: I can connect to wifi, send and receive data (to an apache server inside my home network) just fine. After my project was almost done, I decided to connect it to a real server on the internet only to discover that ESP-01 couldn't detect my gateway.

    #include "WiFiEsp.h"
    #include "SoftwareSerial.h"

    int pinWifiRX = 6;
    int pinWifiTX = 7;

    char ssid[64]    = "*****";
    char pass[32]    = "************";

    SoftwareSerial Serial1(pinWifiRX, pinWifiTX);

    int wifi_status;

    void setup() {

      Serial.begin(9600);

      Serial1.begin(9600);
      while(!Serial1) (true);

      WiFi.init(&Serial1);

      if (WiFi.status() == WL_NO_SHIELD) {
        Serial.println(F("No shield"));
        while (true) {}
      }

      IPAddress localIp(192, 168, 1, 60);
      IPAddress subnetMask(255, 255, 255, 0);
      IPAddress gateway(192, 168, 1, 36);

      WiFi.config(localIp);  // <--- this line is accepted and works, but the other 3 gives compilation errors
    //  WiFi.config(localIp, gateway);
    //  WiFi.config(localIp, gateway, subnetMask);
    //  WiFi.config(localIp, gateway, subnetMask, gateway);

      wifi_status = WiFi.begin(ssid, pass);

      if (wifi_status == WL_CONNECTED) {

        IPAddress ip;

        ip = WiFi.localIP();
        Serial.print(F("[WiFiEsp] IP Address: "));
        Serial.println(ip);

        ip = WiFi.subnetMask();
        Serial.print(F("[WiFiEsp] Subnet Mask: "));
        Serial.println(ip);

        ip = WiFi.gatewayIP();
        Serial.print(F("[WiFiEsp] Gateway: "));
        Serial.println(ip);

    //    ip = WiFi.getDNS();  // <--- function doesn't exist
      }

    }

    void loop() {}

Results in:

    [WiFiEsp] Initializing ESP module
    [WiFiEsp] Initilization successful - 2.2.1
    [WiFiEsp] IP address set 192.168.1.60
    [WiFiEsp] Connected to *****
    [WiFiEsp] IP Address: 192.168.1.60
    [WiFiEsp] Subnet Mask: 255.255.255.0
    [WiFiEsp] Gateway: 192.168.1.0

As one can see, Subnet Mask is corret, but it "detects" Geteway **192.168.1.0** when it should be **192.168.1.36**. This way, I can connect to any device in LAN, but cannot access any address on the internet.

I even tried to send some AT commands directly to SoftwareSerial.h, but I don't get any response.

Will I have to start the whole project over from scratch (using another hardware combination), or is there a way to change gateway by hand? Better yet, is there a way to make it detect the gateway's address correctly?

EDIT: could it be related to the firmware I installed to the ESP-01? I followed [this tutorial][1] and got it from [this link][2].

Thanks in advance.

**EDIT: in this example, i used the WiFi.config(localIp) function to set a fix IP. I don't really need that, it was just an attempt to make it get the correct Gateway address. Even if I comment that line, the Gateway is still wrong.**

  [1]: https://blogmasterwalkershop.com.br/embarcados/esp8266/upgrade-de-firmware-do-wifi-esp8266-esp-01-atraves-do-arduino-e-conversor-usb-serial/
  [2]: https://blogmasterwalkershop.com.br/arquivos/firmware/Ai-Thinker_ESP8266_DOUT_8Mbit_v1.5.4.1-a_20171130.bin

title: ESP-01 + UNO won't detect gateway

Answers: 2

body:
Using a static IP address with a gateway is not implemented (as you can see from [the source code](https://github.com/bportaluri/WiFiEsp/blob/master/src/WiFiEsp.h#L86)).

To get out to the internet with that library you can only use DHCP (by omitting the `WiFi.config(localIp)` call).

body:
I've had some progress in my researches towards this problem.

In fact, Arduino gets the correct gateway address from my DHCP server, but displays the wrong one. There must be a bug somewhere in WiFiEsp library somewhere.

To debug this, I made a few changes to the following files:

- WiFiEsp-Master/src/WiFiEsp.h

>     void config(IPAddress local_ip, IPAddress gateway);
>     void config(IPAddress local_ip, IPAddress gateway, IPAddress subnetMask);

- WiFiEsp-Master/src/WiFiEsp.c

>     void WiFiEspClass::config(IPAddress ip, IPAddress gateway)
>     {
>       EspDrv::config(ip, gateway);
>     }
>     void WiFiEspClass::config(IPAddress ip, IPAddress gateway, IPAddress subnetMask)
>     {
>       EspDrv::config(ip, gateway, subnetMask);
>     }

- WiFiEsp-Master/src/utility/EspDrv.h

>     static void config(IPAddress local_ip, IPAddress gateway);
>     static void config(IPAddress local_ip, IPAddress gateway, IPAddress subnetMask);

- WiFiEsp-Master/src/utility/EspDrv.cpp

>     void EspDrv::config(IPAddress ip, IPAddress gateway) {
>       LOGDEBUG(F("> config"));
>
>       // disable station DHCP
>       sendCmd(F("AT+CWDHCP_CUR=1,0"));
>
>       // it seems we need to wait here...
>       delay(500);
>
>       char buf_ip[16];
>       sprintf_P(buf_ip, PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
>
>       char buf_gateway[16];
>       sprintf_P(buf_gateway, PSTR("%d.%d.%d.%d"), gateway[0], gateway[1], gateway[2], gateway[3]);
>
>       int ret = sendCmd(F("AT+CIPSTA_CUR=\"%s\",\"%s\""), 2000, buf_ip, buf_gateway);
>       delay(500);
>
>       if (ret==TAG_OK)
>       {
>         LOGINFO1(F("IP and gateway addresses set"), buf_ip);
>       }
>     }
>
>     void EspDrv::config(IPAddress ip, IPAddress gateway, IPAddress subnet)
>     {
>
>       LOGDEBUG(F("> config"));
>
>       // disable station DHCP
>       sendCmd(F("AT+CWDHCP_CUR=1,0"));
>
>       // it seems we need to wait here...
>       delay(500);
>
>       char buf_ip[16];
>       sprintf_P(buf_ip, PSTR("%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]);
>
>       char buf_gateway[16];
>       sprintf_P(buf_gateway, PSTR("%d.%d.%d.%d"), gateway[0], gateway[1], gateway[2], gateway[3]);
>
>       char buf_subnet[16];
>       sprintf_P(buf_subnet, PSTR("%d.%d.%d.%d"), subnet[0], subnet[1], subnet[2], subnet[3]);
>
>       int ret = sendCmd(F("AT+CIPSTA_CUR=\"%s\",\"%s\",\"%s\""), 4000, buf_ip, buf_gateway, buf_subnet);
>       delay(500);
>
>       if (ret==TAG_OK)
>       {
>         LOGINFO1(F("IP, gateway and subnet mask addresses set"), buf_ip);
>       }
>     }

These few changes should be enough to implement fix IP address and specify manual address for gateway and subnet mask (please feel free to correct me if I'm wrong).

But after doing this, I realized the gateway continued to be "192.168.1.**0**". Then I added this piece o code to the function EspDrv::readUntil, inside EspDrv.cpp:"

   ringBuf.push(c); // this line was already there
   Serial.print(c);

This way, I could see exactly all responses for the AT commands sent by WiFiEsp library. When asked, the results were:

    +CIPSTA:ip:"192.168.1.60"
    +CIPSTA:gateway:"192.168.1.36"
    +CIPSTA:netmask:"255.255.255.0"

Then I realized the problem wasn't the gateway, but the DNS. If the library sends command "AT+CIPSTART=3,"TCP","www.google.com",80", the result was:

    Not connected

    busy p...

And, if increased the timeout value to 15000 instead of 5000, the result was:

    DNS ERROR

Now my problem is partially solved. I can connect to an external server if I use an IP address, but I can't set a domain name because it won't be resolved by the DNS.

Apparently the firmware version of my ESP-01 won't accept "AT+CDNSCFG=?" required to set/retrive DNS address. I tried to set 8.8.8.8 as the DNS, but the result was "NOT OK".

I will stick to this "solution" for now, but would be glad to hear any comment about what I described here and a more final solution.

Thanks.