message:
Connect arduino nano and ESP32 with I2C on the GPIO7 and GPIO8?

I made a mistake connecting SD0 (GPIO7) and SD1 (GPIO8) with the SDA and SCL on my arduino nano. I got confused with GPIO21 and pin21 and GPIO22 and pin 22!

Since I made a PCB prototype, I would avoid to add some wires and cut the traces, so I would ask if I could use these pins (GPIO7 and GPIO8) as SDA and SCL.

If the answer is affirmative, using Arduino library how could I assign them?

Wire.begin (7,8)?

Another question, I would use a dedicate 2x4.7K pull up resistors. On the arduino side I wrote:

digitalWrite(SDA, 0);
digitalWrite(SCL, 0);

It is correct to do the same thing on the ESP32 side?

Update November 01:
After the question from Majenco I think I need more help for the I2c setup.

I designed the PCB having in mind that the esp32 was 5V tolerant, so at the moment I pull-up the SDA, SCL from the 5V that I input in the esp power pin. Note that this 5V doesn't come from the Nano due to the high current required by the esp. I take my 12V power supply input and regulate it to 5V with a 7805, only dedicated to the esp (I know, a lot of dissipation! In the next PCB version I have to change the things, having in mind that I need both 12V and 5V in my circuit).

Now, I read that the esp32 is not 5V tolerant. In order to avoid level shifter can I pull up the SDA and SCL from the 3.3V line (the arduino 3.3V or esp32 one?)?

I would use the esp32 as master.

Thanks.

body:
> Since I made a PCB prototype, I would avoid to add some wires and cut the traces, so I would ask if I could use these pins (GPIO7 and GPIO8) as SDA and SCL.

No, you can't. Those pins are used by the internal flash chip. If you connect things to them you will end up not being able to read the flash and thus won't be able to run any code.  In other words, the chip will not boot. So you will have to bite the bullet and cut traces and add bodge wires.

> Wire.begin (7,8)?

Yes. That will control the bus matrix to route the I2C through different pins - but of course you can't use those pins, as noted above.

> On the arduino side I wrote:
>
> digitalWrite(SDA, 0); digitalWrite(SCL, 0);
>
> It is correct to do the same thing on the ESP32 side?

No. That exploits a quirk in the AVR GPIO system that doesn't exist in the ESP32. In the ESP32 the pins are configured with:

    pinMode(sda, OPEN_DRAIN | PULLUP | INPUT | OUTPUT );

and

    pinMode(scl, INPUT | PULLUP);

so you could *try* replicating that in your code but without the `PULLUP` flag. However the effect of this is unknown, so YMMV.

However, if your external pullups are pulling up to 3.3V then you really don't need to do anything on the ESP32. All you end up with is a large resistance in parallel with your 4.7kΩ, which will just cause your resistance to drop slightly (and since 4.7kΩ is arguably too high any way that's a good thing).


sender: user

message:
When does interrupt get fired

When does the ISR mapped to SPI_STC_vect (SPI transmission complete) get fired? Does it fire after a byte has been received (eight clock cycles) of when the slave select changes back to high to deselect the slave?
Or: does "transmission" mean the transmission of a byte or the whole bunch of bytes that belong to the command sequence?

sender: assistant

body: It fires after a single byte has been sent or received (the two are one and the same). This is because there is only room for one byte in the buffer, so you need to get it out of that buffer (or put a new one in) after each 8-bit transfer.


message:
Esp8266 + Atmega328p as flash

Being clear I'm **not talking about** **How to flash ESP8266 using arduino**.
I want to ask **how can I use atmega328p as flash with esp8266** (instead of that 8 pin small chip on ESP-01) so that I can burn Webserver code on Atmega328p and it simply works with esp8266?

Thanks in advance.

body:
It can't be done (also, why would you think that would ever be a good idea?!)

The 8 pin chip on the ESP-01 is a 512kB SPI flash that runs at (at least) 40MHz.  So to emulate that you would need:

* More than 512kB of flash,
* A slave SPI interface that can operate at a minimum of 40MHz, and
* The knowledge, time and energy to write the firmware to emulate an SPI flash chip

The first two are certainly beyond an ATMega328P with 32kB flash and an 8MHz maximum speed SPI interface. The third is probably beyond you since you have to ask the question in the first place (which shows a certain lack of knowledge on what it is you are proposing).

There are plenty of examples for creating a web server using an ESP8266 using either the standard AT firmware or by directly programming the ESP8266's flash chip through the ESP8266's built-in UART bootloader.  Personally I find the use of AT firmware clumsy at best and prefer to always program my ESP8266's directly.  If you feel the need to also add an ATMega328P into the mix for some reason then the communication protocol that you use between them is entirely up to you.


message:
Measuring Battery level with ADC already in use

I have NodeMCU v3 with ESP8266 and I am running small project where I am measuring the input from IR phototransistor via ADC pin (A0) and everything is working flawlessly.
But now I want to transfer it to battery source (powerbank -> microUSB) and I want to be able to tell the remaining battery capacity, but all tutorials I found were going through switching ADC(A0) to internal, thus disabling it.
Is there any other way I can either measure the battery OR input from phototransistor?
Thanks!

body:
As @dandavis rightly says in the comments, you can't measure the battery voltage from a power bank.  This is because the power bank typically includes a step-up converter to turn the batter voltage (3.2 to 4V) into a stable 5V.  That 5V will alwaye be 5V (or thereabouts) until the battery runs out and the power bank shuts itself off.

To measure the battery state you will have to directly interface with the batteries (disassemble the power bank) and tap into the battery terminals themselves.

Some power banks also have LEDs in them to display the power remaining. It could be possible to interface directly with these as well.

One thing to note, though, is that using a power bank for an ESP8266 board is pretty silly.  You are taking nominal 3.6V, stepping it up to 5V, then linearly dropping it back down to 3.3V again.  Both stages involve power wastage - the 5V to 3.3V most of all (a linear regulator turns the waste voltage into heat).

You would be better removing the batteries from the power bank and wiring them directly to the power input - or better still, feed them through a high efficiency switching regulator to get a stable 3.3V and feed that directly into the 3.3V pin.  be sure to include some way of monitoring the battery voltage and shutting off the power when it gets too low. Since your ADC input is already in use the simplest way is to add an external ADC chip to your design.


message:
Audio stops playing after rtc is connected

I am trying to play a song using arduino while at the same time display time using a rtc board using the tmrpcm library. However, if the rtc board is connected no sound is played.

I do understand that the tmrpcm may be interfering with the wire.h library but even commenting the same doesn't resolve the problem.

I am using the following code:

~~~
// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <RTClib.h>
#include<Wire.h>
#include <Arduino.h>
#include "SevenSegmentTM1637.h"
#include "SevenSegmentExtended.h"
#include "SevenSegmentFun.h"
#include "SD.h"
#define SD_ChipSelectPin 4
#include "TMRpcm.h"
#include "SPI.h"

TMRpcm tmrpcm;

const int ProxSensor=3;
int inputVal = 0;
#define CLK 8
#define DIO 7

// The amount of time (in milliseconds) between tests
#define TEST_DELAY   2000

SevenSegmentFun    display(CLK, DIO);

RTC_DS1307 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup () {
  Serial.begin(9600);
  if(!SD.begin(SD_ChipSelectPin))
  {
    Serial.println("SD fail");
    return;
  }
  while (!Serial); // for Leonardo/Micro/Zero
  tmrpcm.speakerPin=9;
  Serial.begin(57600);
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(2019, 10, 19, 01,41,00));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
  pinMode(ProxSensor,INPUT);    //Pin 2 is connected to the output of proximity sensor
  display.begin();
}

void loop(){
  DateTime now = rtc.now();
  display.print((now.unixtime() / 86400L )-17963);
  Serial.print((now.unixtime() / 86400L )-17963);
  while(digitalRead(ProxSensor)==LOW)      //Check the sensor output
  {
    tmrpcm.setVolume(5);
    tmrpcm.play("test.wav");
      repeat:
    if(digitalRead(ProxSensor==LOW))
      goto repeat;
  }
}
~~~

Can anyone please help me?

body: The TMRpcm and one of your other libraries might use the same timer on Uno which causes one of them to break. Either get a Arduino Mega which can run TMRpcm on TIMER3,4 or 5 or use libraries that don't require a timer.


body:
The problem is

    repeat:
    if(digitalRead(ProxSensor==LOW))
      goto repeat;

`ProxSensor==LOW` is false so 0. **you read the pin 0** and the outcome is random. The surrounding wiring can affect that. If digitalRead(0) is zero the wav starts playing immediately again. At least use

    while (digitalRead(ProxSensor) == LOW);


message:
Laser Controller using Arduino Uno

---> I am trying to create a controller using Arduino Uno that simply detects pulses from a waveform generator mimicking a Laser Machine and then switches between 4 state machines states at the output of a Pre-amp, it is a built on of this [previous post][1] so the connections are the same except for the waveform generator settings. The new waveform generator settings are :

**Type: Pulse, Freq:20Hz (50ms), Amp:5.0 Vpp, Offset:0V, Width = 100ns**

---> I am trying to add 5 things in the project so any input is greatly appreciated:

  1) **Initialize** all the **4 state machine states** into an **Array** so user can define as many states as they want from the declarations.

  2) **ADD a digital** de-bounce to the input pin, **LASER_PIN**.

  3)(requires item #5 to be done first)  **ADD a reset** to the system which moves the program back to **STATE_00**  from whatever it is doing.

  4) Better code to wait until a pulse from Laser arrives before going to the state machine in **void loop()**.

  5) (item #2 depends on this) Completely **Remove** delay from the **CountPulses()** function and replace with **millis()** function to allow the use of reset button

---> Here is what i have so far, i started off by adding 4 state machine states and using the **delay()** function in the **CountPulses()** function just like in the previous post and it works fine and i am able to switch states while counting pulses, however, when i added the **millis() to replace delay()** function as shown below in the code, **i only get** **0s** in pulse count and the state machine is **stuck** in **STATE_00** so i used a couple of print statements to debug  and it turns out currentmillis() - startmillis() is actually less than period = 1000ms so i am stuck on how to set this up and without this i cannot move forward, any help would be appreciated. My code and serial monitor results are shown below:

--> **UPDATE**: items #3 and #5 work perfectly fine , please see updated code. for item #4 i have not figured this one out yet. for item #2 ,there are a lot of libraries for debounce but not sure which libraries (Button, Bounce and etc) are most trusted by arduino community, any suggestions would help.

-->**UPDATE 2:** The code has been update with the following changes, external interrupts are used to reset the system if switch is LOW, Polling with interrupts is used to wait for pulses.

**THE UPDATE TO QUESTION**: items#3, 4 and 5 were solved and now only 2 items remain to be added to the project with modifications to item #1 and item #2 based on comments:

1) I require the state machine to do the following:

 a) Declared in an array where user can easily change the order of execution of states. (eg: state_2--> state_1 -->state_3--> state_0).

  b) User can easily decrease the number of states from MAX_VALUE = 4 to only 1 state. (eg with MAX_VALUE = 3: state_0--> state_1--> state_2)  .

2) **ADD a digital** de-bounce to the input pin, **RESET_PIN**.
Note: The debounce to LASER_PIN was a mistake in understanding based on the comments, so i have updated this.

Updated code with current serial monitor results is shown below:

           //Objectives: Use input from laser to control pre-amp on adc. Multiplex the inputs on Pre-Amp
    //Date:10/21/2019
    //Type: Pulse, Freq:20Hz (50ms), Amp:5.0 Vpp, Offset:500mV, Width = 100ns

    //-----------------------PROJECT LIBRARIES----------------------------------
    #include <Bounce2.h>
    #include <Arduino.h>
    #include <avr/io.h>
    #include <avr/wdt.h>
    #include <avr/interrupt.h>
    //-----------------------DEFINES------------------------------------------
    //Declare Laser Input Pin
    #define LASER_PIN 2

    //Declare Reset Pin
    #define RESET_PIN 3

    //Define the states of the machine
    typedef enum {STATE_00, STATE_01, STATE_10, STATE_11} fsm_state_type;
    fsm_state_type fsm_state = STATE_00;

    // -------------------------CONSTANTS (won't change)-------------------------------------
    const unsigned long period = 1000;  //the value is a number of milliseconds

    //-------------------------VARIABLES (will change)-------------------------------------
    bool only_for_print = false;//used only for print state ments

    int reset_switch = 1;//Start HIGH to avoid reset
    int PulseCount = 0; //Pulse count from X-RAY
    int Output = 0;//Switch state on the Pre-Amp
    int wait = 0;//wait for pulses count
    int N = 20;//no. of pulses to count before switching states
    volatile int IRQcount = 0;
    volatile boolean reset_flag = false;

    unsigned long start_time = 0;
    unsigned long current_time = 0;

    //----------------------------USER DEFINED FUNCTIONS---------------------------------
    void fsm();
    void loop();
    void setup();
    void WDT_RESET();
    void IRQcounter();
    void CountPulses();
    //-----------------------------DEBOUNCE FUNCTIONS---------------------------------------

    //--------------------------------MAIN SETUP--------------------------------------

    void setup()
    {

      Serial.begin(115200);

      //Pin Setup
      pinMode(LASER_PIN, INPUT_PULLUP);
      pinMode(RESET_PIN, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(LASER_PIN), IRQcounter, RISING);//attach interrupt handler to laser input
      attachInterrupt (digitalPinToInterrupt (RESET_PIN), RESET_ISR, FALLING);  // attach interrupt handler to reset, wait for user press button or switch
      start_time = millis();   //initial start time
      sei();//Turn on Interrupts

        WaitForPulses();//Waits to detect 20 pulses
    }

    //--------------------------------MAIN LOOP----------------------------------
    void loop()
    {

     current_time = millis();
     fsm();//State machine
    }

    //--------------------------------PULSE COUNT FUNCTION--------------------------------------------

    void CountPulses()
    {
      //  current_time = millis();
      if ((current_time - start_time) >= period)
      {
        start_time = current_time;
        cli();//disable interrupts
        PulseCount = IRQcount;
        IRQcount = 0;
        Serial.print(F("Pulse Count is = "));
        Serial.println(PulseCount);
        sei();//enable interrupts
      }
    }

    //--------------------------------STATE MACHINE FUNCTION--------------------------------------------
    void fsm()
    {
      switch (fsm_state)
      {

        case STATE_00:

    /////////Print Statement only for debugging//////////
            while (only_for_print == false)
            {
                Serial.println("The state is 00");
                only_for_print = true;
            }

    ///////// Count Pulses Setup /////////////////
                current_time = millis();
                CountPulses();
                Output = 0;
                if (PulseCount == N)
                {
                  PulseCount = 0;//Reset Pulse Count
                  only_for_print = false; //used only for print statments
                  fsm_state = STATE_01;//switch to next state
                }
          break;

        case STATE_01:
    /////////Print Statement only for debugging//////////
          while (only_for_print == false)
          {
              Serial.println("The state is 01");
              only_for_print = true;
          }

    ///////// Count Pulses Setup /////////////////
              current_time = millis();
              CountPulses();
              Output = 2;
              if (PulseCount == N)
              {
                PulseCount = 0;//Reset Pulse Count
                only_for_print = false; //used only for print statments
                fsm_state = STATE_10;//switch to next state
              }
          break;

        case STATE_10:
    /////////Print Statement only for debugging//////////
          while (only_for_print == false)
          {
              Serial.println("The state is 10");
              only_for_print = true;
          }

    ///////// Count Pulses Setup /////////////////
              current_time = millis();
              CountPulses();
              Output = 3;
              if (PulseCount == N)
              {
                PulseCount = 0;//Reset Pulse Count
                only_for_print = false; //used only for print statments
                fsm_state = STATE_11;//switch to next state
              }

          break;

        case STATE_11:
    /////////Print Statement only for debugging//////////
          while (only_for_print == false)
          {
              Serial.println("The state is 11");
              only_for_print = true;
          }
    ///////// Count Pulses Setup /////////////////
              current_time = millis();
              CountPulses();
              Output = 4;
              if (PulseCount == N)
              {
                PulseCount = 0;//Reset Pulse Count
                only_for_print = false; //used only for print statments
                fsm_state = STATE_00;//switch to next state
              }

          break;

        default:
          fsm_state = STATE_00;
          break;
      }

    }

    //----------------------------------RESET SWITCH ISR-------------------------------------

    void RESET_ISR()
    {
      reset_flag = true;
      if(reset_flag == true)
        {
         // Serial.println("System will now Reset");// Only for debugging
          reset_flag = false;//Reset reset switch flag
          wdt_enable(WDTO_500MS);//Reset after 0.5 seconds
          while (1)
           {
             // wdt_reset();          // uncomment to avoid reboot
           }
        }
    }

    //-----------------------PULSE COUNT ISR---------------------------------------

    void IRQcounter()
    {
      IRQcount++;
    }
    //-----------------------WAIT FOR PULSES---------------------------------------
    void WaitForPulses()
    {
      while(wait<20)
     {
        if (bit_is_set(EIFR, INTF0))
        {
          Serial.println("Pulse is detected ");
          wait++;
        }
     }
     wait = 0;//reset
    }
    */

[![edited image][3]][3]

  [1]: https://electronics.stackexchange.com/questions/464324/counting-pulses-using-arduino-uno/464357?noredirect=1#comment1171115_464357
The serial monitor is shown below with added reset switch on pin 3 using watch dog timer library .

     Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    Pulse is detected
    The state is 00
    Pulse Count is = 112
    Pulse Count is = 20
    The state is 01
    Pulse Count is = 20
    The state is 10
    Pulse Count is = 20
    The state is 11
    Pulse Count is = 20
    The state is 00
    Pulse Count is = 20
    The state is 01
    Pulse Count is = 20
    The state is 10
    Pulse Count is = 20
    The state is 11
    Pulse Count is = 20
    The state is 00
    Pulse Count is = 20
    The state is 01
    Pulse Count is = 20
    The state is 10
    Pulse Count is = 20
    The state is 11
    Pulse Count is = 20
    The state is 00
    Pulse Count is = 20
    The state is 01
    Pulse Count is = 20
    The state is 10
    Pulse Count is = 20
    The state is 11
    Pulse Count is = 20

body:
### Important note:

*After reading (again) your other question and its answers: **You are stressing the input of your Arduino with negative voltages!** Please set the offset of the signal to 2.5V (the middle between GND and VCC) and the amplitude to 5Vpp. **The signal must neither be lower than GND nor higher than VCC!** The input might withstand this for a while but given enough time and power it **will** get damaged.*

### Analysis of your problem:

**1. The measurement of the period**

Let's take a look at a "condensed" version of your time code:

    void setup()
    {
      startMillis = millis();
    }

    void loop()
    {
      currentMillis = millis();
      if (currentMillis - startMillis <= period)
      {
        startMillis = currentMillis;
      }
    }

I'm sure you see it now, too! Because right at the first call of `loop()` the time passed since `setup()` is short, the condition is `true` and `startMillis` is updated to the current time. This is repeated ever and ever again. The condition will always evaluate as `true`.

**2. The number of pulses**

In the function `CountPulses()` the counter is reset at the beginning. Then after some undefined very short duration (because your `if`-condition is always `true`) it is read. Chances are low for a pulse to be counted in that time span.

### Additional note:

Just one more tip. You can define and use your own data types to show your intentions. For example the states look so much better like shown below, and you'll get free error messages from code analyzers.

    typedef enum {
        STATE_00, STATE_01, STATE_10, STATE_11,
    } fsm_state_type;
    fsm_state_type fsm_state = STATE_00;

**EDIT after you added new informations:**

### Item #2

Why do you think you need to debounce the laser pulse? Is it generated by a mechanical switch? Only those need debouncing. If the pulses are generated from some electronic circuit they should be clean.

### Item #4

You can reset the `IRQcount` and then wait for it to count up.

But as this involves disabling and enabling the interrupt and reading an `int` just for **1 event**, I'd rather set a flag if the interrupt occurs. Then the FSM could wait for the flag to be set.

Another alternative is to poll the input pin directly and to wait for the leading edge. But for this the pulse has to be wide enough.

As @EdgarBonet pointed out it will be even simpler to poll the interrupt flag. But IIRC the interrupt has to be disabled for this, else the call of the interrupt service routine will clear the flag with no chance for the main program to see it.

> A better alternative is to poll the interrupt flag (i.e. `if (bit_is_set(EIFR, INTF0)) { ... }`). Then you don't need a wide pulse: once the hardware detects the rising edge, the flag is set and remains set until you explicitly clear it (`EIFR = _BV(INTF0);`).


message:
WifiManager and WiFi functionally

I’m considering using `wifiManager` mostly to have the ability not to hard code WiFi creditntials.
But In my current code I use WiFi’s functions as `WiFi.setAutoReconnect(true)` and `WiFi.status() != WL_CONNECTED`

How can it be done using `WifiManager`?

body:
You don't. WifiManager does all that for you. You don't need anything like that in your code. Just follow the examples and read the documentation.

But if you do want to then you just need to remember that WifiManager is merely a library that configures the WiFi for you. If you want to query or alter the WiFi settings you can - exactly as you are right now. The two aren't mutually exclusive.


body:
Here's a working example that's on my Wemos D1 Mini. It stands up an AP until you provide credentials for your local LAN, then displays it's DHCP IP address on a 16x2 LCD and stands up a webserver. Once the credentials are stored it won't stand up the AP, it will just reconnect and do the main loop() of the sketch. To force the AP to restart you need to call the `ESP.reset();` method to flush the stored credentials and reboot the Wemos.

    #include <LiquidCrystal_PCF8574.h>
    #include <ESP8266WiFi.h>

    #include <WiFiManager.h>
    #include <ESP8266WebServer.h>
    #include <Wire.h>

    WiFiClient wemosCL;

    ESP8266WebServer server(80);

    const int led = LED_BUILTIN;

    LiquidCrystal_PCF8574 lcd(0x38);

    void handleRoot() {
      digitalWrite(led, 1);
      server.send(200, "text/html", "<title>ESP8266 Demo</title>
Hello from ESP8266!

IP Addr: " +
              WiFi.localIP().toString() + "
");

      digitalWrite(led, 0);
    }

    void handleNotFound() {
      digitalWrite(led, 1);
      String message = "File Not Found\n\n";
      message += "URI: ";
      message += server.uri();
      message += "\nMethod: ";
      message += (server.method() == HTTP_GET) ? "GET" : "POST";
      message += "\nArguments: ";
      message += server.args();
      message += "\n";
      for (uint8_t i = 0; i < server.args(); i++) {
        message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
      }
      server.send(404, "text/plain", message);
      digitalWrite(led, 0);
    }

    void setup(void) {
      Serial.begin(115200);
      WiFiManager wifiManager;
      wifiManager.autoConnect("Wemos", "configuration");
      pinMode(led, OUTPUT);
      digitalWrite(led, 0);

      lcd.begin(16, 2);
      lcd.setBacklight(255);
      lcd.print("I'm alive");

      // Wait for connection
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        lcd.setCursor(0, 0);
        lcd.print(".");
      }

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Status:Connected");
      lcd.setCursor(0, 1);
      lcd.print("IP:");
      lcd.print(WiFi.localIP());

      server.on("/", handleRoot);

      server.onNotFound(handleNotFound);

      server.begin();
    }

    void loop(void) {
      server.handleClient();
    }


message:
5v relay module and bulb holder

![enter image description here](https://i.stack.imgur.com/5rqjG.jpg)![enter image description here](https://i.stack.imgur.com/zi6mJ.jpg)

Hello sir , so can i cut the switch from the picture and connect the wires to my relay module ? Im sorry because im still learning . Thank you !

body:
A relay is nothing more than a switch - but instead of your finger controlling it, it's controlled by an electromagnet.

The relay can perform the exact same function as the switch on that cable.  In the image you have posted you would use the right-hand two screw terminals (middle is "common", right is "normally open") to replace the switch.


body:
You can refer to this to cut the switch [![enter image description here][1]][1]

If you are a beginner, you can [get started with Relay here][2]

NOTE: It's dangerous and can cost your life. Please be careful when using Relay with 220 VAC

  [1]: https://i.stack.imgur.com/0vPDz.jpg
  [2]: https://arduinogetstarted.com/tutorials/arduino-relay


message:
Creating and Arduino synthesizer without the tone library

I am thinking about trying to make an Arduino synthesizer using the true analog output on the Due. However I would like to be able to play multiple notes at the same time on a single buzzer. Is this possible and how would I do it?

body:
Sound is nothing else than a multiple simple waves combined in to one. So, theoretically you can play as many sounds (tones) as you like on a single pin. If you want to go true analog than you probably want to use a sin wave to generate sound. However, in that case you can do the following:
Either make a function that would be capable of generating a sin wave of your desired frequency. In case of true analog this would probably be done by calculating actual sin values and using the [map()][1] function mapping 0 - 1 to 0 - 1024 and writing to the pin. The frequency can be adjusted by changing the delay between each step of changing the voltage or [DAC][2] value. However, this will not allow for multiple frequencies.
Alternatively for multiple frequencies to be played at the same time you would need to calculate the [Fourier inversion][3] of all the waves you want to play and send the results of that to the [DAC][2].

  [1]: https://www.arduino.cc/reference/en/language/functions/math/map/
  [2]: https://en.wikipedia.org/wiki/Digital-to-analog_converter
  [3]: https://en.wikipedia.org/wiki/Fourier_inversion_theorem


body:
You just have to add the waveforms. For example, if you want to play
pure tones (the simplest and most boring timbre), you generate a sine
wave for each of them and add them together:

```c++
struct Note {
    float frequency;
    float phase;
    bool is_active;
} notes[MAX_NOTES];

void output_sample()
{
    static uint32_t previous_time;
    uint32_t now = micros();
    uint32_t elapsed_time = now - previous_time;
    previous_time = now;
    float output = 0;
    for (int i = 0; i < MAX_NOTES; i++) {
        Note *note = &notes[i];
        if (note->is_active) {
            output += cos(note->phase);
            note->phase += 2*M_PI*note->frequency*1e-6*elapsed_time;
            if (note->phase >= 2*M_PI) {
                note->phase -= 2*M_PI;
            }
        }
    }
    analogWrite(DAC_PIN, 2048 + round(output * (2047.0 / MAX_NOTES)));
}
```

The function `output_sample()` should be called as frequently as
possible. You can change the `notes` array any time to add, remove or
change notes.

There is some room for optimization here, like:

* storing `2*M_PI*note->frequency*1e-6` as the “frequency” in order to
  save some calculations

* using a wave table instead of the `cos()` function (I don't know how
  good is the Due at transcendental math)

* replacing `elapsed_time` by a constant if you can manage to output the
  samples at a fixed rate.

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

**Edit**: I wrote “You can change the `notes` array any time to add,
remove or change notes.” Here is how to start or stop a note, i.e. to
add or remove it from the list of active notes:

```c++
// Start a note. Returns an index to be used with stop_note(), or -1 if
// we couldn't start the note because we are already outputting the
// maximum number of simultaneous notes.
int start_note(float frequency)
{
    int i;  // index of the note in the notes[] array

    // Find a free slot in the array.
    for (i = 0; i < MAX_NOTES; i++)
        if (!notes[i].is_active) break;  // found

    // Couldn't find a free slot?
    if (i == MAX_NOTES) return -1;

    // Setup the note parameters.
    notes[i].frequency = frequency;
    notes[i].phase = 0;
    notes[i].is_active = true;
    return i;
}

// Stop the note with the given index.
void stop_note(int index)
{
    if (index >=0 && index < MAX_NOTES)
        notes[index].is_active = false;
}
```


message:
How to merge two GPS coordinates without losing decimals

I want to take the GPS coordinates like **42.1234** per **22.1234** and merge them as a string, with a separator character:

`42.1234 x 22.1234`

But using this code:

`gps_string = (String)gps.location.lat()+' x '+(String)gps.location.lng();`

I lose the last decimals and I get:

`42.12 x 22.12`

The only way I could see full coordinates is by specifying an extra parameter to println, like this:

`Serial.println(gps.location.lat(), 6);`

How can I create a string containing both two coordinates without losing decimals ? e.g `42.1234 x 22.1234`

body:
If you want 4 decimal places, you may try something like this:

```c++
gps_string = String(gps.location.lat(), 4)
           + " x "
           + String(gps.location.lng(), 4);
```


message:
Serial.println Issue with Flame Sensor

I'm really new to coding and Arduino so I would be eternally grateful for the help.

I'm trying to make a really basic flame sensor that beeps, lights up an LED and displays the distance from the sensor to the flame when activated. I keep getting a "'Serial' does not name a type" error message for the line that reads - Serial.println(analogRead(A0));

I’ve tried to figure it out from the information on this forum of similar questions to try to correct the issue but it seems like every time I fix one thing another 2 errors come up. I’ve been stuck on this one for a little while so I’m hoping I might be able to receive some kind of assistance from the Arduino community.

Below is the entire code - any help is appreciated, thanks :)

    int Led = 4;
    int Buzz = 7;
    int Sensor = 11;
    int Fire = HIGH;
    void setup()
    { Serial.begin(9600);
    pinMode(Buzz,OUTPUT);
    pinMode(Sensor,INPUT);
    pinMode(Led,OUTPUT);
    }
    void loop()
    {
    Fire = digitalRead(Sensor);
    if(Fire == HIGH);
    Serial.print("analog Read = ");
    Serial.print(analogRead);
    }
    Serial.println("HELP! A FIRE!");
    digitalWrite(Buzz,HIGH);
    digitalWrite(Led,HIGH);
    delay(200);
    digitalWrite(Led,LOW);
    delay(200);
    Serial.println(analogRead(A0));
    }
    else
    {
    Serial.println("No fire detected");
    digitalWrite(Buzz,LOW);
    digitalWrite(Led,LOW);
    }
    delay(500);
    }

body:
First things first; please INDENT YOUR CODE. The code you posted is a mess and I took at least double the time to fix that.

First, you have an extra closing curly bracket at line 17 and the `if (Fire == High);` should be changed to `if (Fire == High){`

Fixed code:
~~~
int Led = 4;
int Buzz = 7;
int Sensor = 11;
int Fire = HIGH;
void setup()
{
  Serial.begin(9600);
  pinMode(Buzz,OUTPUT);
  pinMode(Sensor,INPUT);
  pinMode(Led,OUTPUT);
}
void loop()
{
  Fire = digitalRead(Sensor);
  if(Fire == HIGH){
//Serial.print("analog Read = ");
//Serial.print(analogRead);
    Serial.println("HELP! A FIRE!");
    digitalWrite(Buzz,HIGH);
    digitalWrite(Led,HIGH);
    delay(200);
    digitalWrite(Led,LOW);
    delay(200);
    Serial.println(analogRead(A0));
 }
 else
 {
    Serial.println("No fire detected");
    digitalWrite(Buzz,LOW);
    digitalWrite(Led,LOW);
  }
  delay(500);
}
~~~


message:
Converting human readable date to a unix timestamp

Can anyone provide a sample code that would convert a human readable date like `2019-10-27 22:10:35` to a unix timestamp like `1572214235`?

I found many topics about it, but they eider refer to out of date libraries, or they seem to address more complex time functions, I find it hard to extract this functionality from them.

body:
If you have a fixed format you can use `strtok()` to slice the string into individual segments, then convert those segments to integers. They can then be used with `TimeLib.h` with the `setTime()` function.  You can then query TimeLib for the unix timestamp with `now()`.

**Edit:** using [PaulStoffregen's TimeLib][1], this code sets current time and returns current unix timestamp.

```C++
#include <TimeLib.h>

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

  // hour, min, sec, day, month, year
  setTime(22, 30, 11, 29, 3, 2019);

  // 1553898611
  Serial.println(now());
}
void loop() {}
```

**Edit 2:** And to convert **any** given date to a unix timestamp (without setting current time):

```C++
#include "TimeLib.h"

tmElements_t my_time;  // time elements structure
time_t unix_timestamp; // a timestamp

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

  // convert a date and time into unix time, offset 1970
  my_time.Second = 0;
  my_time.Hour = 23;
  my_time.Minute = 0;
  my_time.Day = 25;
  my_time.Month = 3 - 1;      // months start from 0, so deduct 1
  my_time.Year = 2017 - 1970; // years since 1970, so deduct 1970

  unix_timestamp =  makeTime(my_time);
  Serial.println(unix_timestamp);
}

void loop() {}
```

  [1]: https://github.com/PaulStoffregen/Time


body:
After parsing the time into numbers, you can use the standard C time library `time.h`. More specifically, use the `mktime` [function][1] to convert a `struct tm` into a `time_t`, and use `difftime` to get the seconds since the start of the Unix expoch:

    #include <time.h>

    void loop() {
        struct tm ltm = {0};
        ltm.tm_year = 2019 - 1900;
        ltm.tm_mon  = 11 - 1;
        ltm.tm_mday = 5;

        int32_t epoch_seconds = difftime(mktime(&ltm), (time_t)0);
        Serial.print("Remember, remember, ");
        Serial.print(epoch_seconds);
    }

Note that in `struct tm`, the year starts at 1900 and the month starts at 0.

  [1]: https://en.cppreference.com/w/c/chrono/mktime

EDIT: In avr-libc, `difftime` returns an `int32_t`, not a `double`.


message:
FastLED library: How can I adjust the brightness of a single pixel on an absolute scale?

I'm using the [FastLED][1] library to control a digital RGB LED strip.

While this library seems very comprehensive in capability and ease of use, I do not yet see a way to simply set the brightness value of a *individual* pixel on an *absolute scale*. In other words, I want to simply set the brightness of a pixel, without passing a hue or saturation, and without it effecting other pixels.

`FastLED.setBrightness()` scales down the brightness of all pixels.
`leds[i].fadeLightBy()` scales down an individual pixel, but if it's called again for the same pixel before updating the LEDs, then the pixel will be faded again from it's already-faded value.

Is there truly no built-in method for setting the brightness of individual pixels to a particular value?

  [1]: https://github.com/FastLED/FastLED/wiki/Pixel-reference

body:
There is no dedicated function to adjust brightness.

You can (however) do this by using the HSV color model.

**Breaking HSV (Anachronism) into Parts:**

**H** (Hue) Controls the Color itself.

**S** (Saturation) of the Color.

**V** is called Lightness or Value.

**'V'** is what you want to control.

Just set the LEDs color to a HSV value and change it's V value.

    leds[i] = HSV(color, saturation, brightness);

While 'Color' and Saturation' remain the same (to keep the same color), you can change the 'Brightness' directly on the third parameter.

Note that 'leds[i]' is still defined as 'CRGB', not as 'HSV'.

This assignment uses an implicit conversion, that is defined in the library.

You can see the 'HSV' usage example within the 'Cylon' example on the FastLED library.

There you will find the Hue value that gets changed; but it is the same principle as 'brightness'.

Now there is a problem to solve.

The FastLED library can convert 'HSV' Colors to 'RGB' Colors; but not the other way round.

So you cannot simply get the 'hue' and Saturation from an 'RGB' Color with this library.

**You have 2 Alternatives:**

**1.** You can just define an extra LEDs array with HSV colors and synchronize both arrays to contain the same data (everytime you want to change a color, you would set a 'HSV' color in the second array, convert that array to 'RGB' by using 'CRGB(hsv_leds[i])' and save that in the first array, which get's used by the FastLED library).

This is relatively easy, but you effectively need double the memory for storing the color values.

This is not an issue, if you have enough memory or few enough LEDs to control.

**2.** You can write your own function to convert 'RGB' values to 'HSV'; then use it to access the 'hue' and 'Saturation' values for the targeted 'RGB' Color, create a new 'HSV' Color with it and the new 'Brightness' and use it to set the 'RGB' values for the FastLED library.

In [this forum thread][1] there is a brief discussion about that, though it leaves you with the implementation yourself.

I think there are suitable implementations, that can be found on the web.

A quick search gave me [this code][2] from github gist.
I have not tested it, so I cannot say, if it really works correctly, but you should give it a try.
I'm sure there are also other implementations.

  [1]: https://forum.arduino.cc/index.php?topic=493488.0
  [2]: https://gist.github.com/fairlight1337/4935ae72bcbcc1ba5c72


message:
Can I get some help with a metronome code on my arduino uno?

ok so I dont actually know anything about coding or electronics outside of being an electrician. This is something i've been working on for about a month.
I may be asking something dumb but here it is.

also i dont know where to put my code so ill put it in the comments (sorry).

so basically I want a visual metronome. I want to plug a control box into the wall, plug a lamp into the control box to blink at a set interval. the box will have a rotary encoder and lcd display to control the beats per minute. to achieve this im gonna use a SSR and some transformers to achieve a variety of voltages for different led lights. but I want to affect a 120v cct to do it all. but I just want to get the code down before I build it so im trying to blink the onboard led on my arduino uno for now.

I have the code, which is 3 different sketches, frankensteined together. probably poorly.
I added an arithmetic equation to facilitate the metronome timing but I cant transfer that value to the "interval" for the blinking light.

In my serial viewer, the equation works and it gives me the values I desire. I just cant get that into the interval.

the math equation is simple
(60/bpm)1000 = intended interval

example: (60/120)1000 = 500 as the milli interval for the blinking light. 2 blinks per second.

    enter code here

    // rotary encoder -----------------

    int val;
    int encoder0PinA = 6;
    int encoder0PinB = 7;
    int encoder0Pos = 59;
    int encoder0PinALast = LOW;
    int n = LOW;

    // lcd screen ---------------------

         // include the library code:
    #include <LiquidCrystal.h>

         // initialize the library with the numbers of the interface pins
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    // led blink ----------------------

         // the number of the LED pin
    const int ledPin =  LED_BUILTIN;

         // ledState used to set the LED
    int ledState = LOW;

         // will store last time LED was updated
    unsigned long previousMillis = 0;

         // interval at which to blink (milliseconds) --    long interval = ;

    // mathssss -----------------------

    float a = (60 / encoder0Pos) * 1000;

    // on to setup -------------------------------------------------------

    void setup() {
          // put your setup code here, to run once:

    // rotary encoder ---------------
     pinMode (encoder0PinA, INPUT);
      pinMode (encoder0PinB, INPUT);
      Serial.begin (9600);

      Serial.println ("hi");

    // lcd screen -------------------
          // set up the LCD's number of columns and rows:
      lcd.begin(16, 2);
          // Print a message to the LCD.
      lcd.print("BeatsPerMinute");

    // led blink -------------------
    pinMode(ledPin, OUTPUT);

    }

    // on to loop --------------------------------------------------------
    void loop() {
          // put your main code here, to run repeatedly:
          long interval = (60.00 / encoder0Pos) * 1000;

    // rotary encoder --------------
      n = digitalRead(encoder0PinA);
      if ((encoder0PinALast == LOW) && (n == HIGH)) {
        if (digitalRead(encoder0PinB) == LOW) {
          encoder0Pos--;
        } else {
          encoder0Pos++;
        }

         // serial ----------------------------------------------------------------------
      Serial.println ("BPM");
      Serial.println (encoder0Pos);
      Serial.println ("interval");
      Serial.println (interval);
      Serial.println ("intended interval");
      Serial.println (60.00 / encoder0Pos * 1000, 8);
      Serial.println ("----------------");
         // serial done -----------------------------------------------------------------
      }
      encoder0PinALast = n;

      // lcd screen ----------------

           // set the cursor to column 0, line 1
           // (note: line 1 is the second row, since counting begins with 0):
      lcd.setCursor(0, 1);
           // print the number of seconds since reset:
      lcd.print(encoder0Pos);

      // led blink -----------------

        unsigned long currentMillis = millis();

      if (currentMillis - previousMillis >= interval) {
          previousMillis = currentMillis;
        if (ledState == LOW) {
          ledState = HIGH;
        } else {
          ledState = LOW;
        }

        digitalWrite(ledPin, ledState);

     // serial --------------------

     // done

      }

    }

body:
As I wrote in my comment, you don't actually set the value of `interval` to the new value, when the encoder position changes. So the blinking interval does not change. You need to use the formula to set the new value to `interval`. Insert

    interval = 60.00 / encoder0Pos * 1000;

before your `Serial.print()` statements. Also, you need to remove the `const` keyword at the definition of `interval`, or you won't be able to change it's value.

---

Judging from your comments, you misunderstand how variables work. A variable does not save a formula, just a value. `a` is defined at global scope in your code (outside of any function). That means, that the definition get's executed at the very start of the program. Since `encoder0Pos` has the value 59 at that time, the value `1016.95` get's assigned to the variable `a`. This value only ever changes, if you actively assign a new value to that variable (which you never do). The formula is only executed once during the assignment.


message:
I am making a rubber band gun but i cant seem to get the button to work with my code to turn the servo?

#include <Servo.h>
    const int buttonPin = 3;
    int buttonState = 0;

    Servo myservo;
    void setup() {
        myservo.attach(2);
        pinMode(buttonPin, INPUT);
    }

    void loop() {
        buttonState = digitalRead(buttonPin);
        if (buttonState == HIGH){ myservo.write(90); }
        else { myservo.write(155); }
        delay(1000);
    }

body:
Just put your button between pin3 and GND, and use the internal pullup resistor like this:
```
#include <Servo.h>
const int buttonPin = 3;
int buttonState = 0;

Servo myservo;
void setup()
{
    myservo.attach(2);
    pinMode(buttonPin, INPUT_PULLUP);
}

void loop()
{
    buttonState = digitalRead(buttonPin);
    if(buttonState == LOW)
    {
      myservo.write(90);
    }
    else
    {
      myservo.write(155);
    }
    delay(1000);
}
```


body:
There are two problems you should pay attention to when using the button:

 - Floating input: => using pull-up or pull-down resistor, [see Using pull-up/ pull-down][1]
 - Chattering phenomenon => Debounce [See button debounce][2]

  [1]: https://arduinogetstarted.com/tutorials/arduino-button
  [2]: https://arduinogetstarted.com/tutorials/arduino-button-debounce


message:
Addressable RGB strip works fine individually but cannot set all LEDs to full white

I have a 5 meter strip of 12V digital RGB LEDs. The chip is WS2811 (see photo of IC). There are 50 addresses on the strip.

[![WS2811 IC][2]][1]

Using the [FastLED library][3], I am able to run the "FirstLight" example that chases full white with a single address at a time, up and down the length. That works fine. So I know they individually perform properly.

However, if I set all LEDs to full white (255), the first few addresses look white but then the higher the address, the more red it is. See photo below. The strip starts in the center of the reel.

[![All white WS2811 issue][4]][4]

    #include <FastLED.h>

    // How many leds are in the strip?
    #define NUM_LEDS 50

    // Data pin that led data will be written out over
    #define DATA_PIN 5

    // This is an array of leds.  One item for each led in your strip.
    CRGB leds[NUM_LEDS];

    // This function sets up the ledsand tells the controller about them
    void setup() {
     // sanity check delay - allows reprogramming if accidentally blowing power w/leds
        delay(2000);
     Serial.begin(115200);
     Serial.print("### SETUP ###");

          //Both strips are ordered BRG
          FastLED.addLeds<WS2811, DATA_PIN, BRG>(leds, NUM_LEDS);
          //FastLED.addLeds<UCS1903, DATA_PIN, BRG>(leds, NUM_LEDS);

    }

    void loop() {

       for (int i = 30; i < NUM_LEDS; i++) {

        leds[i] = CRGB::White;

       }

       FastLED.show();
    }

---

To debug, I tried turning on just the last half. The result was still problematic:
[![WS2811 last half][5]][5]

    for (int i = 30; i < NUM_LEDS; i++) {

        leds[i] = CRGB::White;

    }

---

I then tried setting all LEDs to white at half brightness, and that looks much better, but the LEDs at the outside are still off-color compared the inside:
[![WS2811 white half brightness][6]][6]

---

I've tried setting the whole strip to full blue, and that works fine.

I also have another nearly identical LED strip that instead uses the 1903 chip. The same code (initialized for 1903 instead of WS2811) works just fine on the 1903 strip!

Other things I've ruled out:

 - I'm using a bench power supply capable of 5A, this strip pulls less than 1.5A on full white.
 - I have verified the supply holds at 12V
 - I have not let the LEDs heat up while coiled in the reel. I make sure to unplug them after observing their color.

What could cause this on the WS2811 strip while the 1903 strip works perfectly?

  [1]: https://i.stack.imgur.com/uigus.jpg
  [2]: https://i.stack.imgur.com/uigusm.jpg
  [3]: https://github.com/FastLED/FastLED/wiki/Pixel-reference
  [4]: https://i.stack.imgur.com/NFZPf.jpg
  [5]: https://i.stack.imgur.com/rwkBg.jpg
  [6]: https://i.stack.imgur.com/ZqMwM.jpg

body:
I would suspect that it is a voltage drop in the power rails caused by the current draw. Probably cheap construction with copper tracks that are just too thin and so have too high a resistance.

To combat it you will need to inject power into the strip at various points along it.  Initially to prove the theory you can try connecting the power to both ends of the strip and see if the "dull" spot is half way along the strip.  If it is, then it's certainly a voltage drop.  (incidentally, a voltage drop will cause the blue LEDs to fade out first making it go yellow-red. Then the green ones would probably be next, making it go red).

Then, once proved, you will need to add extra power connections into the strip at the middle of any dim sections and feed the voltage directly in at those points.


body:
Majenko's answer is correct, and you could also verify it with the test performed.

Since it is an issue I encountered myself in the past in a similar case, I want to share some measurements I took on the LED strip I have, in case it can be useful for you or other people.

Premise: the tests were done with a 5m 60 leds/m RGBW strip (SK6812, natural white).

The first test was done to measure the current from each LED. These are the results:

* All LEDs off: 230 mA (0.77 mA/led)
* 10 LEDs to max RED, GREEN or BLUE (one color): 320 mA
* 10 LEDs to max WHITE: 410 mA

This means that each R, G or B led absorbs at max 9 mA, while the W ones have a 18 mA current. Each LED, whether on or off, has a 0.77 mA current flowing through it.

In order to evaluate the voltage drop, I then turned on to full white the first 100 leds, then measured the current, the input voltage and output voltages of the strip. I got a voltage drop from 4.8 V to 4.16 V with a current of 2.11 A (which is almost equal to 230mA + 18mA/led * 100led).

I then modeled the strip as a sequence of ideal current generators joined by resistors:

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

<!-- End schematic -->

Calling R the resistance introduced by the strip, I_Led the current flowing into one LED and N the number of LEDs turned on (and ignoring the effects of the standby current), the voltage drop on the first resistor is dV1 = R*N*I_Led, the one on the second is dV2 = R*(N-1)*I_Led and so on, up to dVN = R*I_Led. The total voltage drop is dV = R*N*(N+1)*I_Led/2.

Using the measured data, we can calculate the resistance between two consecutive LEDs:

R = (2*dV)/(N*(N+1)*I_Led) = (2*0.64V) / (100*101*0.018A) = 7mOhm

NOTE: this is neglecting the effects of the standby current. However in my calculations I was searching for a worst case, and by excluding these effects I was in fact making worst assumptions, so I did not care about them

So, with this resistance I was able to calculate the voltage drop for arbitrary strips and consequently plan where to put the power supply joints. In my case I planned to have at max stubs 1.2m long (80 LEDs), so that the voltage at the end, in the very worst case (all LEDs on in RGBW, at max brightness), I had a voltage drop of slightly more than 1V.

Note that in my setup the voltage drop on the first element (the one with the largest drop) is (80*0.045A*0.007mOhm) = 25mV, with a power dissipation of 90mW.


body:
Those types of strip are simply not sized for full-on on all LEDs. It's expected that if you wanted that, you'd be running a parallel LED strip for lighting that is not addressible and that uses a much higher voltage such as 12 or 24V, where voltage drop is less critical.

Generally addressible LEDs aren't meant to be used in long strips, but are expected to be fit into an array of some kind with numerous short strips, where each can be fed individually.

Running a long stretch isn't a problem, but you will need to feed power at many locations if you want this level of illumination. And you will get murdered on either wire size or voltage drop because voltage drop is so critical when your voltage is only 5 volts.  Crunch the numbers but you can find yourself buying big 1/0 feeder wire in a hurry. I recommend instead carrying power at 24V or mains and converting to 5V in many locations.

I would suggest rethinking the design intent and if illumination is also desired, run a separate strip just for that.  Those are dirt cheap.


body:
The LEDs require 12v but the chips require lower voltage.
The WS chip requires 3.3v to 5v unlike the 6-7v that the IC require, the added resistance along with the fact that the last led has to run  10 metres on a return trip (5m on positive, 5m on negative = 10m total) could mean the drop is to much.

Easier way to find out is to connect in the middle, if it the problem persists (both ends are bad) it's the power supply


body:
As others have answered, it is because of voltage drop.

If you feed positive to the connector at one end, and negative to the other end, all leds will see the same voltage drop, as all leds have 5m connection to the power supply.

If we call the ends L and R with L+ and L- and R+ and R-:

Connect + to L+ and - to R-

If you want to be advanced, get a power supply with separate output and sense connections.

Then connect sense+ to R+ and sense- to L-

This will ensure that the voltage across the LEDs are 12V, by raising the voltage to compensate for the voltage drop.

I started a drawing in CircuitLab, but they want money now?! How rude...


body:
For completeness, I want to include an RGB circuit simulation I made a while ago, along with some data. It's for analog RGB strips, but the concept regarding voltage drop is the same. I've since added a few more LEDs to show the effect of voltage drop across the length, and added the ability to switch the power connection as well.

The simulation shows the current through each 3-LED segment. 12V strips typically have 3 LEDs in series, and repeat that along the strip.

When I created this simulation, I chose exaggerated resistance values, however, this WS2811 strip may be rather close. I haven't modeled it with particular measurements though.

There are switches in simulation circuit that you can click on to switch the connection to 12V and ground at either end of the strip.

[**\[Link to simulation\]**][1]
[![12V LED strip simulation][2]][2]

---

**Results:**

With 12V and ground on the same end:  28.389mA - 27.892mA = **2.123mA difference**

With 12V and ground on both ends:        28.389mA - 27.892mA = **0.497mA difference**

With 12V and ground on opposite ends: 27.310mA - 26.834mA = **0.476mA difference**

**While both power and ground can be connected at both ends of the strip, this simulation actually shows a better balance by simply moving the ground to the opposite end of the strip that receives 12V.**

The only way for each LED segment to be truly balanced would be for each to have it's own connection to power and ground.

[1]: http://www.falstad.com/circuit/circuitjs.html?cct=$+1+0.000005+1.5642631884188172+45+5+43
d+-128+80+-128+112+3+old-default-led
r+-128+176+-128+224+0+220
v+-352+288+-352+240+0+0+40+12+0+0+0.5
w+-352+400+-352+288+0
368+-128+80+-128+32+0+0
368+-128+320+-128+352+0+0
g+-352+400+-352+416+0
r+-128+80+-64+80+0+0.2
r+-128+320+-64+320+0+0.2
r+-64+320+0+320+0+0.2
r+-64+80+0+80+0+0.2
r+-64+176+-64+224+0+220
r+0+320+64+320+0+0.2
r+0+80+64+80+0+0.2
r+0+176+0+224+0+220
r+64+320+128+320+0+0.2
r+64+80+128+80+0+0.2
r+64+176+64+224+0+220
r+128+176+128+224+0+220
w+496+400+-128+400+0
370+-128+224+-128+272+1+0
370+-64+256+-64+320+1+0
w+-128+272+-128+320+0
w+-64+256+-64+224+0
w+128+272+128+320+0
370+128+224+128+272+1+0
w+0+272+0+320+0
370+0+224+0+272+1+0
w+64+256+64+224+0
370+64+256+64+320+1+0
d+-128+112+-128+144+3+old-default-led
d+-128+144+-128+176+3+old-default-led
d+-64+144+-64+176+3+old-default-led
d+-64+112+-64+144+3+old-default-led
d+-64+80+-64+112+3+old-default-led
d+0+144+0+176+3+old-default-led
d+0+112+0+144+3+old-default-led
d+0+80+0+112+3+old-default-led
d+64+144+64+176+3+old-default-led
d+64+112+64+144+3+old-default-led
d+64+80+64+112+3+old-default-led
d+128+144+128+176+3+old-default-led
d+128+112+128+144+3+old-default-led
d+128+80+128+112+3+old-default-led
x+-335+358+-184+361+4+12+Switch\sground\sconnection\s->
370+-352+240+-352+208+1+0
d+448+80+448+112+3+old-default-led
d+448+112+448+144+3+old-default-led
d+448+144+448+176+3+old-default-led
d+384+80+384+112+3+old-default-led
d+384+112+384+144+3+old-default-led
d+384+144+384+176+3+old-default-led
d+320+80+320+112+3+old-default-led
d+320+112+320+144+3+old-default-led
d+320+144+320+176+3+old-default-led
d+256+80+256+112+3+old-default-led
d+256+112+256+144+3+old-default-led
d+256+144+256+176+3+old-default-led
d+192+144+192+176+3+old-default-led
d+192+112+192+144+3+old-default-led
370+384+256+384+320+1+0
w+384+256+384+224+0
370+320+224+320+272+1+0
w+320+272+320+320+0
370+448+224+448+272+1+0
w+448+272+448+320+0
w+256+256+256+224+0
w+192+272+192+320+0
370+256+256+256+320+1+0
370+192+224+192+272+1+0
r+448+176+448+224+0+220
r+384+176+384+224+0+220
r+384+80+448+80+0+0.2
r+384+320+448+320+0+0.2
r+320+176+320+224+0+220
r+320+80+384+80+0+0.2
r+320+320+384+320+0+0.2
r+256+176+256+224+0+220
r+256+80+320+80+0+0.2
r+256+320+320+320+0+0.2
r+192+320+256+320+0+0.2
r+192+80+256+80+0+0.2
368+448+80+448+32+0+0
r+192+176+192+224+0+220
d+192+80+192+112+3+old-default-led
r+128+320+192+320+0+0.2
r+128+80+192+80+0+0.2
w+496+320+448+320+0
w+-352+208+-352+80+0
x+61+11+168+14+4+16+RGB\sLED\sStrip
x+481+425+495+428+4+8+Bort
w+496+80+448+80+0
368+-64+80+-64+32+0+0
368+0+80+0+32+0+0
368+64+80+64+32+0+0
368+192+80+192+32+0+0
368+128+80+128+32+0+0
368+256+80+256+32+0+0
368+320+80+320+32+0+0
w+496+-16+-160+-16+0
368+384+80+384+32+0+0
w+496+80+496+-16+0
s+-208+80+-160+80+0+0+false
s+-208+32+-160+32+0+1+false
s+-176+400+-128+400+0+0+false
x+-366+58+-219+61+4+12+Switch\spower\sconnection\s->
w+-128+80+-160+80+0
w+-208+80+-208+32+0
w+-160+32+-160+-16+0
s+-176+320+-128+320+0+1+false
w+-176+400+-224+400+0
w+-176+400+-176+320+0
w+496+400+496+320+0
368+64+320+64+368+0+0
368+128+320+128+352+0+0
368+0+320+0+352+0+0
368+-64+320+-64+368+0+0
368+256+320+256+352+0+0
368+192+320+192+368+0+0
368+384+320+384+352+0+0
368+320+320+320+368+0+0
368+448+320+448+368+0+0
w+-352+400+-224+400+0
w+-352+80+-208+80+0
x+-326+268+-284+271+4+12+12V\sDC

[2]: https://i.stack.imgur.com/ePafx.png


message:
Creating an array, assigning a value to each indices, and assessing the array

I am trying to create an unassigned array of size 512 and then assigning a reading to each indices. I want to get the start time before and after the loop and only run it once. Then I want to know how to retrieve the readings and serialprint the values after the loop. So far this is what I have but I don't think it is running as I want it to. I was able to get the start time but I'm not sure if it is running afterwards. Any help is greatly appreciated. Thanks!

```
void setup() {
int Vs[512] = {};
int analogPin = A0; // turn pin A0 on
pinMode(9, INPUT);
Serial.begin(9600); // setup serial
analogWrite(9, pow(2, 7)); //LED power 0
int time = micros();
Serial.println(time);
}

void loop() {
int i;
for (int i = 0; i <= 511; i++); { //loop setup for 512
int c = analogRead(A0) * (5.000/1024.000);
int Vs[i] = {c};
Serial.println(Vs[i]);
}
int stoptime = micros();
Serial.println(stoptime);
}

void stop() {
while(1);
}
```

body:
There are multiple issues with your program. The most obvious is that,
if you define a variable multiple times, you end up with mutliple
_different_ variables that share the same name. For example:

```c++
void setup() {
    int Vs[512] = {};  // this Vs is local to setup()
}

void loop() {
    int i;  // this i is local to loop()
    for (int i = 0;  // this other i is visible within the for loop only
            i <= 511;
            i++)
        ;  // this is the body of the for loop
    {
        ...
        int Vs[i] = {c};  // this Vs is local to loop()
    }
}
```

Another issue I pointed out in the snippet above is that a semicolon by
itself is an empty (i.e. do-nothing) statement. Thus you `for` loop is
empty.

There is no point in defining a constant such as `analogPin = A0` if you
don't use it.

The value returned by `micros()` is not an `int`, it's an
`unsigned log`.

If you store a voltage in volts in an `int`, you get a very poor
resolution of one volt. You could store in a `float`, but that would
fill up the memory of your Arduino. I would rather store the raw
readings, and convert to volts only for printing.

`Serial.println()` takes time, and you are doing this during the timed
part of your code, which is probably unintended.

Here is a version of your program that may better reflect your
intentions. It takes 512 analog readings, stores them in an array, then
prints them and reports the time taken to do the readings. Then it waits
for one second and repeats the whole thing again.

```c++
const uint8_t analogPin = A0;
const int readings_count = 512;
int Vs[readings_count];

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

void loop() {
    // Take a run of analog readings.
    unsigned long start_time = micros();
    for (int i = 0; i < readings_count; i++) {
        Vs[i] = analogRead(analogPin);
    }
    unsigned long stop_time = micros();

    // Print the readings.
    Serial.println("Voltage readings:");
    for (int i = 0; i < readings_count; i++) {
        Serial.println(5.0/1024 * Vs[i]);
    }
    Serial.print("Data recorded in ");
    Serial.print(stop_time - start_time);
    Serial.println(" µs");
    Serial.println();

    // Wait before the next run.
    delay(1000);
}
```

If you really want to run only one iteration of the process, then you
can just replace `delay(1000);` by `exit(0);`. Alternatively, move the
body of `loop()` to the end of `setup()`, and keep an empty `loop()`.


message:
External vs internal pullup

There are two ways of pulling the pins in Arduino – using internal and external resistor. I wonder when I should use external resistor instead of INPUT_PULLUP.

body:
You can use either the internal or external resistor in normal application.

Each method has each own advantages:

**Internal resistor**

 - Pros: flexible to change by changing the code
 - Pros: Reduce PCB size
 - Pros: Reduce cost (very small)
 - Cons: It may make MCU hot

**External resistor**

 - Pros: Reduce heat for MCU
 - Cons: Not easy to replace when it is built-in PCB
 - Cons: Increase PCB size

Besides, Pull-up and pull-down resistors are not only used for INPUT port but also for OUTPUT port. In the case of OUTPUT port. The external resistor has another advantage:  flexibility in connecting devices with different I/O voltages. For example, in I2C hardware [see I2C at the Hardware Level][1].

NOTE: As far as I know, at the writing time, Arduino library does NOT support INPUT_PULLDOWN

  [1]: https://learn.sparkfun.com/tutorials/i2c/all#i2c-at-the-hardware-level


body:
The "Arduino Language" (i.e. the `pinMode()` function) only knows INPUT_PULLUP.

So you need external resistors for PULLDOWN resistors.

OUTPUT signals are not floating, so the term PULLUP/PULLDOWN resistor does not really apply there.

Besides, the value of an internal pullup resistor is not adjustable. If that value (20 .. 50k) is not appropriate (I²C needs something less than 10k) an external resistor is required.


body:
"Cons: It may make MCU hot"
It will not. P=V^2/R, so 5*5/20,000 = 1.25mW, that will not make the processor hot. Even turning all 80 in a Mega2560, and pulling them all low, will only dissipate 0.1W.

"NOTE: As far as I know, at the writing time, Arduino library does NOT support INPUT_PULLDOWN"
That is because Atmega328P, '1284, '2560, etc. family of devices do not have internal pulldown resistors. Only pullup. See Section 14 of their datasheets, "I/O Ports".

This pullup is generally insufficient for I2C pullup, the rising edge created by the 20K to 50K internal pullup is very slow. External 4.7K down to around 2.2K (depends on how many I2C devices are connected) are needed. And the I2C bus spec says they should be at the end of the bus, not the origin of bus (which is generally the processor).

If you have a long wire coming from a button or switch, that is generally a good time to use an external pullup to ensure good switching levels between high and low.


message:
Sending more than BUFFER_LENGTH(32) bytes in slave answer I2C

I need to send 259 bytes as answer to I2C master read request. AFAIK there is a buffer limit of 32 bytes in Wire.h <s>and in HW (Arduino Nano)</s>. Is there a way sending 259 byte answer, or I have to choose another HW?

The code is:

    void serveInitCommunication() {
      Serial.println("serveInitCommunication()");
      static unsigned int counter = 0;
      auto answer = findInitAnswer(counter);

      uint8_t buffer[260]; //maximum size from dataLengths[] in comm_init_data.h
      memcpy_P(buffer, answer.dataPtrProgmem, answer.dataSize);

      Serial.print(" dataSize:");
      Serial.print(answer.dataSize);
      Serial.print(" data:");
      Serial.println(int(buffer[answer.dataSize - 1]));

      auto bytesToWrite = answer.dataSize;
      uint16_t bytesWritten{0};

      while (bytesToWrite > BUFFER_LENGTH) {
        Serial.println("Write part");
        Wire.write(buffer + bytesWritten, BUFFER_LENGTH);
        bytesToWrite -= BUFFER_LENGTH;
        bytesWritten += BUFFER_LENGTH;
      }
      Serial.print("Bytes written:");
      Serial.print(bytesWritten);
      Serial.print(" Bytes yet to write:");
      Serial.println(bytesToWrite);
      Wire.write(buffer + bytesWritten, bytesToWrite);

      counter++;
    }

And called is it:

    void requestHandler() {
      char buff[100];
      sprintf(buff, "requestHandler addr:0x%x counter:%d", readAddress, msgReadCounter);
      Serial.println(buff);

      if (readAddress == INIT_MSG_ADDRESS) {
        serveInitCommunication();
      }
    }

I've tried moving the `serveInitCommunication()` into `void loop()` and setting a just a flag in `requestHandler()` but without success. Sending up to 32 bytes works fine. Tnx

update: `uint8_t twi_transmit(const uint8_t*, uint8_t);` so twi library self limit data to 255 bytes

update2: there is a hacker way doing it, by replacing the twi.c twi_txBuffer and twi_txBufferLength with buffer from the sketch

body:
The limitation is purely in software. The I2C hardware has a limit of one byte at a time, and the software creates a 32 byte buffer and feeds each byte from that in turn.

While it would be perfectly possible to increase that buffer size, you may find you have other problems when you get above 255 bytes, since lots of parameters and internal variables for the library are limited to 8 bit values.

It would also be considered very "hacky" since you can't easily upgrade the Wire library in future.

A better strategy would be to split your data into chunks and make multiple requests, each one saying "Give me chunk number ..." and then recombine them upon reception.


message:
MCP4725 I2C address

I want to use four of MCP4725 DAC module at the same time but it only has two I2C addresses which can be set via jumpers:

[![][1]][1]

In page 10 of the [datasheet][2] it says:

> Device Address Selection pin. This pin can be tied to VSS or VDD, or
> can be actively driven by the digital logic levels. The logic state of
> this pin determines what the A0 bit of the I2C address bits should be.

Is there anyway to set more than two addresses for this module? or any hack via hardware/software...

  [1]: https://i.stack.imgur.com/8uTx9.png
  [2]: https://www.sparkfun.com/datasheets/BreakoutBoards/MCP4725.pdf

body:
There is a trick to this, and it involves considering one device "active" and all others "inactive".

You only ever work with one address, and that is the address of the "active" unit. All other units are on the secondary "inactive" address which you ignore.

The address pin of each unit is then connected to an IO pin, and can be considered a "chip select" pin.

The sequence, then, is:

* Set unit one's A0 low and all other units HIGH.
* Communicate on Address 0
* Set unit two's A0 LOW and all other units HIGH.
* Communicate on Address 0
* Etc for each unit

Since you never communicate on Address 1 the rest of the "inactive" units ignore all the communication.


message:
Ramping up and down arduino motor due to ultrasonic sensor input

Im working on an arduino robot that needs to follower a leader robot infront of it. The leader robot can accelerate, decelerate , and stop and my robot needs to be able to follow the leader without crashing into it.

I have my two sensors working however Im having a harder time integrating the motors to ramp up or down. Currently only one wheel turns on at a time for the right and left commands.
How can I appropriatly ramp up or down the wheel speed.

```
int SpRMotor = 5;  //speed Right Motor
int MotorA1 = 7; //Right Motor = +
int MotorA2 = 6; //Right Motor = -
int MotorB1 = 8; //Left Motor = -
int MotorB2 = 9; //Left Motor = +
int SpLMotor = 10;  //speed Left Motor

int TriggerPIN1 = 3;//right
int EchoPIN1 = 2;
int TriggerPIN2 = 12;//left
int EchoPIN2 = 11;

void setup(){
  pinMode(TriggerPIN1,OUTPUT);
  pinMode(EchoPIN1,INPUT);
  pinMode(TriggerPIN2,OUTPUT);
  pinMode(EchoPIN2,INPUT);

  pinMode(MotorB1, OUTPUT);
  pinMode(MotorB2, OUTPUT);
  pinMode(MotorA1, OUTPUT);
  pinMode(MotorA2, OUTPUT);
  pinMode(SpLMotor, OUTPUT);
  pinMode(SpRMotor, OUTPUT);

  analogWrite(SpRMotor, 170);
  analogWrite(SpLMotor, 170);
  Serial.begin(9600);
  }
void loop(){

  int limit;
  int sampledata1, sampledata2;
  sampledata1 = distance(TriggerPIN1, EchoPIN1);
  Serial.print("distance1: ");
  Serial.print(sampledata1);
  delay(100);
  sampledata2 = distance(TriggerPIN2, EchoPIN2);
  Serial.print(" distance2: ");
  Serial.println(sampledata2);
  delay(100);
  limit = 10;
  if((15> sampledata1 >= limit)&&(15> sampledata2 >= limit))
  {
    Serial.print("True");
    forward();
    delay(100);
  }
     if (sampledata2  >= 15 )
    {turnRight();}
  if (sampledata1  >= 15 )
    {turnLeft();}
  if ((limit > sampledata1)&&(limit> sampledata2 ))
  {
    Stop();
  }

}

void forward(){
digitalWrite(MotorA1, LOW);
digitalWrite(MotorA2, HIGH);
digitalWrite(MotorB1, HIGH);
digitalWrite(MotorB2, LOW);
}

void turnRight(){
digitalWrite(MotorA1, LOW);
digitalWrite(MotorA2, LOW);
digitalWrite(MotorB1, HIGH);
digitalWrite(MotorB2, LOW);
}

void turnLeft(){
digitalWrite(MotorA1, LOW);
digitalWrite(MotorA2, HIGH);
digitalWrite(MotorB1, LOW);
digitalWrite(MotorB2, LOW);
}

void Stop(){
digitalWrite(MotorA1, LOW);
digitalWrite(MotorA2, LOW);
digitalWrite(MotorB1, LOW);
digitalWrite(MotorB2, LOW);
}
int distance(int trig, int echo)
{ digitalWrite(trig,LOW);
  delayMicroseconds(2);
  digitalWrite(trig,HIGH);
  delayMicroseconds(10);
  digitalWrite(trig,LOW);
  long timedelay = pulseIn(echo,HIGH);
  int distance = 0.0343 * (timedelay/2);

  return distance;
}
```

body:
The speed seams to be defined by a an analog write to `SpRMotor` and `SpLMotor`. You did that once (with value 170)  in the setup. If you use variables for that (e.g. `speedValueL` and `speedValueR`) you can change their values as you need it and write it to the PWM channels on each forward, backward, left or right statement.

A short example:

    int SpRMotor = 5;  //speed Right Motor
    int MotorA1 = 7; //Right Motor = +
    int MotorA2 = 6; //Right Motor = -
    int MotorB1 = 8; //Left Motor = -
    int MotorB2 = 9; //Left Motor = +
    int SpLMotor = 10;  //speed Left Motor

    int TriggerPIN1 = 3;//right
    int EchoPIN1 = 2;
    int TriggerPIN2 = 12;//left
    int EchoPIN2 = 11;

    int speedValueL = 0;
    int speedValueR = 0;

    void setup()
    {
      pinMode(TriggerPIN1,OUTPUT);
      pinMode(EchoPIN1,INPUT);
      pinMode(TriggerPIN2,OUTPUT);
      pinMode(EchoPIN2,INPUT);

      pinMode(MotorB1, OUTPUT);
      pinMode(MotorB2, OUTPUT);
      pinMode(MotorA1, OUTPUT);
      pinMode(MotorA2, OUTPUT);
      pinMode(SpLMotor, OUTPUT);
      pinMode(SpRMotor, OUTPUT);

      analogWrite(SpRMotor, speedValueR);
      analogWrite(SpLMotor, speedValueL);

      Serial.begin(9600);
    }

    void loop()
    {
      int limit;
      int sampledata1, sampledata2;
      sampledata1 = distance(TriggerPIN1, EchoPIN1);
      Serial.print("distance1: ");
      Serial.print(sampledata1);
      delay(100);
      sampledata2 = distance(TriggerPIN2, EchoPIN2);
      Serial.print(" distance2: ");
      Serial.println(sampledata2);
      delay(100);
      limit = 10;
      if( (15> sampledata1 >= limit) && (15> sampledata2 >= limit) )
      {
        Serial.print("True");
        // Just my guess - do what fits for you
        speedValueL = 170;
        speedValueR = 170;

        forward();
        delay(100);
      }

      if (sampledata2  >= 15 )
      {
        // Just my guess - do what fits for you
        speedValueL = 200;
        speedValueR = 0;

        turnRight();
      }

      if (sampledata1  >= 15 )
      {
        // Just my guess - do what fits for you
        speedValueL = 0;
        speedValueR = 200;

        turnLeft();
      }

      if ( ( limit > sampledata1 ) && ( limit> sampledata2 ) )
      {
        // Just my guess - do what fits for you
        speedValueL = 0;
        speedValueR = 0;

        Stop();
      }
    }

    void forward()
    {
      analogWrite(SpRMotor, speedValueR);
      analogWrite(SpLMotor, speedValueL);

      digitalWrite(MotorA1, LOW);
      digitalWrite(MotorA2, HIGH);
      digitalWrite(MotorB1, HIGH);
      digitalWrite(MotorB2, LOW);
    }

    void turnRight()
    {
      analogWrite(SpRMotor, speedValueR);
      analogWrite(SpLMotor, speedValueL);

      digitalWrite(MotorA1, LOW);
      digitalWrite(MotorA2, LOW);
      digitalWrite(MotorB1, HIGH);
      digitalWrite(MotorB2, LOW);
    }

    void turnLeft()
    {
      analogWrite(SpRMotor, speedValueR);
      analogWrite(SpLMotor, speedValueL);

      digitalWrite(MotorA1, LOW);
      digitalWrite(MotorA2, HIGH);
      digitalWrite(MotorB1, LOW);
      digitalWrite(MotorB2, LOW);
    }

    void Stop()
    {
      analogWrite(SpRMotor, speedValueR);
      analogWrite(SpLMotor, speedValueL);

      digitalWrite(MotorA1, LOW);
      digitalWrite(MotorA2, LOW);
      digitalWrite(MotorB1, LOW);
      digitalWrite(MotorB2, LOW);
    }

    int distance( int trig, int echo )
    {
      digitalWrite( trig, LOW );
      delayMicroseconds( 2 );
      digitalWrite( trig, HIGH );
      delayMicroseconds( 10 );
      digitalWrite( trig, LOW );
      long timedelay = pulseIn( echo, HIGH );
      int distance = 0.0343 * ( timedelay / 2);

      return distance;
    }


message:
What are the sizes of each primitive datatype on a Metro M4 Express SAMD51?

What are the data sizes of all the primitive datatypes on a Metro M4 Express SAMD51 C++ implementation? In some C++ implementations, `int` has 16 bits and in other implementations it has 32 bits. Is

body:
And that is the only difference in fundamental type sizes. On 8-bit Arduinos `int` is 16 bit and on 32-bit `int` is 32 bit.

 - `short` is 16 bit
 - `long` is 32 bit
 - `long long` is 64 bit

[https://en.cppreference.com/w/cpp/language/types][1]

  [1]: https://en.cppreference.com/w/cpp/language/types


body:
Here is a sketch to quickly find out **unsigned** maximum values on any architecture and deduce the bit width from them (I had to use sprintf, because Serial.println(unsigned long long) did not work on my Due):

    #include <limits.h>

    #define sprintfln(args...) { char _qsx6_[200]; snprintf(_qsx6_, 200, args); Serial.println(_qsx6_); } // _qsx6_ may collide with local var

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

        unsigned char  uc = 0; uc=~uc; Serial.println(uc);
        unsigned short us = 0; us=~us; Serial.println(us);
        unsigned int   ui = 0; ui=~ui; Serial.println(ui);
        unsigned long  ul = 0UL; ul=~ul; Serial.println(ul);
        unsigned long long ull = 0ULL; ull=~ull; // doesn't work: Serial.println(~ull);

        sprintfln("char:%u short:%u int:%u long:%lu long long:%llu", uc, us, ui, ul, ull);
        sprintfln("char:%u short:%u int:%u long:%lu long long:%llu", UCHAR_MAX, USHRT_MAX, UINT_MAX, ULONG_MAX, ULLONG_MAX);
        sprintfln("char:%u short:%u int:%u long:%u long long:%u", sizeof(uc), sizeof(us), sizeof(ui), sizeof(ul), sizeof(ull));
        sprintfln("pointer:%u", sizeof(&uc));
    }

On Arduino Due this gives (I expect it to be the same on SAMD51):

    char:255
    short:65535
    int:4294967295
    long:4294967295
    long long:18446744073709551615
    char:1 short:2 int:4 long:4 long long:8
    pointer:4

Usually you could include "limits.h", but it seems that unsigned long long is missing (at least on Due). Hmmm, I didn't expect int and long to be the same, good to know.


message:
Why is this code not working?

So I am trying to use Port Manipulation to turn on LEDS but I need to use PORT Manipulations for specific reasons.

```
//22-29PORTA (0x01-0x80)
//30-37PORTC (0x80-0x01)
//38-45PORTD (0x80-0x01)

void setup(){
PORTA =  B0000000; //29--->22
PORTC =  B0000000; //37--->30
PORTD =  B0000000; //45--->38
}

void loop(){
 PORTA =  B1000100;
 PORTC =  B0101000;
 PORTD =  B0000010;
 delay(1000);

 PORTA =  B1010000;
 PORTC =  B0001010;
 PORTD =  B0100000;
 delay(1000);

 PORTA =  B0010100;
 PORTC =  B0100010;
 PORTD =  B0001000;
 delay(1000);

}```
Heres the code for Arduino Mega 2560

body:
You need to set the ports to output first, before you can use them.

To do that you use the DDRx (Data Direction) registers.  Your code should look like:

    //22-29PORTA (0x01-0x80)
    //30-37PORTC (0x80-0x01)
    //38-45PORTD (0x80-0x01)

    void setup(){
        // Set the pins all to output
        DDRA = 0xFF;
        DDRC = 0xFF;
        DDRD = 0xFF;

        PORTA =  B0000000; //29--->22
        PORTC =  B0000000; //37--->30
        PORTD =  B0000000; //45--->38
    }

    void loop(){
        PORTA =  B1000100;
        PORTC =  B0101000;
        PORTD =  B0000010;
        delay(1000);

        PORTA =  B1010000;
        PORTC =  B0001010;
        PORTD =  B0100000;
        delay(1000);

        PORTA =  B0010100;
        PORTC =  B0100010;
        PORTD =  B0001000;
        delay(1000);
    }

You can read more about direct port manipulation [here](https://www.arduino.cc/en/Reference/PortManipulation).


message:
Does AWG size affect signal from sensors?

Would using a thicker cable like 16 AWG affect the signal being received from an RFID or Ultrasonic sensor?

I understand AWG can make a significant impact on voltage when a thick cable is used over a long distance. In my head signal data is delicate so a nice thin wire will ensure little disturbance....

Looked around and couldn't find a clear answer so hopefully someone can help!

body:
A signal is just a varying voltage.  A wire is just a (very long) small resistor.  The device reading the signal is just a current sink.

That's three terms there: voltage, resistance, and current. Three terms you should know are related by Ohm's Law.

Also, some simple rules:

* The thinner the wire the bigger the resistance
* The longer the wire the bigger the resistance
* The more load on the wire the greater the current

And of course, that all means:

* The greater the resistance or the greater the current, the greater the voltage drop across the wire.

If the voltage drop gets too great then the device receiving the signal won't be able to work out what it is.

But then of course a wire is also an antenna picking up all sorts of noise. The longer the wire the more noise it will pick up. And the thinner the wire the greater the resistance and the greater the resultant voltage drop, meaning the lower the noise margin and immunity.

**So no, a thinner wire isn't better than a thicker wire. The exact opposite is true.**


message:
Powering Peltier using solar panels

I am a beginner to electronics and trying to make a portable air conditioner using a Peltier cooling pad (12V). I am planning on using a solar panel to power the Peltier and looking forward to your expert opinion  for below;
- Is this possible?
-What the specifications I have to consider prior to purchasing the solar panel?
- What is the weight of the solar panel?
- Can I operate the Peltier through an Arduino using Solar panel as the power source( without using batteries to power Arduino and Peltier). My idea is to control the Peltier cooler via Arduino using a phone App.
Really sorry if these questions are basic, yet your guidance will be very much helpful for me as well as for the other beginners like me.

body:
A microcontroller like an Arduino needs a constant source of regulated 5V (or 3.3V for some models.) The voltage of a solar panel varies depending on the amount of light, and in low light conditions there won't be enough power to run the Arduino.

So the short answer is no, you won't be able to run the Arduino reliably from a solar panel without a battery. You probably want a battery and a buck/boost voltage regulator that can convert a wide range of voltages to the 5V the Arduino needs.

What do you want the Arduino for? Temperature regulation? You'd probably be better off using a bimetallic thermostat that would turn the power to the Peltier pad on and off without needing electronics.

As for running a Peltier junction cooling pad from a solar panel, that should work. It would depend on the specs of the Peltier unit and of the panel. Again, you'll probably get the maximum cooling if you use a buck/boost voltage regulator to convert the variable output of your solar panel to a steady 12V. You'll need a big enough solar panel to provide the current that your Peltier pad needs.

All the talk about Peltier pads and solar panels is not Arduino-specific, however.

## Edit:

Research solar chargers for 12V batteries. Buy a solar panel made to charge a 12V battery. Make sure you select a solar panel that puts out enough current to run the Peltier panel at full power when it is in the sun. Ideally, select a solar panel that provides several times more current than needed to run the Peltier pad. That way the solar panel will charge the battery AND run the Peltier pad while the sun is shining, and when the sun is behind the clouds or at night, the Peltier pad will continue to run from the battery.

Start from that. Buy a buck/boost power supply that can convert a wide range of voltages to 5V. Use that to power the Arduino.

Buy a digital thermometer (like a DHT11 for example). Follow the instructions to wire it into your Arduino, and write a sketch that measures the temp in the thing you are trying to cool.

Buy a power MOSFET transistor that is made to work from a 5V logic signal. This one, for example: https://www.sparkfun.com/products/10213

Wire the MOSFET so a logic signal from one of the digital pins on the Arduino is connected to the gate of the MOSFET and it switches the power to the Peltier pad on and off. (You should be able to find a wiring diagram online.)

Write a sketch that measures the temp from the digital thermometer every few seconds, and turns on the power to the MOSFET if the temp rises above a threshold temp, and turns it off if it drops below a colder temp. (Say it turns on the MOSFET when the temp rises above 24°C, and turns the MOSFET off when the temp drops to 20°C. (This is really simple code to write.)

Note that if the battery gets too low, it won't provide enough power to the voltage regulator which supplies the Arduino and it will shut down. That will cause the Peltier pad to turn off. Once the solar panel charges the battery up enough, the voltage regulator will start providing 5V to the Arduino again, it will restart, your sketch will start running, and the cycle will continue. When the battery barely has enough power to drive the Arduino, it may restart the Arduino, try to turn on the Peltier pad, and immediately die again, every few seconds. That would be bad, and would put a lot of stress on all the electronics.

You might want to add a voltage sensor¹  to the battery and have the Arduino measure the battery voltage, and not try to power the Peltier pad unless and until the battery has a reasonable charge. Instead it would monitor the battery charge level and wait until there was enough power stored in the battery to run the Peltier pad. You could also have the Arduino detect that the battery charge level was getting low, and shut off the Peltier pad before it got too low.

A lead/acid battery would be a good choice since it's cheap, holds a lot of power, and it's easy to estimate the remaining power in a healthy lead/acid cell from its output voltage.

If you **do** use a lead-acid battery, it's important to add a battery charge level sensor and make your sketch avoid draining the battery too low. Lead-acid batteries are damaged when you discharge them too much.

## Edit #2:

You said in a comment to another answer that you're looking to provide small-scale cooling while traveling in a hot climate: The fact that you're trying to handle travel poses some interesting challenges, and perhaps some opportunities. If you're traveling in a car or truck you could tap the 12V power that is almost always available in a motor vehicle. If you don't have an external source of power then the shifting and turning you will likely experience while traveling will greatly reduce the efficiency of your solar panel. They only give maximum power when the panel is directly perpendicular to (or "normal to") the sun. As the angle of the panel to the sun shifts from the ideal angle the power output of your panel will drop significantly.

---
¹ A voltage sensor could be as simple as a voltage divider that reduces the input voltage from a max of a little under 14V down to 5 V, fed into an analog input on the Arudino. You might need to disconnect the solar panel input before measuring the battery charge level however, since input from the solar panel will make the battery voltage seem higher than it actually is. Also note that your battery charge level estimates are going to be crude, since you should really let a lead-acid battery rest with no input and no output for several minutes before taking a measurements in order to get an accurate reading.


body: Your first decision is to figure out the heat load on the space. How many BTU/hr you need to remove to keep the temperature you want. Then figure out how large / how many Peltier you need to remove that much heat. Do you need some reserve capacity for unusual circumstances or is a higher inside temperature Ok sometimes? Then you need a power budget - how much power will it take to remove that much heat with Peltier panels. How much PV area will you need to provide that power? If you need cooling when the sun isn't out, your power budget has to include the 24-hour demand, and the intermittent supply, perhaps again with some headroom. Power storage - batteries or the power grid - will be a requirement to match the two. The same storage can power your Arduino. The Arduino's power budget will be minuscule compared to the rest of the installation and you can totally ignore it. Do you have to power your internal network that connects the Arduino to the Internet, too? Figure that in. By this point, you'll have the answers to most of your questions. Just a heads-up: A Peltier beer-cooler is quite doable. A whole house A/C *might* be doable but no practical - you probably won't like the numbers! I'm guessing your project lies somewhere between the two.


message:
Sending the data for temperature and soil using esp8266-01 through software serial

The code I used was from online and I tried using it to send data to firebase through web server. But the ouput I get from serial monitor was just "ATE0" which means there's something wrong. Hence, I can't proceed in solving this issue.

I tried several resources online to match my current problem.

I hope someone can help me

Thank you :)

    #include <SoftwareSerial.h>;
    SoftwareSerial Serial1(10, 11);
    #include "DHT.h"
    #define Terra "terra1"
    #define DHTPIN 2

    #define DHTTYPE DHT22

    DHT dht(DHTPIN, DHTTYPE);

    //const int rs = 7, en = 6, d4 = 5, d5 = 4, d6 = 3, d7 = 2; eyagagana soy

    int j=0;
    int prev=0;
    int pres=0;
    String status="";
    String buff(64);
    String getStr(128);

    void setup() {

      Serial.begin(9600);
      Serial1.begin(9600);
    //  Serial.println(F("Humiture and Soil Moisture Sensors"));
      delay(2000);
      Serial1.setTimeout(5000);
      dht.begin();

       if (!connectWiFi()) {
        Serial.println("Can not connect to the WiFi.");
        while (true)
          ; // do nothing
      }
      Serial.println("OK, Connected to WiFi.");
      sendCommand("AT+CIPSTA?");
      sendCommand("AT+CIPDNS_CUR?");
      sendCommand("AT+CIPSTAMAC?");

    }

    void loop() {
     j=analogRead(A0);
      j=map(j,0,982,148,0);
      pres=j;
      if(j>100)
      j=100;
      else if(j<0)
      j=0;

      prev=j;
      delay(1000);

      float h = dht.readHumidity();
      // Read temperature as Celsius (the default)
      float t = dht.readTemperature();
      // Read temperature as Fahrenheit (isFahrenheit = true)
      float f = dht.readTemperature(true);

      // Check if any reads failed and exit early (to try again).
    //  if (isnan(h) || isnan(t) || isnan(f)) {
    //    Serial.println(F("Failed to read from DHT sensor!"));
    //    return;
    //  }

      // Compute heat index in Fahrenheit (the default)
      float hif = dht.computeHeatIndex(f, h);
      // Compute heat index in Celsius (isFahreheit = false)
      float hic = dht.computeHeatIndex(t, h, false);

    //  Serial.print(F("Humidity: "));
    //  Serial.print(h);
    //  Serial.print(F("%  Temperature: "));
    //  Serial.print(t);
    //  Serial.print(F("°C "));
    //  Serial.print(("Soil Moisture: "));
    //  Serial.print(j);
    // Serial.println("%");

    // connect to server
      if (sendCommand("AT+CIPSTART=\"TCP\",\"https://terraduino.000webhostapp.com\",80")) {
        Serial.println("connected to Cloud");
        // build HTTP request
        getStr = "GET /upload.php?terra=";
        getStr += Terra;
        getStr += "&j=";
        getStr += j;
        getStr += "&t=";
        getStr += t;
        getStr += "&h=";
        getStr += h;
        getStr += " HTTP/1.1\r\n";
        //WEBSERVER
        getStr += "Host: https://terraduino.000webhostapp.com\r\n\r\n";
        // open send buffer
        buff = "AT+CIPSEND=";
        buff += getStr.length();
        if (sendCommand(buff.c_str()) && Serial1.find(">")) { // AT firmware is ready to accept data
          // send HTTP request
          Serial.println(getStr);
          Serial1.print(getStr);
          // print HTTP response
          if (Serial1.find("+IPD,")) { // response received
            int l = Serial1.parseInt();
            while (l > 0) {
              if (Serial1.available()) {
                Serial.write(Serial1.read());
              }
            }
            Serial.println("--------------");
          } else {
            Serial.println("no response");
          }
        } else {
          Serial.println("send error");
        }
        sendCommand("AT+CIPCLOSE");
      } else {
        Serial.println("Error connecting");
      }
    }
    bool connectWiFi() {
      if (!sendCommand("ATE0")) // echo off
        return false;
      if (!sendCommand("AT+CIPMUX=0")) // set single connection mode
        return false;
      if (!sendCommand("AT+CWMODE=1")) // set STA mode
        return false;

      return sendCommand("AT+CWJAP=\"I Pronounce you Man and Wifi\",\"-PX?*z3A_1x@.exe\"");
    }
    bool sendCommand(const char* cmd) {
      Serial.println(cmd);
      Serial1.println(cmd);
      while (true) {
        buff = Serial1.readStringUntil('\n');
        buff.trim();
        if (buff.length() > 0) {
          Serial.println(buff);
          if (buff == "OK" || buff == "SEND OK" || buff == "ALREADY CONNECTED")
            return true;
          if (buff == "ERROR" || buff == "FAIL" || buff == "SEND FAIL")
            return false;
        }
      }
    }

body:
I would say you are trapped in the `sendCommand` function. You print the `cmd` (cmd="ATE0") variable to the terminal and then send the command to the ESP over Serial1 = software serial. Serial1 is configured with a baud rate of 9600 (`Serial1.begin(9600)`)  it depends on your ESP but that might be wrong. A common value is 115200 (`Serial1.begin(115200)`). But because that can vary from board to board, it could also be wrong.

If I'm right and you configured a wrong baud rate, the command can not be understood by the ESP and even the newline after the command might be missing for it.

So the ESP send nothing back and the 'buff.length()' equals to 0. Then the `while(true)` runs and runs and runs ... .


message:
Using the MIDI library in my own library

------------
Error message :

    "error: invalid declarator before 'MIDI'
             MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI);
                                                           ^
    Plusieurs bibliothèque trouvées pour "libMidi.h"
    /home/due32/Arduino/libraries/MIDI/midi_Defs.h:170:31: note: in definition of macro 'MIDI_CREATE_INSTANCE'
         midi::MidiInterface<Type> Name((Type&)SerialPort);"

--------
libMidi.h

    #ifndef libMidi_h
    #define libMidi_h

    #include <Arduino.h>
    #include <MIDI.h>

     void midiSetup();
     void pmbMIDI();

    // void MIDI_CREATE_DEFAULT_INSTANCE(); //doesn't work

    #endif

---------
libMidi.cpp

    #include "libMidi.h"
    #include <MIDI.h>

    void midiSetup(){

    //midi::MidiInterface<Type> Name((Type&)SerialPort);

      void MIDI_CREATE_DEFAULT_INSTANCE();
      void MIDI.begin(MIDI_CHANNEL_OMNI);
    }

    void pmbMIDI(){
     if (MIDI.getType() == 144){
      digitalWrite(13, 1);}

     if (MIDI.getType() == 128){
      digitalWrite(13, 0);}
    }

---
Thank you by advance

body:
    void MIDI_CREATE_DEFAULT_INSTANCE();

This line should not be placed inside a function, because it is a forward function declaration.

However, I think there are more problems in your code.

My wild guess is to improve the following lines:

- Uncomment line that doesn't work

Change

    MIDI_CREATE_DEFAULT_INSTANCE();

to

    MIDI_CREATE_DEFAULT_INSTANCE();

and place it outside a function.

Remove the word `void`  in the following lines

    void midiSetup();
    void pmbMIDI();

And also align the { and }

    void MIDI.begin(MIDI_CHANNEL_OMNI);

So it's a function call.

Other improvements is to remove spaces or tabs  in

        void midiSetup();
        void pmbMIDI();

Also align { and } in

    if (MIDI.getType() == 144){
        digitalWrite(13, 1);}

    if (MIDI.getType() == 128){
        digitalWrite(13, 0);}


message:
Improvised Keyboard?

I want to make a keyboard type panel, which will only have 7 buttons and two knobs, and connect it arduino to program it with functions, he heard that he needed the Keyboard library. but it is not available with arduino uno, which is what I work with, he heard about what I should do a keyboard mapping, it would help me explain to lay a foundation and carry out the project that I want "please do not leave me with the doubt". first of all, Thanks.

body:
If you plan to trigger function on a PC by keystroke and want to simulate a PC keyboard on the PC with your computer than I recommend to use the keyboard lib which is able to map your button to key codes and send them to a PC over USB. But the communication over USB and the simulation of a HID (Human Interface Device) connection is (as far as I know) not possible with an Arduino. (You need a 32u4 or SAMD micro based board) like the leonardo.

But if you just plan to trigger functions, that run on the Arduino, the kb lib is not necessary. That a standard job for the Arduino and can be done with 7 input pins and 2 analog pins.