body: I have an ESP8266 Wemos D1R2 Board with a JSN-SR04T-2.0 ultrasonic range finder and everything works perfectly when I have the device connected to my computer USB or via a 12V battery into the onboard regulator via the external power jack. However when I use a 240V AC to 12V DC transformer to power the setup my readings become quite erratic. I have checked the voltage coming out of the power supply (12.48v) and the voltage going to the sensor (3.28V,  I have it coming off the 3.3V pin) and it is the same on each type of power supply so the onboard regulator is working. Can anyone advise what might cause this? The transformer provides 1A which is more than enough as I have measured the peak usage at <100ma

title: Power supply affecting sensor readings ESP8266 and JSN-SR04T-2.0

Answers: 1

body: The JSN-SR04T-2.0 ultrasonic range finder is rated to 5Volts. giving it 3.3 volts may not be enough. from my limited knowledge it should work if you give it a separate power supply and not depend on the 3.3 volts of the ESP.


body:
I am using Arduino Uno + an attached ESP-01 (ESP8266).

I want to save battery, so I made my Arduino get sleep & interrupt by a watchdog timer.

But if the Arduino goes to sleep, does the attached ESP also sleep?

title: If an Arduino goes to sleep, does the attached ESP also sleep?

Answers: 0


body:
I am using Arduino-uno, attached ESP-01 module

I want to give interrupt when I send some wifi-signal to arduino,
which is in sleep mode.

so I write this code:

```
SoftwareSerial esp(2, 3); // RX, TX

void setup() {
  // put your setup code here, to run once:
 Serial.begin(9600);

  esp.begin(9600);

  attachInterrupt(digitalPinToInterrupt(2),work,RISING);

  delay(1000);

  init_sleep(); // go to sleep
}

void work(){
    light = ! light;

    digitalWrite(12,light);

}

```

when I don't write down the init_sleep, this interrupt is able to work.

but when the arduino is in sleep mode, because of writing 'init_sleep'
It does not react signal by interrupt.

Is it impossible to wake up sleeping arduino by attachInterrupt() ?
please give me some solution.

title: How to get interrupt while in sleep mode?

Answers: 0


body:
I am working on an Arduino project where I use an infra red camera along with 4 transmitters placed each on a corner of a square platform to park a robot perfectly on this platform.
However, it is important for the camera to distinguish between the 4 transmitters.
(it should know the right transmitters from the left and the upper transmitters from the lower).
Can anyone please help me find a solution to this problem?

title: Distinguishing between multiple Infra Red Transmitters

Answers: 1

body:
It's a symmetry problem, you can solve it breaking the simmetry.
Options:

 - use three transmitter instead of four, the plane and its center is
   still determined.
 - move one transmitter in the middle of the side of the square.
 - use different duty cycle for one (or more) transmitter.
 - use linear polarizing filters on the transmitters and a rotating filter on the camera lense.
 - ...

I guess that also [SVD][1] could be helpful to find the pattern's center, when the camera is not centered and perpendicular.

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


body:
I'm using  nfc 2 click (NT3H2111), I tried via arduino to send data to my mobile phone using this code :

    #include <Wire.h>

    int i = 0;
    int j = 0;

    uint8_t NDEF_DATA[] = { 0x03, // NDEF Message
    15, // Message size
    0xD1, // Record header
    1, // Type Length - 1 byte
    11, // Payload Length - 11 bytes
    'U', // Type / URI
    0x01, // Payload
    'm', 'i', 'k', 'r', 'o', 'e', '.', 'c', 'o', 'm',
    0xFE
    }; // NDEF Message End Mark

    void setup()
    {

    delay(5000);
    Wire.begin();
    // initialisation de la liaison I2C
    Serial.begin(9600);
    // initialisation de la liaison série vers la console

    Wipe_Tag() ;

    Wire.beginTransmission(0x55);
    Wire.write(0x00);
    Wire.endTransmission();
    Wire.requestFrom(0x55, 7);
    Serial.println("UUID:");
    while(Wire.available())
    {
    Serial.print(Wire.read(),HEX);
    }

    delay(1000);
    Serial.println();

    Serial.println("Start wrting");
    Wire.beginTransmission(0x55);
    Wire.write(0x01);

    for (i = 0; i < 16; i++)
    {
    Wire.write(NDEF_DATA[i]); //Fill Block with Data
    }
    Wire.endTransmission();
    delay(50);

    Wire.beginTransmission(0x55);
    Wire.write(0x02);

    for (i = 16; i < 32; i++)
    {
    Wire.write(NDEF_DATA[i]); //Fill Block with Data
    }
    Wire.endTransmission();
    delay(50);

    Serial.println("Start wrting");

    }
    void loop()
    {

    }

    void Wipe_Tag()
    {
    for (i = 1; i < 50; i++)
    {
    Wire.beginTransmission(0x55);
    Wire.write(i);
    for (j = 0; j < 16; j++)
    {
    Wire.write(0x00); //Fill Block with Zeros
    }
    Wire.endTransmission();
    delay(50); //Delay 50 ms

    }
    }

All I get is the right UUID than nothing happened, if I try to put my phone I can't read nothing ( it should send me to mikroe website).

As I'm using the nfc 2 click from mikroe.

Thanks for reading.

title: NFC wont send URL to mobile phone

Answers: 0


body:
I'm using a 28BYJ-48 stepper motor with a ULN2003 driver board. I'm trying to control the motor using an Arduino MEGA. I initially connected the pins on the driver: IN1,2,3,4 to pins of the Arduino: 8,9,10,11 respectively; as was given in a youtube video I referred to(https://www.youtube.com/watch?v=HdqCtAJxhrs). The power for the motor was given from the 5V and GND ports in the Arduino. What happens is that it rotates 180 degrees,and then stops and then goes at random angles and stops. This was the code:
<!-- language-all: lang-cpp -->

    #include <Stepper.h>

    Stepper stepper1(64,8,9,10,11);
    int a=1;

    void setup() {
      stepper1.setSpeed(50);
    }

    void loop() {
      while(a<10){
        stepper1.step(2048);
        delay(1000);
        a++;
      }
    }

title: My stepper motor connected to a driver and an Arduino is not working

Answers: 1

body:
For those who missed the comments, what I made a mistake in, as @JRobert pointed is that I was suppose to have connected the stepper motor to a separate power supply as the Arduino was not capable of so much resources. I also altered the code as I think I had gotten the steps-per-revolution wrong which is needed in the Stepper function in the Arduino Code. One needs to check this with the datasheet or somewhere online for the respective stepper motor model. The final code that got it working is [here][1]. All thanks to @JRobert for helping me figure out the solution :)

  [1]: https://www.mschoeffler.de/2017/09/23/tutorial-how-to-drive-the-28byj-48-stepper-motor-with-a-uln2003a-driver-board-and-an-arduino-uno/


body:
I've been trying to store data in an external I2C EEPROM but it doesn't seem to work, and i don't know why.

When i run the i2c scanner it founds my memory but i can't write in it, or at least it seems like i can´t

Please help me :(

(I'm using a 24C512 btw)

```
#include <SoftwareSerial.h>
SoftwareSerial BT1(3, 4); // RX | TX
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <EEPROM.h>

#define EEPROM_I2C_ADDRESS 0x50

//Vcc - Vcc
//Gnd - Gnd
//Din - Mosi (Pin 11)
//Cs  - SS (Pin 10)
//Clk - Sck (Pin 13)

String inicio="";
const int pinCS = 10;
const int numberOfHorizontalDisplays = 8;
const int numberOfVerticalDisplays = 1;
String bt;
//String cadena[]={"holamundooooooooo"};  //textos
int i=0;
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

const int wait = 25; // Velocidad a la que realiza el scroll(Velocidad a la que se muestra la frase)

const int spacer = 1;
const int width = 5 + spacer; // Ancho de la fuente a 5 pixeles

void setup()
   {
       Serial.begin(9600);
       Serial.println("Enter AT commands:");
       BT1.begin(9600);

        matrix.setIntensity(15); // Ajustar el brillo entre 0 y 15

 // Ajustar segun las necesidades
 matrix.setPosition(0, 0, 0); // El primer display esta en <0, 0>
 matrix.setPosition(1, 1, 0); // El segundo display esta en <1, 0>
 matrix.setPosition(2, 2, 0); // El tercer display esta en <2, 0>
 matrix.setPosition(3, 3, 0); // El cuarto display esta en <3, 0>
 matrix.setPosition(4, 4, 0); // El quinto display esta en <4, 0>
 matrix.setPosition(5, 5, 0); // El sexto display esta en <5, 0>
 matrix.setPosition(6, 6, 0); // El séptimo display esta en <6, 0>
 matrix.setPosition(7, 7, 0); // El octavo display esta en <7, 0>
 matrix.setPosition(8, 8, 0); // El noveno display esta en <8, 0>

 matrix.setRotation(0, 1);    // Posición del display
 matrix.setRotation(1, 1);    // Posición del display
 matrix.setRotation(2, 1);    // Posición del display
 matrix.setRotation(3, 1);    // Posición del display
 matrix.setRotation(4, 1);    // Posición del display
 matrix.setRotation(5, 1);    // Posición del display
 matrix.setRotation(6, 1);    // Posición del display
 matrix.setRotation(7, 1);    // Posición del display
 matrix.setRotation(8, 1);    // Posición del display

 char bt[]={"prueba"} ;
   }

void loop()
   {
 //bluetooth recoger datos
 if(BT1.available()){
  bt="";
 }
 int i=0;
  while(BT1.available()){
       // Serial.write(BT1.read());
        char c=(char)BT1.read();
        if((c=='a')||(c=='b')||(c=='c')||(c=='d')||(c=='e')||(c=='f')||(c=='g')||(c=='h')||(c=='i')||(c=='j')||(c=='k')||(c=='l')||(c=='m')||(c=='n')||(c=='ñ')
        ||(c=='o')||(c=='p')||(c=='q')||(c=='r')||(c=='s')||(c=='t')||(c=='u')||(c=='v')||(c=='w')||(c=='x')||(c=='y')||(c=='z')||
          (c=='A')||(c=='B')||(c=='C')||(c=='D')||(c=='E')||(c=='F')||(c=='G')||(c=='H')||(c=='I')||(c=='J')||(c=='K')||(c=='L')||(c=='M')||(c=='N')||(c=='Ñ')
        ||(c=='O')||(c=='P')||(c=='Q')||(c=='R')||(c=='S')||(c=='T')||(c=='U')||(c=='V')||(c=='W')||(c=='X')||(c=='Y')||(c=='Z')||(c==' ')){
          bt=bt+char(c);

          writeByte(EEPROM_I2C_ADDRESS,i, (byte)c);

          i++;
          delay(50);

        }else{
          bt=bt;
        }
  }
  Serial.println(bt);

String palabrasacada;
for(int i=0; i<bt.length(); i++){
  byte z=readByte(EEPROM_I2C_ADDRESS,i);
  char a=char(z);
  palabrasacada=palabrasacada+String(a);
}

String cadena[]={palabrasacada};
int n = random(0,1);

 for (int i = 0; i < width * cadena[n].length() + matrix.width() - 1 - spacer; i++) {

 matrix.fillScreen(LOW);

 int letter = i / width;
 int x = (matrix.width() - 1) - i % width;
 int y = (matrix.height() - 8) / 2; // Centrar el texto

 while (x + width - spacer >= 0 && letter >= 0) {
 if (letter < cadena[n].length()) {
 matrix.drawChar(x, y, cadena[n][letter], HIGH, LOW, 1);
 }

 letter--;
 x -= width;
 }
 matrix.write(); // Muestra loscaracteres
 delay(wait);
 }
}

void writeByte(int device, unsigned int add, byte data)
{
  Wire.beginTransmission(device);
  Wire.write((int)(add >> 8)); // left-part of pointer address
  Wire.write((int)(add & 0xFF)); // and the right
  Wire.write(data);
  Wire.endTransmission();
  delay(5);//small delay for eeprom to save data
}

// reads a byte of data to the I2C address 'device', in memory location 'add'
byte readByte(int device, unsigned int add)
{
  Wire.beginTransmission(device); // I2C address
  Wire.write((int)(add >> 8)); // bit shift for high byte of pointer address
  Wire.write((int)(add & 0xFF)); // mask for the low byte
  Wire.endTransmission();
  Wire.requestFrom(device, 1);
  return Wire.read();
}
```

The led matrix and bluetooth receiving actually works, but i'm adding them anyways, just in case

title: I can't write or read data in an external eeprom

Answers: 0


body:
I am very new to Arduino. In fact I am entirely new to embedded system. I have been using other platforms for my experiments specifically PICs.

I just moved to Arduino for more easier coding but I am hooked somewhere.

Here is the constraints:

In the code I will post below;

1. When MAINS is present and is within usable range, both MAINS_OK & ENABLE Pins will go HIGH after 3sec delay(non-blocking).

2. When MAINS is BAD, MAINS_OK Pin will go LOW immediately while ENABLE Pin will wait for 3sec before going LOW.

3. If MAINS is recovered and is within usable range again, the sequence described in "1." must be followed an so on.

I have tried in so many ways, it is not working as expected. Only the blinking of the SYSTEM LED is working fine.

```
// constants won't change. Used here to
// set pin numbers:
const int enablePin     = 7;      // the number of the Function Pins
const int lvdPin        = 6;
const int sysledPin    = 5;
const int mainsokPin   = 4;

// Variables will change:
int mainsPin = A0;
int batteryPin = A2;
int MAINS;
int BATT;
int ENABLE = LOW;
int LVD = LOW;
int SYS_LED = LOW;
int MAINS_OK = LOW; // State used to set the Function Pins

long previousMillis1 = 0;
long previousMillis2 = 0;// will store last time PIN was updated
long previousMillis3 = 0;
long previousMillis4 = 0;
long previousMillis5 = 0;

long ENABLE_ON        = 3000;
long ENABLE_OFF       = 3000;
long LVD_ON           = 3000;
long LVD_OFF          = 3000;
long MAINS_DELAY_ON   = 3000;
long MAINS_DELAY_OFF  = 0;
long SYS_LED_ON       = 1000;
long SYS_LED_OFF      = 1000; //Duration of the delay time (milliseconds)

void setup()
{
  pinMode(ENABLE, OUTPUT);  // set the digital pin as output:
  pinMode(LVD, OUTPUT);     // set the digital pin as output:
  pinMode(SYS_LED, OUTPUT); // set the digital pin as output:
  pinMode(MAINS_OK, OUTPUT); // set the digital pin as output:
  pinMode(A0, INPUT); //set pin as Analog nput
  pinMode(A1, INPUT); //set pin as Analog nput
}
void loop()
{
  unsigned long currentMillis1 = millis();
  unsigned long currentMillis2 = millis();
  unsigned long currentMillis3 = millis();
  unsigned long currentMillis4 = millis();

  if ((SYS_LED == LOW) && (currentMillis1 - previousMillis1 >= SYS_LED_OFF))
  {
    SYS_LED = HIGH;  // Turn it off
    previousMillis1 = currentMillis1;  // Remember the time
    digitalWrite(sysledPin, SYS_LED);  // Update the actual SYS_LED
  }
  if ((SYS_LED == HIGH) && (currentMillis1 - previousMillis1 >= SYS_LED_ON))
  {
    SYS_LED = LOW;  // turn it on
    previousMillis1 = currentMillis1;   // Remember the time
    digitalWrite(sysledPin, SYS_LED);    // Update the actual SYS_LED
  }

  MAINS = analogRead(mainsPin);

  //========================= MAINS OK =======================================
  /* If MAINS supply is ok, the MAINS_OK and ENABLE Pins will wait for 3sec
      before going high. Both Pins will go high at the same time.
  */

  if (MAINS >= 84 && MAINS <= 177) // >=0.410V && <=0.864V >=140V && <=250V
    if ((MAINS_OK == LOW) && (currentMillis2 - previousMillis2 >= MAINS_DELAY_ON))
    {
      MAINS_OK = HIGH;  // Turn MAINS_OK on with 3sec delay
      previousMillis2 = currentMillis2;  // Remember the time
      digitalWrite(mainsokPin, MAINS_OK);  // Update the actual MAINS_OK
    }
  if (MAINS >= 84 && MAINS <= 177) // >=0.410V && <=0.864V >=140V && <=250V
    if ((ENABLE == LOW) && (currentMillis3 - previousMillis3 >= ENABLE_ON))
    {
      ENABLE = HIGH;    //Turn ENABLE ON with 3sec delay
      previousMillis3 = currentMillis3;  // Remember the time
      digitalWrite(enablePin, ENABLE);  // Update the actual MAINS_OK
    }

  //=================== MAINS NOT PRESENT or IT IS LOW/HIGH VOLTAGE ====================
  /* As soon as MAINS is lost, whether it enters low voltage or high voltage,
     the PINs MAINS_OK will go LOW imedatly without delay while ENABLE will wait for
     3sec before going LOW. Then If MAINS is restored OK, the initial delay sequence
     must be followed.
  */
  if (MAINS <= 53 || MAINS >= 258) // <= 0.260V || >=1.26V// Below <= 120V and >= 276V
    if ((MAINS_OK == HIGH) && (currentMillis2 - previousMillis2 >= MAINS_DELAY_OFF))
    {
      MAINS_OK = LOW;  // Turn MAINS_OK off after 0sec delay
      previousMillis2 = currentMillis2;  // Remember the time
      digitalWrite(mainsokPin, MAINS_OK);  // Update the actual MAINS_OK
    }
  if (MAINS <= 53 || MAINS >= 258) // <= 0.260V || >=1.26V// Below <= 120V and >= 276V
    if ((ENABLE == HIGH) && (currentMillis3 - previousMillis3 >= ENABLE_OFF))
    {
      ENABLE = LOW;    //Turn ENABLE off aftar 3sec delay
      previousMillis3 = currentMillis3;  // Remember the time
      digitalWrite(enablePin, ENABLE);  // Update the actual ENABLE
    }

  BATT = analogRead(batteryPin);

  //============================ BATTERYERY SETTINGS ==============================
  /* If Battery is below 21V LVD Pin go HIGH with 3sec delay
      When it goes high, it remains high the Batter goes up to 27.6V
      LVD will then go LOW ahter 3sec delay
  */
  if (BATT <= 391) //(1.91V) 21V         // BATTERY Low
    if ((LVD == LOW) && (currentMillis4 - previousMillis4 >= LVD_ON))
    {
      LVD = HIGH; //Turn LVD on with 3sec delay
      previousMillis4 = currentMillis4;  // Remember the time
      digitalWrite(lvdPin, LVD);  // Update the actual LVD
    }

  if (BATT >= 512) // (2.50V)  27.6V         // BATTERY low Recovery
    if ((LVD == HIGH) && (currentMillis4 - previousMillis4 >= LVD_OFF))
    {
      LVD = LOW; // turn LVD off after 3sec delay
      previousMillis4 = currentMillis4;  // Remember the time
      digitalWrite(lvdPin, LVD);  // Update the actual LVD
    }
}

```

Please What can I add or remove from this code for it to work properly?

Thanks.

title: Mains And Battery Monitor Using Delay on And Delay off

Answers: 1

body:
There are lots of problems with your code. To start, most/all of this code is wrong:

      pinMode(ENABLE, OUTPUT);  // set the digital pin as output:
      pinMode(LVD, OUTPUT);     // set the digital pin as output:
      pinMode(SYS_LED, OUTPUT); // set the digital pin as output:
      pinMode(MAINS_OK, OUTPUT); // set the digital pin as output:
      pinMode(A0, INPUT); //set pin as Analog nput
      pinMode(A1, INPUT); //set pin as Analog nput

Those lines should be setting various pins to their desired input/output state. However, you are using the variables you declared to hold their bool status, not their pin numbers.

The variables you are using are declared like this:

    int ENABLE = LOW;
    int LVD = LOW;
    int SYS_LED = LOW;
    int MAINS_OK = LOW; // State used to set the Function Pins

Those are not pin numbers, those are variables that hold boolean values.

This line, for example:

    pinMode(MAINS_OK, OUTPUT); // set the digital pin as output:

Should almost certainly read

    pinMode(mainsokPin, OUTPUT); // set the digital pin as output:

Instead.

Same goes for `enablePin`, `lvdPin`, and `sysledPin`

The two lines

    pinMode(A0, INPUT); //set pin as Analog nput
    pinMode(A1, INPUT); //set pin as Analog nput

Should probably read

    pinMode(mainsPin, INPUT); //set pin as Analog nput
    pinMode(batteryPin, INPUT); //set pin as Analog nput

Since you define the variables `mainsPin` and `batteryPin`.


body:
I've always wanted to make my own game console. I don't know why the existing Arduino game consoles have this issue with framerate when a 2006's [Sony handheld PC][1] had 1GB of RAM and an Intel CPU running Windows XP. Why haven't normal DIY open-sourcing copyright-libertarian hobbyists been able to make something at that magnitude? Don't say money because money is the reason I'm in gamedev scene; wanting to make a game console or anything that has a screen, characters, multimedia and nerdiness to make money.

So the issue has always been how do I find a microcontroller that's enough fast to run a 320x240 display like ILI9341 at 60FPS without stuttering or having to do lots of precalculations for partial screen updates. What about the NES/SNES consoles which didn't even have a framebuffer but which used discrete logic?

 - My scheme was to use ATXMEGA128A1U with a parallel bus and DMA, but it was hard to find a board containing all the stuff I needed and the External Bus Interface.

 - Then I tried to use ESP32 with SPI, but SPI would go max to 80MHz while the screen could only handle 40MHz.

 - Then I tried ESP32 again with 8-bit IO pin permutation which didn't work; it was too slow; maybe it would be faster if I used Xtensa assembly to take advantage of the CPU pipeline in case the dumb C++ compiler compiled machine code that waited 7 cycles for every next operation.

 - But now I'd like to use ESP32 with an I2S bus and DMA which was used for a camera demo and it was really really fast, but I'd like to use it for I2S output for that ILI9341 display. According to my calculations, it should take 10MHz to write out all of the bytes if the bus is 16-bit wide (8 bits for data and 1 bit for Data/Command register) + Read/Write/Select strobes controlled by the bus interface. However, Bitluni has been able to drive it to out of spec values of 580MHz for his VGA library that's superfast, but that month he had nothing to pay his rent with so he licensed the code under a copyleft license (ShareAlike). You know what they say, "The love of money and the lack of money are the roots of all evil.". Money is important, but really... this just makes money an even worse enemy than it was before.

So I guess I'm out of options. There have been many attempts and they have failed. Yes, there's Teensy and stuff, but I need something in the EU which I won't have to pay for more in shipping than the actual product.

So, what are the solutions?

P.S. if I get one of those "off-topic" or "too-broad" or dislikes to my question, I'm deleting it and moving to Reddit and screenshooting how yet again StackExchange is just too formalistic and banhammersome to open conversations.

  [1]: https://www.youtube.com/watch?v=E1r2e8ub02o

title: Which Arduino microcontrollers are able to drive a parallel 8-bit ILI9341 display at 320x240@60fps with DMA or extra CPU core or both and how?

Answers: 1

body:
The problem is the whole concept of running an ILI9341 TFT screen at 60FPS from a microcontroller. You can't. It's just not fast enough.

To get those kind of speeds you need to directly interface the TFT panel with the microcontroller. And that takes a special microcontroller with a TFT interface built in.  As well as that you need the memory to store the image that you are displaying on the screen.

There are microcontrollers available that can do it quite happily.  But they aren't in the "maker scene". Simply because they aren't a common thing to do.

For many years now there has been the PIC24 "DA" range of microcontrollers with a built in GPU and TFT interface - but there is no free C++ compiler, so no Arduino support - so no easy route to using them for beginners.

There are now, though, the PIC32MZ "DA" rage which are more accessible - though still very hard to use.  These are much more viable for the kind of thing you want, with 32MB of built in DDR, a TFT panel interface, and available in a 144 pin TQFP chip that is possible for an experienced maker to hand solder.

But the barrier is still software.  While chipKIT has full support for the PIC32MZ "EF" range of chips the "DA" range is not yet supported.  That's not to say you can't work with them, just not with the Arduino API and IDE.

The more common way to make a games console like device is to take an ARM SoC and interface it with a TFT panel directly. The simplest way for a maker to do that is to put a TFT on a Pi and install Retropie.

And we're not against open discussion as people. It's the site. It's not a site for open discussion. It's a *question and answer site*. You ask a technical question that you need assistance with, and we tell you the answer. It's not a forum for general discussion.  As such, this question will be closed as either "top broad" or "primarily opinion based". However your question does deserve an answer anyway.


body:
I recently run into a problem that causing my whole code processing slow down, for example i had a millis timer set for one minute but it took 1:30m to finish, pressing buttons was laggy etc.

After hours of digging and commenting out codes piece by piece i finally found out what is causing the slow down!

my DS18B20 temperature sensor DATA pin is connected to pin A0 when i remove the library and related codes to the sensor processing became MUCH faster more snappier/responsive...

After googling a bit i realized that everyone connected the sensor to pin 2 of Arduino!

So is the processing slow because DS18B20 is on pin A0 instead of pin 2 **or** there's something wrong with the sensor itself **or** it is because of [This library][1]?

  [1]: https://github.com/milesburton/Arduino-Temperature-Control-Library

title: Is DS18B20 temperature sensor makes Arduino processing slow?

Answers: 2

body:
Indirectly it's the library.

That library uses the OneWire.h library.  The OneWire protocol requires some reasonably precise timing, and because of the the OneWire.h library turns off interrupts while it communicates.

While interrupts are disabled nothing else can happen. That means that the timer interrupt that drives `millis()` can't "tick" - so the millis count doesn't increase while you communicate with the temperature sensor.

body:
The **software function** managing the 1-wire protocol generally has several non-interruptable sections in order to ensure the bus timings.  This can make your processor unavailable for long periods of time.

Worse, some implementations do not allow any interrupt at all.

And even if your implemenation would allow being interrupted, it is generally blocking the main loop as it is not executed in an interrupt itself.

Using a **hardware implementation** for the 1-wire control instead of a full software would release the CPU from managing the timing and waiting for the 1-wire to complete.  But such hardware implementation are not commonly available in microcontrollers.

There is however a middle way.  An open source implementation using **the microprocessor's or controller's UART** to ensure the timings is available ( https://github.com/MaJerle/onewire_uart ) - MAXIM also has an application note for it ( https://www.maximintegrated.com/en/app-notes/index.mvp/id/214 ).
This also offloads the processor and it can be interrupt driven.

**Is the processing slow because DS18B20 is on pin A0 instead of pin 2 ?**
That might have an influence if the processor that is on your Arduino board would have a (partially) 1-wire compatible source on another pin, in which case the libary would have to take advantage of that.

**Is there something wrong with the sensor itself?**
That would not be generally the case, but in case you have two sensors on the same bus, the 1-wire protocol is slower as it needs to find all peripherals and the master has to indicate which one it is addressing.

**Is it because of "This library"?**
It is not because of that library, but there are other implementations (see the link above) that use hardware resources to improve performance at the cost of using a hardware resource (some MCU's have only 1 HW UART so you'ld not have a second one if you also need RS232 communication for instance on other signal lines).


body:
This is actually a follow up question to [this question][1], so basically I'm using DS18B20 temperature sensor which requires Onewire.h library that interrupts millis() function.

Luckily i have a [DS3231 RTC][2] module which I'm using it with [RTClib library][3], is there any way to use that module as a timer instead of millis() function?

  [1]: https://arduino.stackexchange.com/questions/67125/is-ds18b20-temperature-sensor-makes-arduino-processing-slow
  [2]: https://www.amazon.com/DS3231-AT24C32-module-precision-Arduino/dp/B00HCB7VYS
  [3]: https://github.com/adafruit/RTClib

title: Do we have an alternative for millis() function?

Answers: 1

body:
You can use the SQW output of the module to indicate the passage of precisely 1 second. Every time it transitions from LOW to HIGH one second will have passed.

RTCs cannot give you times of higher resolution than 1 second, but they can give you that 1 second granularity to a high accuracy.


body:
I need to control 220V RGB Led strip with Arduino/ESP32-wroom over internet.
Single color led is easy (just with a relay), 12V RGB can be done with PWM and maybe external power source. But how can I control 220V RGB via MCU?
I couldn't find any answer yet.

title: How to control 220V RGB Led Strip with Arduino/ESP32

Answers: 1

body:
Try looking at a relay or a [triac](https://en.m.wikipedia.org/wiki/TRIAC).

Also, you can not simply "use PWM to control a 12V circuit from your MCU" which is most likely running at 5V. You need to use a component such as a MOSFET. The MCU controls the MOSFET via the Gate. The MOSFET switches the 12 V circuit off or on based upon the signal at the gate.

Alternatively, like the AC solution, you can use a Relay to control the 12V circuit.


body:
So I programmed my Arduino Mega 2560 to play certain sound effects from a DF Mini Player that I have. I  took the base code that I modified from online so some fo the names might seem odd. Currently, when uploaded to the Arudino, it works as it should, "buttonPause" and "play()" only play one of the audio files WHILE I am pressing a button. "buttonNext"/"play1()" and "buttonPrevious"/"play2()" activate a sound when a button is tapped (not held down). To allow the sound effect to play in full only while I'm, holding down "buttonPause," I had to use a delay as well as interrupt to stop the playback as soon as I released the button. However, I know aside from changing pin numbers, there are some other alterations I have to make for the interrupt to adapt it to work with the ATTiny85. Any idea how I can get started on making those changes? I have been confused by the sources I have found online.

Full code for using the DF Mini Player with the Arduino Mega

    ///              MP3 PLAYER PROJECT
    /// http://educ8s.tv/arduino-mp3-player/
    //////////////////////////////////////////
    #include "SoftwareSerial.h"
    SoftwareSerial mySerial(10, 11);
    # define Start_Byte 0x7E
    # define Version_Byte 0xFF
    # define Command_Length 0x06
    # define End_Byte 0xEF
    # define Acknowledge 0x00 //Returns info with command 0x41 [0x01: info, 0x00: no info]
    # define ACTIVATED LOW

    int buttonNext = 2;
    int buttonPause = 3;
    int buttonPrevious = 4;
    boolean isPlaying = false;
    const byte interruptPin = 3;
    volatile byte state = LOW;
    int buttonState = 0;
    int buttonState1= 0;
    int buttonState2= 0;
    int ledPin = 9;

    void setup () {
    pinMode(buttonPause, INPUT);
    digitalWrite(buttonPause,HIGH);
    pinMode(buttonNext, INPUT);
    digitalWrite(buttonNext,HIGH);
    pinMode(buttonPrevious, INPUT);
    digitalWrite(buttonPrevious,HIGH);
    mySerial.begin (9600);
    attachInterrupt(digitalPinToInterrupt(interruptPin), pause, CHANGE);
    pinMode(ledPin, OUTPUT);

    }
    void loop () {

    buttonState = digitalRead(buttonPause);
    buttonState1 = digitalRead(buttonNext);
    buttonState2 = digitalRead(buttonPrevious);

    if (buttonState == LOW)
      {
          play();
          setColor(255, 0, 222); // red
          digitalWrite(ledPin, HIGH);
          delay(1500);

      }

    if (buttonState1 == HIGH)
      {

      }

    if (buttonState == HIGH)
      {

      }

      if (buttonState1 == LOW)
      {
          play1();

          delay(100);

      }

    if (buttonState2 == HIGH)
      {

      }

        if (buttonState2 == LOW)
      {
          play2();

      }

    }

    void pause()
    {
      execute_CMD(0x16,0,0);

          digitalWrite(ledPin, LOW);
    }
    void play()
    {
      execute_CMD(0x03,0,1);
    }
    void play1()
    {
      execute_CMD(0x03,0,2);
    }
    void play2()
    {

      execute_CMD(0x03,0,3);
    }

    void execute_CMD(byte CMD, byte Par1, byte Par2)
    // Excecute the command and parameters
    {
    // Calculate the checksum (2 bytes)
    word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
    // Build the command line
    byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
    Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte};
    //Send the command line to the module
    for (byte k=0; k<10; k++)
    {
    mySerial.write( Command_line[k]);
    }
    }

Board Layout

The amount and placements of the resistors seemed to reduce the amount of noise as much as possible.

[![layout1][1]][1]

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

title: How to adapt this code using a DF Mini Player and interrupts for the ATTiny85?

Answers: 0


body:
ESP32 tx2 (pin17) and rx2 (pin16) uses 3.3v based signals.

HX-53 data connect to tx2, gnd to gnd and vcc to vin(5v).

But as i can understand HX-53 data input should be 5v based.

How can i solve this problem?

HX-53: https://www.amazon.com/Electronic-Infrared-Emission-Transmitter-Arduino/dp/B07PJC7WSQ

Best regards.
GA

title: how to use hx-53 (IR Transmitter Infrared Sensor Module) with ESP32?

Answers: 2

body:
The HX-53 look like a IR LED and a current limiting resistor on a small PCB.

It also has a LED and a resistor in series for indication when the invisible IR diode is on or off.

So you can change the resistor to a lower value to match the 3,3 volt output from the ESP32.

Resistor values:

    221 = 220 ohm   = IR LED
    102 = 1000 ohm  = SMD indicator LED

So replace the 220 ohm with something near 75 ohm.

**HX-53**

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

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

body:
I happen to have one just like yours. I was trying to use it on my Arduino to send commands to my AC like a remote but as it turns out, the Vcc pin on the HX-53 breakout board appears to be a dummy and doesn’t connect to anything as far as i know. By right there should be a transistor circuit driving that LED. As it is now, not only is there insufficient current from the signal pin to drive that IR LED for signal bursts, but the red SMD LED in series with the resistor is also stealing some of the current away from the IR LED. In the end, I had to buy a BJT, a standalone IR LED, some resistors and design my own transistor circuit to drive it.

On the transistor’s collector side I had a connection to Vcc and the IR LED in series with a resistor. On the base side was a connection to the signal pin and a resistor. The emitter was connected directly to Ground. Values of the resistors you use will depend largely on the Vcc, the LED max forward current, the specs of the transistor you choose and available current from the power supply.

Hope this helps.


body:
I use `Serial.write()` to transmit 53 bytes to PC. For the time measurement I use `micros()` (before and after the write function). There is a delay of 1s after each transmission.

The time of the `Serial.write()` function is 532 us with 1000000 baud rate, and 360 us with 9600 baud rate.

The `Serial.write()` function is clearly asynchronous because the transmission of 53 bytes with 9600 baud rate is 53*8/9600*1e6 = 44167 us. (By the way, in the case of 1000000 baud rate, it is not so obvious that the function is asynchronous.)

I use `Serial.availableForWrite()` before `Serial.write()` to confirm that there is enough space in the buffer (this returns 63 each time, the buffer size is default 64).

I don't understand these numbers. Using `memcpy()` to copy the 53 bytes only takes 32 us. Is copying to the serial buffer not the same as the `memcpy()` function? And why is there a difference in the copy times when the baud rate is different? Serial.write() is even slower with higher baud rates according to the results. Why does `Serial.availableForWrite()` return 63 while the buffer size is 64 (according to SERIAL_TX_BUFFER_SIZE)?

Update:
Thanks for all of your answers.

I have tried another library for serial communication: https://github.com/greiman/SerialPort

It seems to be faster than the original one.
I use 2 time measurements and a delay in the code, these 3 deltaTimes represents the whole step as follows:

writeTime + memcpyTime + delaymicros = computedTime != realTime

The first 2 times are measured, the delaymicros is the theoretical delay (900 us), I can compute the step time from these. This computed step time is different from realTime (the measured step time, I measure the whole step too). It seems that the additional time can be found in the delay.

SerialPort library:
100 + 30 + 900 = 1030 != 1350

writeReal = 100 + 1350 - 1030 = 430

Arduino Serial:
570 + 30 + 900 = 1500 != 1520

writeReal = 570 + 1520 - 1500 = 590

Then I measured the delaymicros time (which is 900 us in theory), the missing time can be found there. I programmed 900 us delay, but the real delay was around 1200 in the first, and 920 in the second test.

These measurements can prove the existence of the interrupts, because measuring only the write functions doesn't give all of the writing time (especially with the downloaded serial library).
The downloaded library can work faster, but requires bigger tx buffer because of errors (256 works properly instead of 64).

Here is the code: I use a checkSum in the sendig function (which is 570-532 = 38 us). I use Simulink to receive and process the data.
<!-- language-all: lang-cpp -->

    struct sendMsg1 {
      byte errorCheck;//1

      unsigned long dT1;//4
      unsigned long dT2;//4
      unsigned long t;//4
      unsigned long plus[10];//40
    };//53

    sendMsg1 msg1;
    byte copyMsg1[53];

    unsigned long time1;
    unsigned long time2;
    unsigned long time3;
    unsigned long time4;

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

    void loop() {
      sensorRead();
      sendMsg1_f();

      //time3 = micros();
      delayMicroseconds(900);
      //time4 = micros();
    }

    void sensorRead() {
      time3 = micros();

      msg1.t = micros();
      for (unsigned long i = 0; i < 1; i++) {
        memcpy((void*)&(copyMsg1[i*sizeof(sendMsg1)]), (void*)&msg1, sizeof(sendMsg1));
      }

      time4 = micros();
      msg1.dT2 = time4 - time3;
    }

    void sendMsg1_f() {
      time1 = micros();

      msg1.errorCheck = 0;
      for (int i = 0; i < sizeof(sendMsg1) - 1; i++) {
        msg1.errorCheck += ((byte*)&msg1)[i];
      }
      Serial.write((byte*)&msg1,sizeof(sendMsg1));

      time2 = micros();
      msg1.dT1 = time2 - time1;
    }

title: Why is Serial.write() slower than memcpy()?

Answers: 3

body:
If you take a look into the implementation:

<!-- language: c++ -->

    size_t HardwareSerial::write(uint8_t c)
    {
      _written = true;
      // If the buffer and the data register is empty, just write the byte
      // to the data register and be done. This shortcut helps
      // significantly improve the effective datarate at high (>
      // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
      if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) {
        // If TXC is cleared before writing UDR and the previous byte
        // completes before writing to UDR, TXC will be set but a byte
        // is still being transmitted causing flush() to return too soon.
        // So writing UDR must happen first.
        // Writing UDR and clearing TC must be done atomically, otherwise
        // interrupts might delay the TXC clear so the byte written to UDR
        // is transmitted (setting TXC) before clearing TXC. Then TXC will
        // be cleared when no bytes are left, causing flush() to hang
        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
          *_udr = c;
    #ifdef MPCM0
          *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << MPCM0))) | (1 << TXC0);
    #else
          *_ucsra = ((*_ucsra) & ((1 << U2X0) | (1 << TXC0)));
    #endif
        }
        return 1;
      }
      tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;

      // If the output buffer is full, there's nothing for it other than to
      // wait for the interrupt handler to empty it a bit
      while (i == _tx_buffer_tail) {
        if (bit_is_clear(SREG, SREG_I)) {
          // Interrupts are disabled, so we'll have to poll the data
          // register empty flag ourselves. If it is set, pretend an
          // interrupt has happened and call the handler to free up
          // space for us.
          if(bit_is_set(*_ucsra, UDRE0))
     _tx_udr_empty_irq();
        } else {
          // nop, the interrupt handler will free up space for us
        }
      }

      _tx_buffer[_tx_buffer_head] = c;

      // make atomic to prevent execution of ISR between setting the
      // head pointer and setting the interrupt flag resulting in buffer
      // retransmission
      ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
        _tx_buffer_head = i;
        sbi(*_ucsrb, UDRIE0);
      }

      return 1;
    }

It basically answers all the questions.

If the buffer is empty and it's not sending anything, it'll send the character directly so it's synchronous (but sending the character will be much faster than overhead of function callbacks and so)

No, you cannot use memcpy, as it just replaces buffer, but it does nothing else, like actually start the data register ready interrupt nor proper setting of head/tail counters (it's round buffer, so there can be scenario you'll overwrite something outside of buffer)

And write function is called for each character separately (all other specialisation of write are using this one)

Also if the buffer is full, it'll wait until there is a space for another character.

body:
Copying to the serial buffer is not the same as `memcpy()`, no.

The serial buffer is a [circular buffer](https://en.wikipedia.org/wiki/Circular_buffer). Because of that there are lots of calculations involved in working out exactly where in the buffer to place the next character. That takes time.  `memcpy()` just copies one block of memory directly over another. It makes no checks, and it can't wrap around like a circular buffer.

The reason why higher baud rates seem slower is because each character is taken from the buffer by an interrupt. The higher the baud rate the more often that interrupt is triggered, and so the more time is spent by the CPU in processing that interrupt to send the next character. And equally, the less time is available to the CPU to process the placing of data into to the serial buffer.

body:
The function you were testing is presumably
`Serial.write(const uint8_t *buffer, size_t size)`.
If you search for it in HardwareSerial.h, you will see

```c++
    using Print::write; // pull in write(str) and write(buf, size) from Print
```

and the implementation is in Print.cpp:

```c++
/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
  size_t n = 0;
  while (size--) {
    if (write(*buffer++)) n++;
    else break;
  }
  return n;
}
```

This is writing the bytes one by one, and for every byte, the whole code
of `HardwareSerial::write(uint8_t c)` is being run. This includes the
tests for full or empty buffer, and the arithmetic for updating
`_tx_buffer_head`.

As stated in the comment above the code, it would have been possible to
override this with a specialized implementation. In principle, you could
copy the linear buffer into the ring buffer using at most two calls to
`memcpy()`, and updating `_tx_buffer_head` only once. That would likely
be more efficient than the current implementation, at least for buffer
sizes in the range you are using (close to, but less than the ring
buffer capacity).

Would it be worth it? Maybe for your use case it would. But it could
also make the code more complex and require more flash. And the benefit
is likely to be really small for people who write small buffers. I am
not sure a pull request implementing this sort of optimization may be
accepted. You may try if you feel like so.


body:
I am programming my Atmega328P chip via a USB to TTL converter (https://www.amazon.com/gp/product/B075N82CDL/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)

I am able to upload hex files via the command line and the Arduino IDE when I have the RTS pin of the adapter and a capacitor attached to the !RESET pin of the Atmega. (http://www.electronics-lab.com/wp-content/uploads/2018/09/programming-Uno-on-breadboard.png)

I am also able to upload via the command line when I have a push button attached to the !RESET pin and manually pull it low then begin uploading the firmware within a few moments. (https://cdn.instructables.com/F0L/2F6U/J7AQSHD1/F0L2F6UJ7AQSHD1.LARGE.jpg)

My problem is that for my application I will only have the TX/RX/Vcc/GND pins available (no RTS or push button) and need to reset the micro controller so the bootloader runs and listens to be programmed with updated firmware.

So far I have written a batch file that sends a command to restart the Arduino, and then calls avrdude to upload a hex file. I have tried two methods of restarting the micro controller. I have told it to go to memory location zero, and I have attached an IO pin to the reset and dropped it low (although it stays low until reset, so the reset doesn't really work until I manually remove the wire between the IO pin and the !RESET pin)

My sequence is as follows:

1. Have Arduino running code:
<!-- language-all: lang-cpp -->
```
    int recvByte;
    int delayS = 400;
    int resetPin = 9; //bttom right pin of uC

    void setup() {
      // put your setup code here, to run once:
    pinMode(txPin, OUTPUT);
    pinMode(rxPin, INPUT);
    pinMode(resetPin, OUTPUT);
    digitalWrite(resetPin, HIGH);
    Serial.begin(57600);
    Serial.write("Booted/reset");
    Serial.write("This setup was uploaded with batch");
    }

    void(* resetFunc) (void) = 0;

    void loop() {

    if (Serial.available() )
    {    // get incoming byte:
        recvByte = Serial.read();
        if (recvByte==int('r'))
        {
        Serial.write("resetting");
        delay(10); //wait for last message to send
        //digitalWrite(resetPin, LOW); //commented out because this method stays low until wire is removed
        resetFunc();
        Serial.write("should not see if reset properly");
        }

    }

    delay(100);
    }
```

2.I then run my batch file.
```
echo Running upload bat, sending reset command then calling avrdude
cd "C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\"
python "path\sendR.py"
.\avrdude.exe -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -carduino -PCOM6 -b57600 -D -Uflash:w:"path\Atmega328code.hex":i
```

The python sendR.py is to send the "r" character, which the Arduino views as the reset command.
```
import serial
ser = serial.Serial("COM6", baudrate=57600)  # open serial port
bytes = "r".encode()
ser.write(bytes)
ser.close()
print("End python script")
```

When I send "r" via Tera Term or python the setup code runs again, but I have not been able to upload with the `.\avrdude.exe -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -carduino -PCOM6 -b57600 -D -Uflash:w:"path\Atmega328code.hex":i` command inside the batch file. If I use the pushbutton to do a hardware reset, this command works without issue.

How can I upload new firmware via the RX and TX pins using software to reset the microcontroller and listen for new code as the bootloader runs?

New ideas tried:
Use a uniform baud rate of 57600 in python and atmega serial setup. I chose this value because the Arduino IDE output this baudrate in `avrdude.exe -C"C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -carduino -PCOM6 -b57600 -D -Uflash:w:"path\Atmega328code.hex":i`
[![enter image description here][1]][1]

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

title: How do I properly trigger the ATMega328 reset pin via software so that the bootloader runs and the firmware can be updated via RX/TX pins?

Answers: 1

body:
You wrote:

> `void(* resetFunc) (void) = 0;`

This seems to me like an approach worth trying, except that the function
address is wrong. At address zero of the flash you have the start of the
user's code. The bootloader, if you do use one, lives at the end of the
flash. The start address of the bootloader depends on its size, and is
configured by setting some fuses on the chip. If you are using the
popular optiboot (the bootloader of the Uno), you have to jump to
exactly 512 bytes before the end of the flash, i.e.:

```c++
void (*resetFunc)(void) = 0x7e00;
```

Oh, wait... the flash is organized as 16-bit words, so you may have to
use the wordwise address instead:

```c++
void (*resetFunc)(void) = 0x3f00;
```

But do note that, unlike a real hardware reset, this approach does not
reset the peripherals to their normal initial state. You may want to do
it before jumping to the bootloader.

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

**Edit**: I have disassembled a test program that does this kind of
call-by-pointer, then double checked the documentation of [the `icall`
instruction][icall]. It appears that the function address you provide is
indeed interpreted as a word-wise address, so you should write half the
byte-wise address. If you write anything larger than the size of the
flash (`0x4000` = 16 kilowords), the most significant bits get
lost, and the address gets reduced to the correct range modulo the flash
size.

That is, if `0x7800` worked for you, then presumably the correct address
is `0x3800`, i.e. 2 kilowords (4 KB) before the end of the
flash. This is quite a large bootloader, and the largest size supported
by the ATmega328P. Are you sure it is righ? Aren't you sliding through
some uninitialized flash before hitting the bootloader? Here is a table
that gives the bootloader's start address as a function of the amount of
memory reserved for it:

    reserved size  start address
        512 B         0x3f00
         1 KB         0x3e00
         2 KB         0x3c00
         4 KB         0x3800

Note that the Arduino Uno uses [optiboot][], which fits into the
smallest size that can be allocated to a bootloader (512 bytes).

[icall]: http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf#_OPENTOPIC_TOC_PROCESSING_d94e21480
[optiboot]: https://github.com/Optiboot/optiboot


body:
I'm using [DS18B20][1] sensor with [this library][2], the 750ms delay is causing problem in timer part of my code. the code below is from DallasTemperature.cpp:

    // returns number of milliseconds to wait till conversion is complete (based on IC datasheet)
    int16_t DallasTemperature::millisToWaitForConversion(uint8_t bitResolution) {

     switch (bitResolution) {
     case 9:
      return 94;
     case 10:
      return 188;
     case 11:
      return 375;
     default:
      return 750;
     }

I'm reading the temperature like this:

    #include <OneWire.h>
    #include <DallasTemperature.h>
    #define ONE_WIRE_BUS A0
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);

    void setup() {}

    void loop () {
     float currentTemp = sensors.getTempCByIndex(0);
     sensors.requestTemperatures();
    }

*sensor is not connected in parasite mode, and there is only one sensor.*

How can i change the resolution from 12 to 9 bit?

  [1]: https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf
  [2]: https://github.com/milesburton/Arduino-Temperature-Control-Library

title: How to change the resolution of DS18B20?

Answers: 2

body:
Simple:

    sensors.setResolution(9);

It normally defaults to 9, but then probes the connected device to find the maximum resolution it supports and sets it to that. This would normally be done in `sensors.begin()` which you omitted from your snippet above. If you don't have that it will be on 9 bit anyway, and also the bus probably won't work regardless.

body:
Seems to work better:

    sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);


body:
Arduino: 1.8.9 (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Serial, 115200, 4M (3M SPIFFS)"

```
In file included from C:\Users\Priyaranjan Tiwari\Documents\Arduino\007mcu_php\007mcu_php.ino:3:0:

C:\Users\Priyaranjan Tiwari\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:84:9: error: 'WiFiClient' does not name a type

         WiFiClient & getStream(void)  __attribute__ ((deprecated)) ;

         ^

C:\Users\Priyaranjan Tiwari\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:85:9: error: 'WiFiClient' does not name a type

         WiFiClient * getStreamPtr(void);

         ^

C:\Users\Priyaranjan Tiwari\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:97:9: error: 'WiFiClient' does not name a type

         WiFiClient * _tcp;

         ^

C:\Users\Priyaranjan Tiwari\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.0.0\libraries\ESP8266HTTPClient\src/ESP8266HTTPClient.h:98:9: error: 'WiFiClientSecure' does not name a type

         WiFiClientSecure * _tcps;

         ^

exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
```

title: error compiling for board node MCU 1.0

Answers: 0


body:
I'm trying to use the IR source and detector of the CD Pickup reader/writer (KSS-213C) along with the lens focussing/tracking system. I want to control them using an Arduino MEGA. So since I will be needing one constant source for the diode, I will connect it separately to a source, not to the Arduino. Since this is a sensitive device, I read that you need to have constant current sources and so on. Now, I'm new to designing circuits of my own, I found this picture in an article, but it is for a DVD writer. Could someone tell me if I could use the same circuit with some modifications or should I try something else. Now note that my main output is that of the IR sensor that my Arduino would read. [![enter image description here][1]][1]

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

title: I need help in designing a circuit to connect an Arduino MEGA and a CD-Pickup Reader/Writer

Answers: 0


body:
Peter Scargill [found a way][1] to use DS18B20 temperature sensor without any library and just using OneWire library, and it's amazing how blazing fast it is! *(it's an old article from 2013)*

    #include <OneWire.h>
    int16_t dallas(int x,byte start){
     OneWire ds(x);
     byte i;
     byte data[2];
     int16_t result;
     do{
      ds.reset();
      ds.write(0xCC);
      ds.write(0xBE);
      for (int i = 0; i < 2; i++) data[i] = ds.read();
      result=(data[1]<<8) |data[0];
      result>>=4; if (data[1]&128) result |=61440;
      if (data[0]&8) ++result;
      ds.reset();
      ds.write(0xCC);
      ds.write(0x44, 1);
      if (start) delay(1000);
     } while (start--);
     return result;
    }
    void setup (){
      dallas(A0,1);
    }
    void loop (){
      float currentTemp = dallas(A0,0);
    }

Problem is The accuracy, he converts float to int to get accuracy of 1 degree and it's working just fine.

How can i get accuracy of .5 (or .2?) degree using this semi library?

  [1]: https://www.scargill.net/reading-dallas-ds18b20-chips-quickly/

title: DS18B20 with only OneWire library

Answers: 2

body:
Actually he isn't really converting `float` to `int`. He never uses `float` since he don't need it. The [datasheet][1] of the DS18B20 shows at page 6, how the data is formatted:

[![data structure][2]][2]

1. The 4 highest bits just resemble the sign bit 11.
2. The first digit with full degrees is bit 4. Every bit below that has values below 1°C

So the data bytes `0b1111100001010000` will represent a temperature of -123°C and `0b1111100001011000` -122.5°C.

The author from the link then shifts this data 4 bits to the right, so that all bits representing values under 1 vanish. You can convert the received value per hand to `float` by also using this.

    int16_t whole_degree = (result & 0x07FF) >> 4;
    float temperature = whole_degree + 0.5*((data[0]&0x8)>>3) + 0.25*((data[0]&0x4)>>2) + 0.125*((data[0]&0x2)>>1) + 0.625*(data[0]&0x1);
    if (data[1]&128) temperature*=-1;

As float does not have the same structure, as the data, we need to convert them. So I calculate first the number of whole degrees analog the your code. Then I add this up with the values of the lowest 4 bits. `((data[0]&0x8)>>3)` and it's siblings will be 1, when the corresponding bit is set, and 0, if not.

So you get the full precision of the sensor (12 bits). Please note, that for this to work, you should not configure the sensor to less resolution. In that case you would have to ignore the corresponding lowest bits. But the sensor is in 12 bit mode at power up anyway and your code does not configure it otherwise.

Note: I'm unsure about the line `result |=61440;` in the original code. This sets the 4 highest bits of a 16 bit value to 1. I don't see, why this should be correct here, since a normal 16bit integer does only have 1 sign bit. In my understanding the original code would lead to false readings (way off), when reading temperatures below zero. I instead simply multiplied the resulting temperature with `-1`.

The whole code would look like this (I also added the statement for printing out the pure received data as binary, as I requested it in my comment. These statements are currently commented out):

    #include <OneWire.h>
    float dallas(int x,byte start){
        OneWire ds(x);
        byte i;
        byte data[2];
        int16_t result;
        float temperature;
        do{
            ds.reset();
            ds.write(0xCC);
            ds.write(0xBE);
            for (int i = 0; i < 2; i++) data[i] = ds.read();
            result=(data[1]<<8) |data[0];
            // Here you could print out the received bytes as binary, as requested in my comment:
            // Serial.println(result, BIN);
            int16_t whole_degree = (result & 0x07FF) >> 4; // cut out sign bits and shift
            temperature = whole_degree + 0.5*((data[0]&0x8)>>3) + 0.25*((data[0]&0x4)>>2) + 0.125*((data[0]&0x2)>>1) + 0.625*(data[0]&0x1);
            if (data[1]&128) temperature*=-1;
            ds.reset();
            ds.write(0xCC);
            ds.write(0x44, 1);
            if (start) delay(1000);
        } while (start--);
        return temperature;
    }
    void setup{
      //Adding Serial.begin(9600); for printing the received bytes here
      //Serial.begin(9600);
      dallas(A0,1);
    }
    void loop{
      float currentTemp = dallas(A0,0);
    }

  [1]: https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf
  [2]: https://i.stack.imgur.com/uboxl.png

body:
Why not rewrite the dallas() function so that it returns a float?

    #include <OneWire.h>

    OneWire ds(A0);

    float dallas(OneWire& ds, byte start = false) {
        int16_t temp;
        do {
            ds.reset();
            ds.write(0xCC);
            ds.write(0xBE);
            ds.read_bytes((uint8_t*) &temp, sizeof(temp));
            ds.reset();
            ds.write(0xCC);
            ds.write(0x44, 1);
            if (start) delay(1000);
        } while (start--);
        return (temp * 0.0625);
    }

    void setup {
      dallas(ds, true);
    }

    void loop {
      float currentTemp = dallas(ds);
    }


body:
I am completely new to Arduino, and all sorts of hardware and software. I have a stepper motor, which I want to rotate by a number of rotations when I press a button, and then go backwards by a number of rotations when pressed again. I'm not getting any errors with the code, but it does not seem to do what I want. Before adding the button, the stepper motor worked fine, so I don't think it's malfunctioning. When the button is pressed, the LEDs on the H-bridge flicker, but there's no response at all from the motor. I don't know if it's a problem with the code or the set up.

```C
#include <Stepper.h>
const float STEPS_PER_REVOLUTION = 4096;
const float GEAR_REDUCTION = 4;
const float TOTAL_STEPS = STEPS_PER_REVOLUTION * GEAR_REDUCTION
int StepsRequired = 16384;
int switchPin = 7;
boolean current = LOW;
boolean last = LOW;
boolean isOpen = LOW;
Stepper steppermotor (STEPS_PER_REVOLUTION, 8, 10, 9, 11);

void setup() {
  pinMode(switchPin, INPUT);
}

boolean debounce(boolean inLast) {
  boolean inCurrent = digitalRead(switchPin);
  if(inLast != current) {
    delay(5);
    inCurrent = digitalRead(switchPin);
    }
  return inCurrent;
}

void garageAction(float factor){
  StepsRequired = TOTAL_STEPS*factor;
  steppermotor.setSpeed(1000);
  steppermotor.step(StepsRequired);
  if (isOpen == LOW) {
    delay(3000);
  } else if (isOpen == HIGH) {
    delay(5);
  }
}

void loop() {
  current = debounce(last);

  if (current == HIGH && last == LOW && isOpen == LOW) {
    garageAction(2);
    isOpen = !isOpen;
  }

  if(current == HIGH && last == LOW && isOpen == HIGH) {
    garageAction(-2);
    isOpen = !isOpen;
  }
}
```

I would really appreciate any help with this - as mentioned, I'm completely new to any sort of hardware and software, and I'm also under time pressure to get this done, so I'd really appreciate any help in getting this solved. I could just be missing something really silly, but I'm completely lost.

Thanks in advance

title: Arduino Uno - Stepper motor not working with button

Answers: 0


body:
So i'm doing something wrong but i don't exactly know what and hope somebody can give me a quick pointer:

I declared a starting color for my fastled animation:

    CHSV startcolor(100, 255, 255);

and then a data structure

    typedef struct {

    int currentBrightness = 0;

    int targetBrightness = 0;

    int updown;

    CHSV color = startcolor;

    } blinkblink, *pblinkblink;

So basically my idea is to have every LED be represented with this data structure to control brightness within an anmation. However if i now set

    CRGB leds[NUM_LEDS];

and do something like

    for (int i = 0; i < sizeof(myLeds); i++) {

    leds[i] = myLeds[i].color;

    }

    FastLED.show();

nothing happens. I'm pretty sure, that this is because i'm somehow not understanding the data type thing. What am i doing wrong?

title: Data Structures and Color Data Types in FastLED

Answers: 0


body:
When I put this code only on arduino, sound sensor works:

    int soundSensor=A1;
    int LED=5;

    boolean LEDStatus=false;

    void setup() {

    Serial.begin(9600);

      pinMode(soundSensor,INPUT);
      pinMode(LED,OUTPUT);

    }

    void loop() {

      int SensorData=analogRead(soundSensor);

      if(SensorData>600){

        if(LEDStatus==false){
            LEDStatus=true;
            digitalWrite(LED,HIGH);
        }
        else{
            LEDStatus=false;
            digitalWrite(LED,LOW);
        }

        delay(50);
      }

     }

When I upload same code in big project, even when I upload little part of project on arduino, sound sensor doesnt work.. whats happening?

I checked soundsensor with everything.
I leave whole code till void loop ()  and sound sensor works.
But if I put even delay(1000) in void loop after, sound sensor doesnt work.

Also, if I put every other thing : servo, dht, lighting in code with sound sensor.. with or without delay... sound sensor doesnt work!

Thanks

Whole code:

    #include <Servo.h>
    #include "DHT.h"
    #include <SPI.h>
    #include <MFRC522.h>
    #include <Wire.h>

    #define SERVO_PIN 8
    #define SS_PIN 10
    #define RST_PIN 9
    #define lightingOutput A2
    #define ldrPin A0
    #define PIR 7
    #define ledGrn 6
    #define heatingOutput A3
    #define coolingOutput A4
    #define DHTPIN 2
    #define DHTTYPE DHT11

    MFRC522 mfrc522(SS_PIN, RST_PIN); // Create instance of our reader
    Servo myservo; // Create instance of our motor /// create servo object to control a servo
    DHT dht(DHTPIN, DHTTYPE);     //// Initialize DHT sensor for normal 16mhz Arduino

    int pos;
    int light;
    float h, t;
    int soundSensor=A1;
    int LED=5;
    boolean LEDStatus=false;
    const int buzzer = 4;
    long zadnje_ocitanje=0;

    void setup()
    {

      Serial.begin(9600);
      dht.begin();
      SPI.begin();
      mfrc522.PCD_Init();
      myservo.attach(SERVO_PIN);
      myservo.write(0);

      pinMode(heatingOutput, OUTPUT);
      pinMode(coolingOutput, OUTPUT);
      pinMode(ledGrn, OUTPUT);
      pinMode(soundSensor,INPUT);
      pinMode(LED,OUTPUT);
      pinMode(lightingOutput, OUTPUT);

      zadnje_ocitanje=millis();
    }
    void loop() {

      Serial.println("\nHOME AUTOMATION\n");

      readSOUND();
      readRFID();
      readDHT();
      readLIGHT();

    delay(1000);

    }

    ////////////////////////////////////////////
    void readRFID()

    {
      //Look for new cards
      if ( ! mfrc522.PICC_IsNewCardPresent() ) {
        return;
      }
      if ( ! mfrc522.PICC_ReadCardSerial() ) {
        return;
      }
      // If a card is detected, execute the following:
      Serial.println("Time to open");
      // Print the card's ID
      String content = "";
      byte letter;
      for ( byte i = 0; i < mfrc522.uid.size; i++ ) {
        content.concat(String(mfrc522.uid.uidByte[i], HEX));
        if ( i < mfrc522.uid.size - 1 ) content += "-";
      }
      content.toUpperCase();
      Serial.println();
      Serial.println("UID tag :'" + content + "'");

      if (content == "C0-E5-86-25") {

        Serial.println("Authorized access");
         digitalWrite(ledGrn, HIGH);

        for (pos = 0; pos <= 90; pos += 1) {
          myservo.write(pos);
          delay(25);
        }
        for (pos = 90; pos >= 0; pos -= 1) {
          myservo.write(pos);
          delay(70);
          digitalWrite(ledGrn, LOW);
        }
      }
      else {
        Serial.println("Access Denied");
          tone(buzzer, 1000, 6000);
      }
    }

    //////////////////////////////////////////////////////

    void readDHT()
    {

      h = dht.readHumidity();
      t = dht.readTemperature();
      Serial.print("Humidity: ");
      Serial.print(h);
      Serial.print(" %\t");
      Serial.print("Temperature: ");
      Serial.print(t);
      Serial.print(" *C ");
      Serial.println();

      if (t < 18) //if temperature is less than 18 celcius
      {
        digitalWrite(heatingOutput, HIGH);
        Serial.print("Heating activated\n");
      }
      else
      {
        digitalWrite(heatingOutput, LOW);
      }

      if (t > 22) //if temperature is more than 22 celcius
      {
        digitalWrite(coolingOutput, HIGH);
        Serial.print("Cooling activated\n");
      }
      else
      {
        digitalWrite(coolingOutput, LOW);
      }
    }

    //////////////////////////////////////////////////////

    void readLIGHT()
    {

     int value_pir = digitalRead(PIR);
     light = map(analogRead(ldrPin) , 0 , 1024 , 1 , 100);

      Serial.print("Lighting percentage: ");
      Serial.print(light);
      Serial.print("\nMotion detector: ");
      Serial.print(digitalRead(PIR));

    if ((millis()-zadnje_ocitanje)>6000)
      {

      if ((light < 50) && ( value_pir == HIGH) )
      {
        digitalWrite(lightingOutput, HIGH);
        Serial.println("\nLighting ON");
      }
      else
      {
        digitalWrite(lightingOutput, LOW);
        Serial.println("\nLighting OFF");
      }
        zadnje_ocitanje=millis();
      }
    }

    //////////////////////////////////////////////////////////////

    void readSOUND()
    {
      int SensorData=analogRead(soundSensor);

      if(SensorData>600){

        if(LEDStatus==false){
            LEDStatus=true;
            digitalWrite(LED,HIGH);
        }
        else{
            LEDStatus=false;
            digitalWrite(LED,LOW);
        }

        delay(50);
      }

    }

title: Sound sensor dont work in whole project

Answers: 0


body:
I have a single function for debugging messages, used through all the project. When `KEYDEBUG` is defined as `1` or `0`, the function is enabled or disabled as required.
<!-- language-all: lang-cpp -->

    #define KEYDEBUG 0

    void debugging(int var){
       #if KEYDEBUG
       //Assert
       #endif
    }

When checking the compiler, the variable `var` raises a warning `-Wunused-parameter`.
How should remove this warning just at this part of the project?
Or which other alternative for using debugging code and removing it from memory for production release?

title: Remove Function at Preprocessor Time

Answers: 1

body:
In your case you do not use the entire body, so you can use a macro.

This way the code when KEYDEBUG is 0, will be like the complete function would not exist (except for the void cast, see below).

    #include "assert.h"

    #define KEYDEBUG 0

    #ifndef KEYDEBUG
    #define debugging(x) void(x);
    #endif

    void debugging(int var){
       assert(var);
    }

    void setup() {
      // put your setup code here, to run once:
      debugging(1);
    }

---

The information below is for not using the function parameter, but keep the function (in case you have code in your function that also does something when KEYDEBUG is 0.

**Unused attribute**

The cleanest way I could find is using the unused attribute:

    #if KEYDEBUG
       void debugging(__attribute__((unused)) int var){
          //Assert
    #else
       void debugging(int var){
          //Assert
    #endif
       }

or if you prefer better readability:

    #if KEYDEBUG
       void debugging(__attribute__((unused)) int var){
          //Assert
       }
    #else
       void debugging(int var){
          //Assert
       }
    #endif

**Cast to void**

Less clean but does the job:

    void debugging(int var){
       #if KEYDEBUG
          //Assert
       #else
          (void) var; // prevent unused parameter warning
       #endif
    }

**Macros/Parameter**

It's not easy to remove the variable since it's used in a function and will be called from many places probably. You could maybe you use a macro but that gets messy soon.

This solution works, and afaik the compiler will optimize the code out (if not , it will cost very less anyway).


body:
So I have an Arduino Mega and I'm attempting serial communication with another device, and I ran into this weird issue.

Let's say I use Serial1.write to send out hex A-F. If I read on that same port (Serial1, print out what I read on Serial0), **with NO wires plugged in the serial port**, I get a mirror of what I'm sending out in my read function. I've tested this theory on multiple serial ports, as well as different Megas.

How is this interference happening? Do I have an incorrect understanding of the serial buffers? What can I do to stop it? It's causing interference in communicating with my external device.

Here is a super short program to test this theory.

<!-- language-all: lang-cpp -->

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

    void loop()
    {
      char test[15];
      for (int i = 0; i < 15; i++)
        test[i] = i;

      for (int i = 0; i < 15; i++)
         Serial1.write(test[i]);

      while(Serial1.available() > 0 )
       {
        byte c = Serial1.read();
        Serial.print(' ');
        Serial.print(c, HEX);
      }
    }

**UPDATE:**  I came back the next day with my O-scope and the yellow line is the TX and the blue line is the RX. I was not getting the crosstalk anymore in the Serial port, but on the scope shows the RX line was only being effected about 250mV in perfect unison to the TX. I tried connecting everything back up the same way but I was not able to replicate the issue. Somehow whatever I had going on when I posted this was causing the RX line to be affected great enough for the Mega to pick up on it over serial. For now I'm just blaming it on escaped aliens from Area 51 :)

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

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

title: Arduino Mega reading same information that it's sending out via serial

Answers: 1

body:
I ran a slightly modified version of your test code on a Mega 2560 and got no echo at all;  Unless I totally misunderstood your problem description, there must be something else going on.  Here's the code I ran:
<!-- language-all: lang-cpp -->

    char test[15];

    void setup()
    {
     Serial.begin(9600);
     Serial1.begin(115200);
     for (int i = 0; i < 15; i++)
     {
      //Serial.print(i);
      test[i] = i;
      Serial.print(test[i],HEX);
     }
     Serial.println();

     for (size_t j = 0; j < 15; j++)
     {
      Serial.print("test["); Serial.print(j);
      Serial.print("] = ");Serial.println(test[j],HEX);
     }
    }

    void loop()
    {
     for (int i = 0; i < 15; i++)
     {
      Serial1.write(test[i]);
     }

     Serial.println(Serial1.available());

     while (Serial1.available() > 0)
     {
      byte c = Serial1.read();
      Serial.print(' ');
      Serial.print(c, HEX);
     }
    }

And here's a bit of the output seen on Serial0:

    Opening port
    Port open
    VMDPV_1|1_�Se�
    0123456789ABCDE
    test[0] = 0
    test[1] = 1
    test[2] = 2
    test[3] = 3
    test[4] = 4
    test[5] = 5
    test[6] = 6
    test[7] = 7
    test[8] = 8
    test[9] = 9
    test[10] = A
    test[11] = B
    test[12] = C
    test[13] = D
    test[14] = E
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0
    0

As you can see, the Serial1 read buffer was always empty.

Did I misunderstand something you said?


body:
I am trying to follow [this tutorial][1] but when I get to the step...

"Once the ESP board is in bootload mode, upload the sketch via the IDE"

..I get the following error in Arduino IDE:

    File "[path]/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.5.2/tools/esptool\esptool.py", line 468, in connect
        raise FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error))
    esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header

Any ideas about how to fix this?

  [1]: https://learn.adafruit.com/adafruit-huzzah-esp8266-breakout/using-arduino-ide

title: ESP8266 Huzzah error: "Failed to connect to ESP8266: Timed out waiting for packet header"

Answers: 0


body:
 I am having issues with my PID controller  for a BAR 30 depth sensor. The issue that I have is my ESC have two initial start up { 1500 - 1900} is min - max respectively clockwise and { 1500-1900} is max respectively counter clockwise.
What I want is for me to set a depth and I can submerge to a certain depth and lock in at that certain depth.

    #include <PID_v1.h>
    #include <MS5837.h>
    #include <Wire.h>
    #include <Servo.h>
    MS5837 sensor;
    Servo vertical_thruster1;

    // Variables

    float current_depth ;
    float set_depth = 0.50 ; //  depth u wish to go in meters
    float PID_error = 0;
    float previous_error = 0;
    float elapsedTime,  Time , timePrev;
    double pwmvertical_thruster1 = 1440;

    int s;

    float PID_value = 0;
    float PID_p = 0;
    float PID_d = 0;
    float PID_i = 0;
    //PID constants
    float kp = 100;
    float ki = 0.003;
    float kd = 5.2;

    void setup() {
      Serial.begin(9600);
     vertical_thruster1.attach(4);
       vertical_thruster1.writeMicroseconds(1500);

     Time = millis ();

     ///Bar 30 Configuration

      Serial.println("Starting");
      Wire.begin();
     while (!sensor.init()) {
    Serial.println("Init failed!");
    Serial.println("Are SDA/SCL connected correctly?");
    Serial.println("Blue Robotics Bar30: White=SDA, Green=SCL");
    Serial.println("\n\n\n");
    delay(2000);
      }
      sensor.setModel(MS5837::MS5837_30BA);
      sensor.setFluidDensity(997); // kg/m^3 (freshwater, 1029 for seawater)
    }

    void loop() {

    ///*
    // First read the current value of the depth sensor
    sensor.read();
    current_depth = sensor.depth();

    timePrev = Time;
    Time= millis();
    elapsedTime = ( Time - timePrev) / 1000;

    // calculate the error between the set depth and current depth
     PID_error =  set_depth - current_depth ;

     // Calculate the P Value
     PID_p = kp * PID_error;
       Serial.print("PID_p: ");
        Serial.print(PID_p);
        Serial. println ( "\t\t");
    // Calculate the i value in a range on +-0.3

     if (-0.2 < PID_error < 0.2)
     {
      PID_i = PID_i + (ki * PID_error);
     }
    Serial.print("PID_i: ");
    Serial.print(PID_i);
    Serial. println ( "\t\t");
    // Calculate the d value
     PID_d = kd*((PID_error - previous_error)/elapsedTime);
    Serial.print("PID_d: ");
    Serial.print(PID_d);
    Serial. println ( "\t\t");
    // The total PID value
    PID_value = (PID_p + PID_i + PID_d) ;

    // range for the blue robotics esc

    if ( PID_value < -150)
     {
     PID_value = -150;
      }
      if( PID_value >150)
      {
      PID_value = 150;

      }
      Serial.print("PID_value: ");
      Serial.print(PID_value);
      Serial. println ( "\t\t");
     // calcualte the pwm

     s =  (pwmvertical_thruster1 + PID_value  );
     if(s < 1350)
    {
     s= 1450;

    }
    else if(s> 1650)
    {
      s=1550;

    }
      Serial.print("Depth: ");
      Serial.print(sensor.depth());
      Serial.println(" m");
      Serial.print ( "Speed s  ");
      vertical_thruster1.writeMicroseconds(s);
      Serial.print( s) ;
      Serial. println ( "\t\t");
      previous_error = PID_error;
      //  */
      delay(300);
     }

title: Making a PID Controller for BAR 30 pressure sensor

Answers: 1

body:
A PID controller should be a good match for your application, but it appears that your code doesn't take advantage of the PID_v1 library at all; a PID_v1 object is never declared, and it appears you are attempting to manually compute what the PID library is designed to do for you automatically.

I would recommend you 'start slow and simple' by learning how to use a PID controller in its most basic form.  The PID library has a very basic example, which I have modified slightly to demonstrate how a PID controller works.  I tested this example with a UNO, a potentiometer (variable resistor) and a capacitor. The resistor and capacitor values aren't critical - I used the first things I found in my parts box.  The output on Pin 3 is a PWM pulse train signal, and the resistor/capacitor combination filters this pulse train to a variable level analog signal, which the PID controller sees as the analog 'Input' on A5.

 Once you have this running, you can vary the pot value to see how the PID changes the output value in order to achieve the setpoint value on the input, and you can vary the setpoint and PID parameters to play around with different configurations.  Once you are comfortable with basic PID operation, you should then be able to configure it properly for your application.

Hope this helps,

    #include <PID.h>

     //Define Variables we'll be connecting to
    double Setpoint, Input, Output;

    //Specify the links and initial tuning parameters
    PID myPID(&Input, &Output, &Setpoint, 2, 5, 1, DIRECT);

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

     //initialize the variables we're linked to
     //Input = analogRead(0);
     Input = analogRead(A5);  //I used A5 as A0 was unavailable
     Setpoint = 100;

     //turn the PID on
     myPID.SetMode(AUTOMATIC);
    }

    void loop()
    {
     //Input = analogRead(0);
     Input = analogRead(A5); //I used A5 as A0 was unavailable
     myPID.Compute();
     analogWrite(3, Output);
     Serial.print("Input = "); Serial.print(Input); Serial.print(", Output = "); Serial.println(Output);
     delay(100);

    }

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

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


body:
How should I index HardwareSerial ports into a single array?.

This compiles, but do not work.

    HardwareSerial Serials[]={Serial,Serial1,Serial2,Serial3};

    void setup(){
        for (int i=0;i<=3;i++){
            Serials[i].begin(38400);
            while (!Serials[i]);
        }
    }

    char s;
    void loop(){
        for (int i=0;i<=3;i++){
            if (Serials[i].available()){
                s=Serials[i].read();
                Serials[i].write(s);
            }
        }
    }

title: HardwareSerial Indexing Array

Answers: 1

body:
your code makes copies of Serials into items in the array of HardwareSerials. To use the original Serial objects, store and use pointers.

    HardwareSerial* Serials[]={&Serial,&Serial1,&Serial2,&Serial3};

    void setup(){
        for (int i=0;i<=3;i++){
            Serials[i]->begin(38400);
            while (!*Serials[i]);
        }
    }

    void loop(){
        for (int i=0;i<=3;i++){
            if (Serials[i]->available()){
                char s=Serials[i]->read();
                Serials[i]->write(s);
            }
        }
    }


body:
I send data with Android and read it from the Arduino serial screen. When I use UNO, I can read the data smoothly. When I use MEGA, it uploads the code without error, but does not transfer data on the serial screen. Can you tell me why?

```
#include <SoftwareSerial.h>

SoftwareSerial bluetooth(2,3);    // TX,RX
int bar_analog=0;
int head_analog=0;
int bar_anim=0;
int strip_anim=0;
int motor_speed=1;
int direct=0;
int level=0;
boolean debug = true;

void setup() {
  Serial.begin(9600);
  bluetooth.begin(9600);
  Serial.println("Program is starting...");
  Serial.println("by Berke Ogulcan Parlak");
}

void loop() {
  if (bluetooth.available()) {
    while (bluetooth.available())
    {
      bar_analog = bluetooth.parseInt();
      head_analog = bluetooth.parseInt();
      bar_anim = bluetooth.parseInt();
      strip_anim = bluetooth.parseInt();
      motor_speed = bluetooth.parseInt();
      direct = bluetooth.parseInt();
      level = bluetooth.parseInt();
      if (debug) {
        Serial.print("Bar Brightness: ");
        Serial.println(bar_analog);
        Serial.print("Bar Animation Type: ");
        Serial.println(bar_anim);
        Serial.print("Headlight Brightness: ");
        Serial.println(head_analog);
        Serial.print("Strip Animation Type: ");
        Serial.println(strip_anim);
        Serial.print("Motor Speed Level: ");
        Serial.println(motor_speed);
        Serial.print("Direction: ");
        Serial.println(direct);
        Serial.print("Mast Goes: ");
        Serial.println(level);
        Serial.println("--------------------------------");
      }
      if (bluetooth.read() == '\n') {
        azdırma işlemleri bu satırda yapılacak..

      }
    }
  }

}
```

title: Code that worked in Uno is not working in Mega 2560

Answers: 1

body:
SoftwareSerial relies on the Pin Change interrupt. Not all pins on the Mega have pin change interrupts.

But that is all a moot point really, because when you're using a microcontroller that has lots of *real hardware UARTs* there is no call to be using SoftwareSerial in any case.


body:
------------ *This question has been edited* ------------

*note*: Dac and Adc is12bits

my problem : I use two ESP. Using esp1, I read the Adc amount of the alternating signal (ECG) and send it to esp2 with UDP and I get it. Now, using the same amount of Adc, I would use the MCP4725 to convert the digital value of the Adc to the analog. But I don't know how to do it !

- Do you need sine lookup table like default library example again ??!

- If so, how is it done?!

- I wrote the following code right now, what is your opinion?
Explain to me if my code is in error.

I just want the DAC output, to be the ADC signal input.

*Code*:

    void loop () {

      int noBytes = Udp.parsePacket();
      String received_command = "";

      if ( noBytes ) {
        Udp.read(packetBuffer,noBytes);

        for (int i=1;i<=noBytes;i++)
        {
          received_command += char(packetBuffer[i - 1]);
        }
        int dac_value ;
        dac_value = received_command.toInt();
        Serial.print("dac value: ");Serial.println(dac_value);
        aPin = dac_value ;
        if (!si.i2c_start((I2C_7BITADDR<<1)|I2C_WRITE)) {
          Serial.println("I2C device busy");
          return;
        }

        else{
          Serial.println("i2c is worked");
        }

        for (byte i=1; i<noBytes; i++){
          si.i2c_write(aPin);
          si.i2c_rep_start((I2C_7BITADDR<<1)|I2C_READ);
          si.i2c_stop();
          delay(50);
        }
      }
    }

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

I use `#include <SlowSoftI2CMaster.h>`.

***si*** is: `SlowSoftI2CMaster si = SlowSoftI2CMaster(4, 5, true);`

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

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

title: i2c Connection for MCP4725(Dac) with Esp8266 wemos d1 mini

Answers: 1

body:
Ok, I will explain the basic principles and give some tips. This won't be about your code, since it is neither compilable, nor does it make much of a sense to me.

1. **The I2C Protocol:** An I2C connection always needs 2 lines, SDA (which carries the data) and SCL (where the master outputs the clock signal). The communication always get's started by the master with a START CONDITION. Then it transmits the first byte, which consists of the 7 bits long address of the slave device and one bit, that shows if a read or a write operation will be performed. The slave - if there is any with that address - will then respond with an Acknowledgement. The master will transmit it's data and end the transmission with a STOP CONDITION or start a new transmission with a repeated start condition.

2. **Choose the I2C library:** You are using the [SlowSoftI2CMaster][1] library because it is architecture independent. As you are a beginner, you should use the [SlowSoftWire][2] library, which is a `Wire`-like wrapper library. It gives you the same interface, as the `Wire` library. That is good for beginners, since this hides some of the complexity and most examples and tutorials use the `Wire` library (so you can often copy the code structure). You have to install both libraries (`SlowSoftI2CMaster` and  `SlowSoftWire`) in your libraries folder, but you only need to include the `SlowSoftWire` library. Please look at the examples, that come with that library. I will refer to that library in the following points.

3. **Using the `SlowSoftWire` library:** You can declare and initialize the library as in it's `simpleSlowWire.ino` example. For transmitting a new value to the DAC, you have to first use `beginTransmission()` to configure the library for a master write transaction. Then place the data bytes in the libraries buffer with `write()`. And finally do the transmission with `endTransmission()` (this is the only place during this process, where the real I2C action happens on the bus). When you begin the transmission with `beginTransmission()` you must provide the correct address of the DAC. This is meant without the direction bit. The address of the MCP4725 consists of the device code `1100`, the hardwired address pins A1 and A2, and the variable address pin A0. The hardwired address pins are most likely both zero, unless the manufacturer was ordered to program it otherwise (You can check the address with the scanner example). So, if you wire A0 to ground, the address will be `0b1100000`. If you wire A0 to 3.3V, it will be `0b1100001`. The direction bit will be handled by the library - you don't have to worry about it.

4.**The MCP's data protocol:** You cannot simply send the values from the ADC to the DAC. It except's a special data format, which includes command bits to determine it's mode of operation. I think, I have already described how the data is build up in principle and code pretty well in my answer to [this question][3]. If there is something special, that you don't understand, you can ask a new question and refer to that answer in it. Also I think, you should use the type `unsigned int` for the `dac_value`, since values from an ADC and values for a DAC both are positive only.

Please keep in mind, that building such projects needs some time investment, until you understand, what actually is happening there. If you use any chip, the datasheet of that chip is always a must read. I personally never haven't worked with the MCP4725. I just have read the datasheet. All information is already there.

  [1]: https://github.com/felias-fogg/SlowSoftI2CMaster
  [2]: https://github.com/felias-fogg/SlowSoftWire
  [3]: https://arduino.stackexchange.com/questions/67043/software-i2c-sending-data/67044#67044


body:
**strong text**[![schematic**`strong text`**][1]][1]i have Vector nav100 IMU sensor that sends data serially UART.I want to receive data from it using ATmega32 and then store data in AT24c1024 EEprom using I2C,then using another ATmega32 to read the saved data on AT24c1024 EEprom using I2C to control a servo motor..so,the AT24c1024 EEprom is then shared between the two microcontrollers...i have serached the internet about how to share one  External serial EEprom,i found that......(On way would be for the two  mcrocontrollers to have an output line as an input to the other. A master that is "using" the EEPROM perhaps pulls his output low (or high - your choice) to say "I'm using it at the moment". The other reads his input first before going near the EEPROM if he finds the line active he backs off until it is set inactive by the other master.i tried this solution but i failed...can any one help me on this solution ?
Thanks in advance......
this is my code

    {

        //the first MCU fristly check the pin
        //if high,then write,then set it low to allow read
        //the second MCU fristly check the pin
        //if low ,then write,then set it high to allow write

        //for the MCu that will write
        //first it will check for the pin ,if it is LOW,
        //then it can write data to EEprom
                         DDRA=0x00;//configure portA as input
          if(PINA==0x00)//check for the pin, if LOw,then wirte
        {
         byte_write(data);
         _delay_ms(10);
        //After writing set the pin as high to allow the second MCU to read
         DDRA=0xff;//configure portA as output
         PORTA=0xff;//set the pin as high
         _delay_ms(10);}

        //for the MCu that will read,i set adelay of 10 ms
        // to allow the first MCU to write some data

                             _delay_ms(1000);//delay from the data to be written on the EEprom
                     DDRA=0x00;//configure portA as input
         if(PINA==0x01)//check for the pin, if HIGH,then read
        {
              y=byte_read(data);
             DDRA=0xff;configure portA as output
             PORTA=0x00;//set the pin as high

    }

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

title: about how to share one External serial EEprom using two microcontrollers?

Answers: 1

body:
You didn't show us a complete, minimal, compilable example, so my answer will only cover some important points.

1. Your indention is way off. It is important to use the correct indention, since it help structure your code and will let you quickly see misplaced brackets. The Arduino IDE even has an autoformat function for this.

2. You are configuring and checking always the whole PORT A, but you have only connected one of the pins. When you configure the whole port as input (without pullup), the other pins will be floating. Also, if both devices have the pin on input (no pullup), this pin will also be floating. The check cannot work this way. You should only look at the first bit in the port registers, since that is the pin, that you connected. You can set all other bits to zero when reading, by performing a bitwise AND operation: `if(PINA & (1<<PA0))`. This will execute, when the first bit of PINA is 1. To set a single bit you can use the bitwise OR: `DDRA |= 1<<PA0;` will set the first bit of DDRA. To erase only that bit from the register, you can use `DDRA &= ~(1<<PA0);`. The rest of the port will stay untoched with this.

3. Your current protocol is, that the first MCU will check for LOW, do it' transmission, then drive the pin actively HIGH as a signal for the second MCU to start transmitting. The second MCU will do it's I2C stuff and then drive the pin actively LOW. So now we have an active LOW and active HIGH on the same pin, which in principle is a short. A rather big amount of current will flow from one MCU to the other, most likely destroying at least one of the pins (meaning the output hardware in the MCU, that serves that pin). To avoid this, you can use a principle like that, that the I2C port uses: Open Drain logic. You can start with the first MCU's pin configured as OUTPUT LOW, while the other is INPUT PULLUP. LOW means the first MCU can work. If the first MCU want's the second MCU to do a transmission, it will release the line by setting the PIN to INPUT PULLUP. The second MCU now sees a HIGH level on it's pin and starts it's transmission. When it is finished, it will drive the line actively LOW for a defined duration (enough for the first MCU to react) and then to INPUT PULLUP again. The first MCU will then see a LOW level on it's pin as a signal, that the second MCU is finished. It then itself drives the line actively LOW. Then the play starts again. The important thing is, that a HIGH state is only done by a pullup, not actively driven.

---

That said, I still don't see the necessity to share an external EEPROM for this use case. You are overthinking the problem. You wrote, that you don't want to miss a frame, if the second MCU is still processing the last frame. There are better ways to do that (especially when you consider the limited lifetime of EEPROM).

- You didn't tell us, why you are using 2 MCU's, so maybe your goal can be reached with only 1 MCU, which will eliminate the whole need for transmission.

- You could use another UART interface via `SoftwareSerial` or it's sibling libraries to let the MCU's communicate directly. "Not missing a frame" will still be the case, when you are not disabling interrupts. The library will read the data into a buffer in interrupts, while you are processing the previous frame. Depending on how much data you send, you might want to make the buffer bigger, but that is a simple change in the libraries definitions.

- If you want to use I2C to communicate between both MCU's, you have 2 ways of doing it. You can either go the same way as described above for UART, by just letting it fill a big enough buffer, or you can do this through the bus transmissions. The first MCU would be the master, that tries to send the data to the second MCU (slave), when there is new data available. The slave will receive the data normally. When the frame is finished receiving, the slave can leave the bus, until it is finished processing. So, when the master tries to send more data in this time, the transmission will fail at the start, since no slave with that address is on the bus (the slave MCU left the bus for this period of time). You can check the return value of `Wire.endTransmission()`, which will reflect the corresponding error code. If this error code is returned, the master should wait a bit and try to send this frame again, until it is received successfully. That also means, that the master needs a big enough buffer for storing new data, while waiting for the slave to be ready. Or another way: The master can request 1 byte from the slave, that indicates, if the slave is ready for new data. If not, the master will wait a bit and ask again. If yes, it will transmit the data.

Note: Either way the frequency of data reception and processing must be equal for continuous operation. The whole chain will be as fast as the slowest part. If you receive data faster, than it get's processed, the buffer will fill up fast, until you really have to drop frames. The prinicples above are more about the case, when the processing and receiving may misalign or vary a bit, but at the average staying at the same speed. And for this simple communication buffers, that all communication libraries use, with enough space for maybe 2 to 4 transmissions (depending on the variation) are way enough.