body:
## Problem summary

When I changed the I2C address of a sensor (EZO RTD) to another address (e.g., 50 or 100) from its default address (102), it didn't work on my Atlas Scientific bare-bones WiFi Hydroponics Kit.

## Specific description

I tried to add a temperature sensor (EZO RTD) to an Atlas Scientific bare-bones WiFi Hydroponics Kit that already has a pH Sensor (EZO pH) and a temperature sensor (EZO RTD) on the pH port and Temperature port, respectively. Since a provided setup guide of Atlas Scientific says that each sensor on the kit has to have a different I2C address when multiple sensors are used on it. So I assigned an I2C address "50" to the additional sensor and then added it to the AUX port (and tried the Temperature port as well), but it didn't work at all. Meanwhile, the temperature sensor with the default I2C address 102) works very well on both the Temperature and AUX ports. I guess this might be related to a coding problem. Atlas Scientific's provided code is as follows: THE CODE IS DELETED BY MYSELF

Thanks for reading my problem.

Jayjay

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

I solved this problem based on the answer I voted for.

The code I made is as follows:

```
#include <iot_cmd.h>
#include <ESP8266WiFi.h>                                         //include esp8266 wifi library
#include "ThingSpeak.h"                                          //include thingspeak library
#include <sequencer4.h>                                          //imports a 4 function sequencer
#include <sequencer1.h>                                          //imports a 1 function sequencer
#include <Ezo_i2c_util.h>                                        //brings in common print statements
#include <Ezo_i2c.h> //include the EZO I2C library from https://github.com/Atlas-Scientific/Ezo_I2c_lib
#include <Wire.h>    //include arduinos i2c library

WiFiClient client;                                              //declare that this device connects to a Wi-Fi network,create a connection to a specified internet IP address

//----------------Fill in your Wi-Fi / ThingSpeak Credentials-------
const String ssid = "WIFI NAME";                                 //The name of the Wi-Fi network you are connecting to
const String pass = "WIFI PASSWORD";                             //Your WiFi network password
const long myChannelNumber = ;                            //Your Thingspeak channel number
const char * myWriteAPIKey = "";                 //Your ThingSpeak Write API Key
//------------------------------------------------------------------

Ezo_board PH = Ezo_board(99, "PH");       //create a PH circuit object, who's address is 99 and name is "PH"
Ezo_board EC = Ezo_board(100, "EC");      //create an EC circuit object who's address is 100 and name is "EC"
Ezo_board RTD = Ezo_board(102, "RTD");    //create an RTD circuit object who's address is 102 and name is "RTD"
Ezo_board RTD2 = Ezo_board(50, "RTD2");   //create an RTD circuit object who's address is 50 and name is "RTD2"
Ezo_board PMP = Ezo_board(103, "PMP");    //create an PMP circuit object who's address is 103 and name is "PMP"

Ezo_board device_list[] = {   //an array of boards used for sending commands to all or specific boards
  PH,
  EC,
  RTD,
  RTD2,
  PMP
};

Ezo_board* default_board = &device_list[0]; //used to store the board were talking to

//gets the length of the array automatically so we dont have to change the number every time we add new boards
const uint8_t device_list_len = sizeof(device_list) / sizeof(device_list[0]);

//enable pins for each circuit
const int EN_PH = 14;
const int EN_EC = 12;
const int EN_RTD = 15;
const int EN_AUX = 13;

const unsigned long reading_delay = 1000;                 //how long we wait to receive a response, in milliseconds
const unsigned long thingspeak_delay = 15000;             //how long we wait to send values to thingspeak, in milliseconds

unsigned int poll_delay = 2000 - reading_delay * 2 - 300; //how long to wait between polls after accounting for the times it takes to send readings

//parameters for setting the pump output
#define PUMP_BOARD        PMP       //the pump that will do the output (if theres more than one)
#define PUMP_DOSE         -0.5      //the dose that the pump will dispense in  milliliters
#define EZO_BOARD         EC        //the circuit that will be the target of comparison
#define IS_GREATER_THAN   true      //true means the circuit's reading has to be greater than the comparison value, false mean it has to be less than
#define COMPARISON_VALUE  1000      //the threshold above or below which the pump is activated

float k_val = 0;                                          //holds the k value for determining what to print in the help menu

bool polling  = true;                                     //variable to determine whether or not were polling the circuits
bool send_to_thingspeak = true;                           //variable to determine whether or not were sending data to thingspeak

bool wifi_isconnected(){                            //function to check if wifi is connected
  return (WiFi.status() == WL_CONNECTED);
}

void reconnect_wifi(){                                    //function to reconnect wifi if its not connected
  if(!wifi_isconnected()){
    WiFi.begin(ssid, pass);
    Serial.println("connecting to wifi");
  }
}

void thingspeak_send(){
  if (send_to_thingspeak == true) {                                                    //if we're datalogging
    if(wifi_isconnected()){
      int return_code = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
      if (return_code == 200) {                                                          //code for successful transmission
          Serial.println("sent to thingspeak");
      }else{
        Serial.println("couldnt send to thingspeak");
      }
    }
  }
}

void step1();      //forward declarations of functions to use them in the sequencer before defining them
void step2();
void step3();
void step4();
Sequencer4 Seq(&step1, reading_delay,   //calls the steps in sequence with time in between them
               &step2, 300,
               &step3, reading_delay,
               &step4, poll_delay);

Sequencer1 Wifi_Seq(&reconnect_wifi, 10000);  //calls the wifi reconnect function every 10 seconds

Sequencer1 Thingspeak_seq(&thingspeak_send, thingspeak_delay); //sends data to thingspeak with the time determined by thingspeak delay

void setup() {

  pinMode(EN_PH, OUTPUT);                                                         //set enable pins as outputs
  pinMode(EN_EC, OUTPUT);
  pinMode(EN_RTD, OUTPUT);
  pinMode(EN_AUX, OUTPUT);
  digitalWrite(EN_PH, LOW);                                                       //set enable pins to enable the circuits
  digitalWrite(EN_EC, LOW);
  digitalWrite(EN_RTD, HIGH);
  digitalWrite(EN_AUX, LOW);

  Wire.begin();                           //start the I2C
  Serial.begin(9600);                     //start the serial communication to the computer

  WiFi.mode(WIFI_STA);                    //set ESP8266 mode as a station to be connected to wifi network
  ThingSpeak.begin(client);               //enable ThingSpeak connection
  Wifi_Seq.reset();                       //initialize the sequencers
  Seq.reset();
  Thingspeak_seq.reset();
}

void loop() {
 String cmd;                            //variable to hold commands we send to the kit

  Wifi_Seq.run();                        //run the sequncer to do the polling

  if (receive_command(cmd)) {            //if we sent the kit a command it gets put into the cmd variable
    polling = false;                     //we stop polling
    send_to_thingspeak = false;          //and sending data to thingspeak
    if(!process_coms(cmd)){              //then we evaluate the cmd for kit specific commands
      process_command(cmd, device_list, device_list_len, default_board);    //then if its not kit specific, pass the cmd to the IOT command processing function
    }
  }

  if (polling == true) {                 //if polling is turned on, run the sequencer
    Seq.run();
    Thingspeak_seq.run();
  }
}

//function that controls the pumps activation and output
void pump_function(Ezo_board &pump, Ezo_board &sensor, float value, float dose, bool greater_than){
 if (sensor.get_error() == Ezo_board::SUCCESS) {                    //make sure we have a valid reading before we make any decisions
    bool comparison = false;                                        //variable for holding the reuslt of the comparison
    if(greater_than){                                               //we do different comparisons depending on what the user wants
      comparison = (sensor.get_last_received_reading() >= value);   //compare the reading of the circuit to the comparison value to determine whether we actiavte the pump
    }else{
      comparison = (sensor.get_last_received_reading() <= value);
    }
    if (comparison) {                                               //if the result of the comparison means we should activate the pump
      pump.send_cmd_with_num("d,", dose);                           //dispense the dose
      delay(100);                                                   //wait a few milliseconds before getting pump results
      Serial.print(pump.get_name());                                //get pump data to tell the user if the command was received successfully
      Serial.print(" ");
      char response[20];
      if(pump.receive_cmd(response, 20) == Ezo_board::SUCCESS){
        Serial.print("pump dispensed ");
      }else{
        Serial.print("pump error ");
      }
      Serial.println(response);
    }else {
      pump.send_cmd("x");                                          //if we're not supposed to dispense, stop the pump
    }
  }
}

void step1() {
  //send a read command. we use this command instead of RTD.send_cmd("R");
  //to let the library know to parse the reading
  RTD.send_read_cmd();
  RTD2.send_read_cmd();
}

void step2() {
  receive_and_print_reading(RTD);             //get the reading from the RTD circuit
    if ((RTD.get_error() == Ezo_board::SUCCESS) && (RTD.get_last_received_reading() > -1000.0)) { //if the temperature reading has been received and it is valid
    PH.send_cmd_with_num("T,", RTD.get_last_received_reading());
    EC.send_cmd_with_num("T,", RTD.get_last_received_reading());
    ThingSpeak.setField(2, String(RTD.get_last_received_reading(), 2));                 //assign temperature readings to the third column of thingspeak channel
  } else {                                                                                //if the temperature reading is invalid
    PH.send_cmd_with_num("T,", 25.0);
    EC.send_cmd_with_num("T,", 25.0);                                                          //send default temp = 25 deg C to EC sensor
    ThingSpeak.setField(2, String(25.0, 2));                 //assign temperature readings to the third column of thingspeak channel
  }

  Serial.print(" ");
  receive_and_print_reading(RTD2);
  if ((RTD2.get_error() == Ezo_board::SUCCESS) && (RTD2.get_last_received_reading() > -1000.0)) { //if the temperature reading has been received and it is valid
    PH.send_cmd_with_num("T,", RTD2.get_last_received_reading());
    EC.send_cmd_with_num("T,", RTD2.get_last_received_reading());
    ThingSpeak.setField(3, String(RTD2.get_last_received_reading(), 2));                 //assign temperature readings to the third column of thingspeak channel
  } else {                                                                                //if the temperature reading is invalid
    PH.send_cmd_with_num("T,", 25.0);
    EC.send_cmd_with_num("T,", 25.0);                                                          //send default temp = 25 deg C to EC sensor
    ThingSpeak.setField(3, String(25.0, 2));                 //assign temperature readings to the third column of thingspeak channel
  }

}

void step3() {
  //send a read command. we use this command instead of PH.send_cmd("R");
  //to let the library know to parse the reading
  PH.send_read_cmd();
  EC.send_read_cmd();
}

void step4() {
  receive_and_print_reading(PH);             //get the reading from the PH circuit
  if (PH.get_error() == Ezo_board::SUCCESS) {                                          //if the PH reading was successful (back in step 1)
     ThingSpeak.setField(1, String(PH.get_last_received_reading(), 2));                 //assign PH readings to the first column of thingspeak channel
  }
  Serial.print("  ");
  receive_and_print_reading(EC);             //get the reading from the EC circuit
  if (EC.get_error() == Ezo_board::SUCCESS) {                                          //if the EC reading was successful (back in step 1)
     ThingSpeak.setField(2, String(EC.get_last_received_reading(), 0));                 //assign EC readings to the second column of thingspeak channel
  }

  Serial.println();
  pump_function(PUMP_BOARD, EZO_BOARD, COMPARISON_VALUE, PUMP_DOSE, IS_GREATER_THAN);
}

void start_datalogging() {
  polling = true;                                                 //set poll to true to start the polling loop
  send_to_thingspeak = true;
  Thingspeak_seq.reset();
}

bool process_coms(const String &string_buffer) {      //function to process commands that manipulate global variables and are specifc to certain kits
  if (string_buffer == "HELP") {
    print_help();
    return true;
  }
  else if (string_buffer.startsWith("DATALOG")) {
     start_datalogging();
    return true;
  }
  else if (string_buffer.startsWith("POLL")) {
    polling = true;
    Seq.reset();

    int16_t index = string_buffer.indexOf(',');                    //check if were passing a polling delay parameter
    if (index != -1) {                                              //if there is a polling delay
      float new_delay = string_buffer.substring(index + 1).toFloat(); //turn it into a float

      float mintime = reading_delay*2 + 300;
      if (new_delay >= (mintime/1000.0)) {                                       //make sure its greater than our minimum time
        Seq.set_step4_time((new_delay * 1000.0) - mintime);          //convert to milliseconds and remove the reading delay from our wait
      } else {
        Serial.println("delay too short");                          //print an error if the polling time isnt valid
      }
    }
    return true;
  }
  return false;                         //return false if the command is not in the list, so we can scan the other list or pass it to the circuit
}

void get_ec_k_value(){                                    //function to query the value of the ec circuit
  char rx_buf[10];                                        //buffer to hold the string we receive from the circuit
  EC.send_cmd("k,?");                                     //query the k value
  delay(300);
  if(EC.receive_cmd(rx_buf, 10) == Ezo_board::SUCCESS){   //if the reading is successful
    k_val = String(rx_buf).substring(3).toFloat();        //parse the reading into a float
  }
}

void print_help() {
  get_ec_k_value();
  Serial.println(F("Atlas Scientific I2C hydroponics kit                                       "));
  Serial.println(F("Commands:                                                                  "));
  Serial.println(F("datalog      Takes readings of all sensors every 15 sec send to thingspeak "));
  Serial.println(F("             Entering any commands stops datalog mode.                     "));
  Serial.println(F("poll         Takes readings continuously of all sensors                    "));
  Serial.println(F("                                                                           "));
  Serial.println(F("ph:cal,mid,7     calibrate to pH 7                                         "));
  Serial.println(F("ph:cal,low,4     calibrate to pH 4                                         "));
  Serial.println(F("ph:cal,high,10   calibrate to pH 10                                        "));
  Serial.println(F("ph:cal,clear     clear calibration                                         "));
  Serial.println(F("                                                                           "));
  Serial.println(F("ec:cal,dry           calibrate a dry EC probe                              "));
  Serial.println(F("ec:k,[n]             used to switch K values, standard probes values are 0.1, 1, and 10 "));
  Serial.println(F("ec:cal,clear         clear calibration                                     "));

  if(k_val > 9){
     Serial.println(F("For K10 probes, these are the recommended calibration values:            "));
     Serial.println(F("  ec:cal,low,12880     calibrate EC probe to 12,880us                    "));
     Serial.println(F("  ec:cal,high,150000   calibrate EC probe to 150,000us                   "));
  }
  else if(k_val > .9){
     Serial.println(F("For K1 probes, these are the recommended calibration values:             "));
     Serial.println(F("  ec:cal,low,12880     calibrate EC probe to 12,880us                    "));
     Serial.println(F("  ec:cal,high,80000    calibrate EC probe to 80,000us                    "));
  }
  else if(k_val > .09){
     Serial.println(F("For K0.1 probes, these are the recommended calibration values:           "));
     Serial.println(F("  ec:cal,low,84        calibrate EC probe to 84us                        "));
     Serial.println(F("  ec:cal,high,1413     calibrate EC probe to 1413us                      "));
  }

  Serial.println(F("                                                                           "));
  Serial.println(F("rtd:cal,t            calibrate the temp probe to any temp value            "));
  Serial.println(F("                     t= the temperature you have chosen                    "));
  Serial.println(F("rtd:cal,clear        clear calibration                                     "));
 }
```

title: How can I add an additional temperature sensor (EZO RTD of Atlas Scientific) to an Atlas Scientific bare-bones wifi pool kit?

Answers: 1

body:
Did you update the code above to add your new sensor?

A quick look at Atlas' site and their Github page didn't find an obvious instruction to do what you're try to do, so that's the first thing I'd try if you haven't already. Below the Thinkspeak Credentials section, add your new device to the I2C devices definitions, then add its name to the array of available devices. I called the new temp sensor RTD2 in my example below, but you could probably call it something more descriptive of its function or placement. It looks like there is a name string in each definition that (I'm guessing) will be displayed in Thingspeak's data, and would be a good place to put a short description.

```c++
        Ezo_board PH = Ezo_board(99, "PH");       //create a PH circuit object, who's address is 99 and name is "PH"
        Ezo_board EC = Ezo_board(100, "EC");      //create an EC circuit object who's address is 100 and name is "EC"
        Ezo_board RTD = Ezo_board(102, "RTD");    //create an RTD circuit object who's address is 102 and name is "RTD";
        Ezo_board RTD2 = Ezo_board(50, "RTD2");   //create an RTD circuit object who's address is 50 and name is "RTD2"
        Ezo_board PMP = Ezo_board(103, "PMP");    //create an PMP circuit object who's address is 103 and name is "PMP"

        Ezo_board device_list[] = {   //an array of boards used for sending commands to all or specific boards
          PH,
          EC,
          RTD,
          RTD2,
          PMP
        };
```

Update:

On review, it looks like you'll need to define an Arduino pin to enable the new device (in the `//enable pins for each circuit` section) and enable it at the head of `setup()` where the the other devices' pins are set to OUTPUT mode, and set this pin HIGH (guessing that your new RTD will be identical to your current one):

```c++
//enable pins for each circuit
const int EN_PH = 14;
const int EN_EC = 12;
const int EN_RTD = 15;
const int EN_RTD2 =    <some available pin# here> ;
const int EN_AUX = 13;
```

And in setup():

```c++

 pinMode(EN_RTD2, OUTPUT);

  ...

 digitalWrite(EN_RTD2, HIGH);
```

Update 2:

I think what we did above will get your new sensor data logged to Thingspeak, since I see a message referring to a "datalog mode" in `print_help()`. If you're expecting the control process to act your new sensor data in some way, you'll need to understand what it does now and what you want it to do differently based on the newly available data. But I would still take getting the system to just log the new data as your first step.


body:
I am writing my own assert() macro on Arduino as shown below.
When I run it **from the main() it always works correctly** (prints the message and gets into an infinite loop), however when I call it within a class function it gets stuck without printing anything. Why is that?

assert.cpp/.h
```
#ifndef _ASSERT_H_
#define _ASSERT_H_

void assertion_failure(const char* expr, const char* file, int linenum);

#define assert(expr) \
    if (expr) ; \
    else assertion_failure(#expr, __FILE__, __LINE__)

#endif /* _ASSERT_H_ */
```
```
#include "assert.h"
#include "Arduino.h"

void assertion_failure(const char* expr, const char* file, int linenum)
{
    Serial.print("Assertion failed in '");
    Serial.print(file);
    Serial.print("' on line ");
    Serial.print(linenum);
    Serial.print(": ");
    Serial.println(expr);
    Serial.flush();

    while (1);
}
```

And the context in which the assert gets stuck below (it works well when I call it in main() however):
```
int ADS1256::assert_debug()
{
    uint8_t id = read_register(STATUS) >> 4;
    assert(false);    // Gets stuck here without printing anything to screen
    return id;
}
```

---

EDIT:
looks like it has something to do with build configuration. I am using PlatformIO build system.
It does not work when I use this file structure:
```
├── include
│   └── assert.h
├── lib
│   ├── ADS1256
│      ├── ads1256.cpp
│      ├── ads1256.h
│      └── ads1256_regmap.h
├── src
    ├── assert.cpp
    └── main.cpp
```

However, if I move assert.cpp/.h into a dedicated directory within lib/ it works fine. What is the reason behind this?
How can I investigate why this happened?

It works with this layout (again, using PlatformIO default build configuration):
```
├── include
├── lib
│   ├── ADS1256/
│   ├── Assert/
│       ├── assert.cpp
│       └── assert.h
├── src
    └── main.cpp
```

title: Custom assert() implementation: not printing the error message

Answers: 1

body:
As per comment on question, this is not as finished as I'd like, but it's a start.

I deeply suspect what you're running into is a conflict between the name of your header and the standard `assert.h` header.  You're using the same header name and same macro names as is used in the standard c header, that is part of both c++ and "Arduino.".  The standard `assert()` with the way things are normally set up on the AVR Arduino core does basically just go into a tight loop and do nothing.

I would consider naming your macro something other than `assert` and naming your header something other than `assert.h`.  If you want to get into the precise details why, we need to see things like your include path order, and the include directives themselves.  Even then, the advice would be about the same.

Diagnostics
-----------

#### `--save-temps`

In platform.io you should be able to add `--save-temps` to the `avr-gcc` command-line to get it to produce (or keep) the output of the preprocessing stage.  GCC annotates these showing where each section of the entire output came from, so you can see which headers each `#include` directive actually included and in what order all of this happened.

#### NDEBUG

Something else you can try, as a diagnostic measure, is to define `NDEBUG` in your project settings. This is usually defined by IDEs for "release mode".  It basically makes `assert()` into a NOP, which in turn means that it will not do the usual avr-libc thing of locking up.  If you're seeing the avr-libc assert being expanded instead of your own, then the behaviour will change to just not locking up, but also not doing what your own `assert` would do.

AVR-based Arduino `assert()` support
------------------------------

avr-libc's `assert()` tries to print its assertion message on stderr, which is not configured on AVR based Arduinos to do anything.  So the outward behaviour is that it locks up.  However, you can complete [avr-libc's implementation][1] of stderr in terms of the Arduino's `Serial.write` function, in which case the normal avr-libc `assert` will work just fine.  Here's [one example][2] of completing avr-libc's stdio printing in terms of `Serial`.

`__FILE__` Caveat and SRAM
------------------------

Something you should be aware of in using `__FILE__`, and therefore `assert` (whether it be avr-libc's or yours) is that `__FILE__` expands to a string literal which is the full path of the source filename, which can be quite long.  On the UNO (you have tagged) these go into SRAM.  So if you use `assert` in a couple different files, you can very quickly eat up the available SRAM on the AVR.

For this reason, in my own little assert-type macros, I've taken to not reporting the file but instead a custom tag, which is often just a single letter or number.  Besides, often my asserts are blinking the `__LINE__` number on an LED, where `__FILE__` is impractical in my typical use case anyway.

  [1]: https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html
  [2]: https://github.com/maniacbug/RF24/blob/master/examples/pingpair/printf.h


body:
An Arduino Nano is set up to perform A/D conversions and send results out over `Serial`. Currently the code structure is like

    loop() {
      delayUntilNextTargetTime();
      measure();
      sendMeasurementsToSerial();
    }

Though I make already sure that `delayUntilNextTargetTime` does not blindly `delay(MILLIS)` but rather subtracts the computation time from the time to sleep to prevent drift, I would rather get the timing from the host computer.

The idea is that the host computer sends a command string over the serial when it wants data, so the loop could look like

    loop() {
      if (!Serial.available()) return;
      measure();
      sendMeasurementsToSerial();
    }

Now I wonder if there is a way to do this without idle polling, something along the lines of

    loop() {
      if(Serial.available()) {
        measure();
        sendMeasurementsToSerial();
      }
      sleepUntilSerialPotentiallyHasData();
    }

I read that saving power is hard and likely not worth the effort, in particular when having a USB power supply. It is pure curiosity to see

 - what it takes to bring the system into, say, IDLE mode, possibly stopping the timers too, because they are not used (I guess)
 - and what it takes to get out of IDLE mode correctly again such that A/D conversion in `measure()` works without flaws.

title: Run computation only on request over serial

Answers: 1

body:
On a Nano you can `#include <avr/sleep.h>`, then simply call
`sleep_mode()` from `loop()`. This will put the device to sleep, by
default in IDLE mode, until the next interrupt fires. The Nano will wake
up at least once every 1,024 µs, to service the timer interrupt
that is used to implement the Arduino timing function(`millis()`,
`delay()`, etc.). Most of the time this `loop()` will do nothing more
than testing `Serial.available()`, so the MCU will be awake only for a
couple of microseconds every 1,024 µs, which is not much.

If you disable the timer interrupt, all the timing functions will be
off, but the MCU will still be waken by the serial port interrupt as
soon as data is available.


body:
I followed this [tutorial][1] a couple of times and when I clicked on bootloader I get this error:
```
avrdude: Device signature = 0x000000
```

To see the configuration file click [here][2].

 1. Why do I get this error (Arduino can't communicate with chip, problem with software)?
 2. How can I fix it?
 3. Is something in the tutorial incorrect?

>Keep in mind I use an `Arduino Uno Rev. 3` and `ATmega328P`

  [1]: https://www.electronicshub.org/burn-bootloader-on-atmega328/
  [2]: https://drive.google.com/open?id=1AZmnBH_1yHPGG1DSEl8AVRWUc3kWIbN4

title: What does avrdude: Device signature = 0x000000 mean? Faulty wiring? Software issue? Incorrect tutorial?

Answers: 4

body:
There is one part of the tutorial that is incorrect - or rather *missing*.

When you open the serial port the Arduino resets. That includes when the serial port is opened by `avrdude`.

You need to prevent that from happening, so that the ArduinoISP sketch receives the serial data, not the Arduino's bootloader.

There's a number of ways of doing that:

* Add a 10uF or greater capacitor between RESET and GND on the Arduino
* Add a small (say 100R) resistor between RESET and 5V on the Arduino
* Cut the RESET-EN trace on the underside of the Arduino

Of those my preferred method is the first: add a 10uF or greater capacitor between RESET and GND on the Arduino.

----

**Update:**

Now that you have provided photographs of your actual setup I can see that the ground wire between your Arduino and the breadboard is actually plugged into the VIN pin of the Arduino, not GND.

body:
Unfortunately the three prominent threads on the Arduino forum on this topic are closed, so their good but incomplete information is baked in time:

 - [Invalid device signature error](https://forum.arduino.cc/t/invalid-device-signature-error/962328/2)
   - Which references: [Did I get these ArduinoISP instructions right?](https://forum.arduino.cc/t/did-i-get-these-arduinoisp-instructions-right/308935)
 - [Invalid Device signature = 0x000000](https://forum.arduino.cc/t/invalid-device-signature-0x000000/922497)
 - [no clock on Atmega328p-AU](https://forum.arduino.cc/t/no-clock-on-atmega328p-au/225563/4)

So let me add a bit more useful information in the hope it permeates.

> Device signature = 0x000000

Means the MCU **did not respond with a signature**. There is a very thin chance that's because it reported all zeros when asked for a signature, but a much higher chance that **it did not respond at all**. Correct signature bytes are found [here](https://onlinedocs.microchip.com/pr/GUID-CBDC1838-0100-4F26-A45A-134958193C3B-en-US-4/index.html) (eg. ATmega328P = 0x1E950F) and crucially, all Atmel microcontrollers have one.

Further, the error:

> avrdude: Device signature = 0x000000
>
> avrdude: Yikes! Invalid device signature.

will occur if you're using ArduinoISP to flash a target Arduino and the **target is not physically connected**. So it really is an "all bets are off" message that doesn't pinpoint any particular cause. To troubleshoot, checking wiring if a good first step.

Do not, on the other hand, concern yourself with the external clock signal. In contrast to some guides, the ATmega328P at least comes factory configured to use an internal RC oscillator, so even a correctly connected crystal or resonator on the `XTAL` pins will not show any activity until the first successful flash.

body:
One of the reason for getting weird device signature like 0x000000/0x0000ff/0xff0000
is not having the crystal clock right.

When I tried uploading the sketch I was getting this different device signatures. I had no idea it could be clock setting because we don't generally get this option to set the clock on regular Arduino boards upload options.

I was using this Atmega328PU clone Chinese board and wasn't able to upload a sketch.
Than I tried uploading the sketch using miniCore board (where by default it was External 16MHz Clock selected). Same signature issues still.

For some reason I tried uploading with 8MHz Clock and this time the device signature was right

i.e. `device signature = 0x1e950f (probably m328p)`

and was able to successfully upload the sketch.

I highly recommend trying this.

body:
Can confirm previous answer about changing SPI clock.
I edited ArduinoISP.ino example and changed `#define SPI_CLOCK (1000000 / 6)` to `#define SPI_CLOCK (128000/6)` and after that I successfully burned bootloader to my UNO


body:
I have had to use Timer0 with phase correct PWM and a prescaler of 1. This results in a 32khz PWM frequency and obviously impacts millis, delay and micros. (Timer1 and Timer 2 are also in use so changing to those is not an option)

millis() is trivial to work around - multiply by 32 as the TOV0 interrupt handler is called 32 times more frequently (subject to overflow of course)

micros() is somewhat trickier - as normally it is the Timer0 overflow count (as used in millis() though shifted in this case) plus the current value of TCNT0. That works great when TCNT0 is increasing only and resetting to 0 after MAX - but in phase correct PWM it could be going upwards or downwards.

I think what I need to do is find the direction the Timer is currently using - but pouring over the datasheet for the ATmega328P I can't seem to find a way to do so...

Is there a way of reading this, eg from a register I can interrogate for it?

Alternatively can anyone else think of a way to get microsecond (or close - 10 microsecond would be good enough) resolution when all timers are in phase correct mode?

I'm considering a fall-back of reading TCNT0 twice and deriving it from that - with a prescaler of 1I am assuming it is not possible to read it twice faster than it could change - however I'd prefer a neater solution if there is one.

title: How can I read the Timer direction in phase correct PWM?

Answers: 1

body:
I decided to go with the inspect method and modified wiring.c accordingly - may not fit everyone's use case but solves mine (along with a couple of tweaks changing the #define's to volatile variables and adding a setter for them.

micros updated to:

    unsigned long micros() {
      unsigned long m;
      uint8_t oldSREG = SREG, t1, t2;

      cli();
      m = timer0_overflow_count;
    #if defined(TCNT0)
      t1 = TCNT0;
      t2 = TCNT0;
    #elif defined(TCNT0L)
      t1 = TCNT0L;
      t2 = TCNT0L;
    #else
      #error TIMER 0 not defined
    #endif

    #ifdef TIFR0
      if ((TIFR0 & _BV(TOV0)) && (t1 == timer0_phase_correct ? 0 : 255))
        m++;
    #else
      if ((TIFR & _BV(TOV0)) && (t1 == timer0_phase_correct ? 0 : 255))
        m++;
    #endif

      SREG = oldSREG;

      if (timer0_phase_correct && t1 > t2){
        t2 = 510 - t2;
      }

      return (m * us_per_timer0_overflow) + (clockCyclesToMicroseconds(timer0_prescale * t2));
    }


body:
I have an Arduino MKR Zero with an UDA1334 I2S module, alongside 2 Speakers and I am trying to play Stereo sound. So far everything seems to work well, connections are also properly done, and i can play wav files. But i also want to be able to play sound either on the right channel only or sometimes only on the left channel. I tried to use audacity to make sounds only on the right channel for example, but when i play the .wav file, i still get the sound on both speakers. How can i fix this please? Is there any syntax to play sound only on the right channel? Thank you.

PS. TestR.wav is a only on the right channel.

```C
#include <SD.h>
#include <ArduinoSound.h>

const char filename[] = "testR.wav";
SDWaveFile waveFile;

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

   Serial.print("Initializing SD card...");
   if (!SD.begin(28)) {
    Serial.println("SD card initialization failed!");
    return;
  }
  Serial.println("SD card is valid.");
  waveFile = SDWaveFile(filename);   // create a SDWaveFile
//  Serial.println(typeof(waveFile));
 if (!waveFile) {
    Serial.println("wave file is invalid!");
    while (1); // do nothing
  }

// print out some info. about the wave file

Serial.print("Bits per sample = ");
Serial.println(waveFile.bitsPerSample());
long channels = waveFile.channels();
Serial.print("Channels = ");
Serial.println(channels);
long sampleRate = waveFile.sampleRate();
Serial.print("Sample rate = ");
Serial.print(sampleRate);
Serial.println(" Hz");
long duration = waveFile.duration();
Serial.print("Duration = ");
Serial.print(duration);
Serial.println(" seconds");

AudioOutI2S.volume(100);

 if (!AudioOutI2S.canPlay(waveFile)) {
    Serial.println("unable to play wave file using I2S!");
    while (1); // do nothing
  }
 Serial.println("starting playback");
  AudioOutI2S.play(waveFile);
}

void loop() {
  if (!AudioOutI2S.isPlaying()) {
    Serial.println("playback stopped");
    while (1);
  }
}
```

title: Playing stereo sound using AudioOutI2S and Splitting channels correctly

Answers: 0


body:
Hi I'm pretty new to cpp.
Could someone review my code and explain any pitfalls or problems?
Below is the code and an example to read from a flow meter with a hall sensor.
Thanks in advance.
Greg

```c++
    /** example
    #include "flow.h"
    Flow f(3);
    Flow f2(4);
    volatile unsigned int counter;
    void flow_counter() // ISR
    {
          // Increment the pulse counter
          counter ++;
    }

    void setup()
    {
      f.start(); //using default ISR
      f2.assign_isr(&flow_counter);
      f2.assign_counter(&counter);
      f2.start();
    }

    void loop()
    {
     Serial.printf("flow rate on 3 = %f \n",f.rate());
     Serial.printf("flow total = %dml %f%% of 500ml \n",f.total_ml(),f.percent(500));
     Serial.printf("flow rate on 4 = %f \n",f2.rate());
     delay(1000);
    }

    */

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

    volatile unsigned int flowPulseCounter;
    void flowCounter() // ISR
    {
          // Increment the pulse counter
          flowPulseCounter ++;
    }

    class Flow{
      public:
        Flow(uint8_t pin)
        {
          if(flowPin==254)
           flowPin = pin;
        }

        void assign_isr ( void (*isr)()){ this->flowISR = isr; };
        void assign_counter (volatile unsigned int * counter ){ this->counter = counter; };
        void assign_pin(uint8_t pin){ flowPin = pin; };

        void  set_calibration_factor( float factor ) { this->calibrationFactor = factor; };
        float get_calibration_factor( ) { return this->calibrationFactor; };

        uint8_t retrieve_pin(){ return flowPin; };

        void start()
        {
          detachInterrupt(digitalPinToInterrupt(this->flowPin));
          *this->counter = 0; // counter is a pointer so * assigns the value at that address to 0
          this->flowRate = 0;
          this->flowMillilitres = 0;
          this->flowMilliseconds = millis();
          pinMode(this->flowPin, INPUT_PULLUP);
          this->running = true;
          attachInterrupt(digitalPinToInterrupt(this->flowPin), this->flowISR, FALLING);
        }

        void calculate()
        {
          if(this->running)
          {
            this->flowRate = ((1000.0 / (millis() - this->flowMilliseconds)) * ( *this->counter )) / this->calibrationFactor;
            this->flowMilliseconds = millis();
            // convert to millilitres.
            this->flowMillilitres = (this->flowRate / 60) * 1000;
            // Add the millilitres to the cumulative total
            this->totalMillilitres += this->flowMillilitres;
          }
        }

        void stop()
        {
          detachInterrupt(digitalPinToInterrupt(flowPin));
          this->calculate();
          this->running = false;
          pinMode(this->flowPin, INPUT_PULLUP);
        }

        bool is_max( uint32_t millilitres )
        {
          this->calculate();
          return (this->totalMillilitres >= millilitres) ? true : false;
        }

        float percent( uint32_t millilitres )
        {
          this->calculate();
          return (float)((double) this->totalMillilitres / (double) millilitres)  * 100.0;
        }

        float rate ()
        {
          this->calculate();
          return this->flowRate;
        }

        uint32_t total_ml()
        {
          this->calculate();
          return this->totalMillilitres;
        }

      private:
        uint8_t flowPin=0;
        uint32_t flowMilliseconds = 0;
        float flowRate=0;
        uint32_t flowMillilitres = 0;
        uint32_t totalMillilitres = 0;
        float calibrationFactor = 4.5;
        bool running = false;
        void (*flowISR)() = &flowCounter;
        volatile unsigned int * counter = &flowPulseCounter;
    };

```

title: Is there anything wrong with this code

Answers: 4

body:
It's hard to answer without any description of the actual problem.

On the top of my head, with that much code i'd consider starting off by creating a separate class declaration, and write your member definitions outside. It will make the code way more manageable, and easier to troubleshoot.

https://www.learncpp.com/cpp-tutorial/class-code-and-header-files/

Also, you have several include statements in at least two different places. They usually go first in a file, along with include guards. If your code consists of separate files, please make that clear to readers.

body:
The only problem I can see is in your use of the `counter` variable. This is a volatile variable that is incremented in an interrupt routine and read from the main loop context.  The variable is "non atomic" in that it is made up of a number of smaller bytes (at least on 8 bit Arduinos it is) which means it takes multiple sequential instructions to read it from memory.

At any point during that sequence the interrupt could trigger and modify the value, corrupting your data.

You should always use a *critical section* around any accesses to variables that are modified inside interrupt routines, such as:

```c++
noInterrupts(); // Disable interrupts
uint32_t currentCount = this->counter; // Grab the current count
interrupts(); // Re-enable interrupts

// Do things with currentCount instead of this->counter
```

body:
Here are some random comments from looking at the code.

First issue, which is more about the example than the library itself:
there is no `Serial.printf()` in the standard Arduino cores. Yes, it is
provided by some alternate cores, and it is a shame it is not available
in the Arduino ones, but that's how it is.

In the constructor, there is `if(flowPin==254)`. Why this condition?
`flowPin` is initialized to zero, so it would seem the condition should
always be false.

As a matter of style, you can remove all the `this->` from the methods.
It is implicit anyway.

For the sake of naming consistency, I would rename `retrieve_pin()` as
`get_pin()`, and all the `assign_*()` method as `set_*()`.

It is not useful to `detachInterrupt()` right before
`attachInterrupt()`, as the latter implies the former.

In `calculate()`, avoid calling `millis()` twice. You have no guarantee
that both calls will return the same value and, if they do not, the
timing calculations will be off. Also, this function will fail badly
(division by zero) if called twice within the same millisecond.

It makes no sense to convert a flow rate to milliliters. Do you mean
milliliters per minute? Per second? In any case, you here converting a
rate to another unit, but it is still a flow rate.

The computation of `totalMillilitres` is wrong: it is incremented by a
flow rate. It should instead be incremented by a product rate × time. Or
better yet: compute it from the pulse count, without going through the
rate. Otherwise you are computing a numerical derivative (to get the
rate) only to integrate it later (to get a total volume). This extra
computations serve no purpose other than accumulating rounding errors.

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

**Edit**: Thinking further about this program, I found a few more things
that I think could be improved. A couple of minor points an one not so
minor.

One of the minor points is that `begin()` would be a better name for
`start()`, for consistency with most other Arduino libraries.

Another one is that there are a couple of methods that have no business
being in the class: `is_max()` and `percent()`. They are trivial
calculations that are in no way related to handling a flow meter. As a
user of the library, I would rather write

```c++
if (flow.total_ml() >= threshold_volume) ...
```

than

```c++
if (flow.is_max(threshold_volume)) ...
```

as the former is way clearer and easy to understand.

The more serious point is about the handling of multiple flow meters.
The first one is completely handled by the library, which is nice.
However, for the second one, the user has to provide the lowest level
bricks. The user of a library should not have to handle himself such
low-level details. Thus, I think both the counter variable and the ISR
function should be handled by the library, as members of the `Flow`
class.

I am aware this creates some difficulties. In order to be attached to an
interrupt, the ISR should be a static method of the class. In order for
this method to access the counter, that counter should be a static
member. In order for each flow meter to have its own counter, we must
have a separate class for each one.

I found a solution that I think is elegant enough: have `Flow` be a
_class template_, parametrized by the pin number. This creates a
separate class for each flow meter. In order to avoid code duplication,
these classes could be almost empty shells that delegate as much as
possible to a handler which is a common, regular class.

Here is what that “handler” class could look like. It has everything
but the ISR:

```c++
class FlowMeterHandler {
    // Everything here is private, only accessible to the Flow class.
    template<uint8_t pin> friend class Flow;
private:
    void begin(uint8_t pin, void (*isr)()) {
        attachInterrupt(digitalPinToInterrupt(pin), isr, FALLING);
    }
    float flow_rate() {
        uint32_t now = millis();
        if (now - last_millis >= 10) {
            uint32_t this_count;
            noInterrupts();
            this_count = count;
            interrupts();
            last_flow = calibration * (this_count - last_count)
                                    / (now - last_millis);
            last_millis = now;
            last_count = this_count;
        }
        return last_flow;
    }
    // + other methods...
    volatile uint32_t count = 0;
    uint32_t last_count = 0;
    uint32_t last_millis = 0;
    float last_flow = 0;
    float calibration = 1e3 / 4.5;
};
```

I've written the methods inline, but you could also put the
implementations in a separate .cpp file.

And here is the template class. Save for the ISR, it forwards everything
to the handler.

```c++
template<uint8_t pin> class Flow {
public:
    static void begin() { handler.begin(pin, isr); }
    static float flow_rate() { return handler.flow_rate(); }
    // other methods also forwarded to the handler...
private:
    static FlowMeterHandler handler;
    static void isr() { handler.count++; };
};

template<uint8_t pin> FlowMeterHandler Flow<pin>::handler;
```

Note that the class has no instance data: everything in it is `static`.

Here is how this would be used:

```c++
Flow<3> f1;
Flow<4> f2;

void setup()
{
    f1.begin();
    f2.begin();
}

void loop()
{
    Serial.print(F("flow rate on 3 = "));
    Serial.println(f1.flow_rate());
    Serial.print(F("flow rate on 4 = "));
    Serial.println(f2.flow_rate());
    delay(1000);
}
```

body:
Ok so if anyone is interested here is what I ended up with

```c++
/*
  this is yet to be varified but comes from the following links
  *
  https://www.bc-robotics.com/tutorials/using-a-flow-sensor-with-arduino/

  "These are not able to monitor a flow of less than 1 liter per minute or in excess of 30 liters per minute.
  The sensor is rated to a Maximum of 2.0MPa (290 PSI) "
  and
  every rotation means 2.25mL of fluid has passed the sensor

  another is

  https://diyhacking.com/projects/FlowMeterDIY.ino
  "// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
   // litre/minute of flow.
  "

  then finally

  https://arduino.stackexchange.com/questions/84578/is-there-anything-wrong-with-this-code

  I make no personal claim to any of this code. It is simply my version of Edgar's version.
  Thanks Edgar
  *
  *
  *
  * I have used start and stop as they signify the start and stop of the process
  * the class begins when it starts and has no end the isr stays linked to the class for the duration
  * and start simply attaches the interrupt to the isr
  * stop simply calculates the total volume and detaches the interrupt.
  *
  * as flow rate related to time
  * just set your own start time
  * read the total_ml
  * then after your own predefined time
  * read the total_ml again
  * and work out the flow rate from that.
  */

class FlowMeterHandler {
  // Everything here is private, only accessible to the Flow class.
  template<uint8_t pin> friend class Flow;
private:

  void start(uint8_t pin, void (*isr)())
  {
    noInterrupts();
    count = 0;
    interrupts();
    attachInterrupt(digitalPinToInterrupt(pin), isr, FALLING);
  }

  void stop(uint8_t pin)
  {
    detachInterrupt(digitalPinToInterrupt(pin));
  }

  unsigned int count_is()
  {
    unsigned int this_count;
    noInterrupts();
    this_count = count;
    interrupts();
    return this_count;
  }

  volatile unsigned int count = 0;
  unsigned int ul_per_tick = 2250;

};

template<uint8_t pin> class Flow {
public:
    static void start() { handler.start(pin, isr); }
    static void stop() { handler.stop(pin); }
    static unsigned int total_ul() { return handler.count_is() * handler.ul_per_tick; }
    static unsigned int total_ml() { return ( handler.count_is() * handler.ul_per_tick ) / 1000 ; }
    static void set_ul_per_rotation( unsigned int ul) { handler.ul_per_tick = ul; }
private:
    static FlowMeterHandler handler;
    static void isr() { handler.count++; };
};

template<uint8_t pin> FlowMeterHandler Flow<pin>::handler;

```

the example ino looks like this
```c++
#include "flow.h"
Flow<3> f1;
Flow<4> f2;

void setup()
{
    f1.start();
    f2.start();
}

void loop()
{
    Serial.print(F("So far volume on 3 = "));
    Serial.println(f1.total_ml());
    Serial.print(F("and the volume on 4 = "));
    Serial.println(f2.total_ml());
    delay(1000);
}
```

Compiles cleanly on all my boards.
Runs ???
Any other suggestions will be gratefully received.

Thanks.
Greg


body:
I'm using a 74HC595N shift register to light up 8 LEDs but for some reason they won't turn on even though current is flowing through all of them. I provided an image of my circuit below, there is a test LED for checking current flow:

[![This is my circuit][1]][1]

I am using a 9A103G resistor network to connect all the LEDs to a common ground. I have tried this with 8 individual 330 ohm resistors in the past but the result is the same, and every time the problem was with the ground wire, current is not flowing through it even though all the resistors I've used showed that current was flowing through them (see below):

[![Current going through resistor network][2]][2]

The following image shows the same test LED not lighting up when connected to the common ground pin of the resistor network:

[![No current going through ground wire][3]][3]

  [1]: https://i.stack.imgur.com/lHNmZ.jpg
  [2]: https://i.stack.imgur.com/h1Zg2.jpg
  [3]: https://i.stack.imgur.com/WfdOw.jpg

I could use some help fixing this issue because it is preventing me from using shift registers for future projects (this only happens when I use shift registers) - I would like to know what is causing this problem so I can avoid it later on. Thanks in advance!

title: LEDs not lighting up even though current is flowing through them, problem with ground?

Answers: 1

body:
(Just to illustrate what Majenko is saying.)

This is the inside of a breadboard:

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

All your connections are on one side of that; you've tied everything to a single point.

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


body:
A friend and I have been working on an Arduino Sketch that does a request to a local API, parses that data and prints it out on an LCD Display.

When we upload the sketch to the Arduino it does exaclty what it should and shows the following on the LCD Display:
[![LCD with Data][1]][1]

But when we disconnect the Arduino from the PC and reconnect it to the PC (or to any other power source), the following shows up on the LCD:
[![enter image description here][2]][2]

It seems as if the Arduino simply does not restart the Sketch and stays idle, while giving the LCD a weird output. When we open the Serial Monitor, in the Arduino IDE, the Arduino reboots and the correct information shows up again. Pressing the reset button on the Arduino itself did not work and seems to do nothing.

When trying other examples (e.g. Blink) it does restart on reconnecting to the PC, so it seems that the problem lies with our code.

Here is our full code:
```lang-cpp
#include <SPI.h>
#include <WiFiNINA.h>
#include <ArduinoJson.h> // Library to deserialize JSON
#include <Wire.h> // Library for I2C communication
#include <LiquidCrystal_I2C.h> // Library for LCD

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);

char ssid[] = "WifiSSID";
char pass[] = "WifiPassword";
bool reading = false;

int refreshRate = 5000;

int status = WL_IDLE_STATUS;
IPAddress server(192,168,1,201);

WiFiClient client;

char json[512];
StaticJsonDocument<512> doc;

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

  memset(json, 0, sizeof json);

  lcd.init();
  lcd.backlight();

  lcd.setCursor(4, 1);
  lcd.print("CONNECTING..");
  status = WiFi.begin(ssid, pass);

  if (status != WL_CONNECTED) {
    while(status != WL_CONNECTED) {
      Serial.println("Retrying connection in two seconds...");
      delay(2000);
      status = WiFi.begin(ssid, pass);
    }
  }
  else {
    lcd.setCursor(0, 1);
    lcd.print("                    ");

    Serial.println("Connected to wifi");
    Serial.println("\nStarting connection...");
    sendRequest();
  }
}

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    if (c == '[') {
      reading = true;
      memset(json, 0, sizeof json);
    } else if (c == ']') {
      reading = false;
      printJson();
    } else if (reading) {
      int len = strlen(json);
      json[len] = c;
      json[len+1] = '\0';
    }
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    client.stop();
    delay(refreshRate);
    sendRequest();
  }
}

void sendRequest() {
  if (client.connect(server, 80)) {
      Serial.println("Connected to server. Requesting data...");
      client.println("GET /api/v1/smartmeter?json=object&limit=1&round=on HTTP/1.0");
      client.println();
    }
}

void printJson() {
  DeserializationError error = deserializeJson(doc, json);

  if (error) {
    Serial.print(F("deserializeJson() failed: "));
    Serial.println(error.f_str());
    return;
  }

  int energy = doc["CONSUMPTION_W"];
  float gas = doc["CONSUMPTION_GAS_M3"];
  Serial.println(json);
  Serial.println(energy);
  Serial.println(gas);

  lcd.setCursor(0, 0);
  lcd.print("CONSUMPTION ENERGY:");
  lcd.setCursor(0, 1);
  lcd.print(energy);
  lcd.setCursor(8, 1);
  lcd.print("WATT");

  lcd.setCursor(0, 2);
  lcd.print("CONSUMPTION GAS:");
  lcd.setCursor(0, 3);
  lcd.print(gas);
  lcd.setCursor(8, 3);
  lcd.print("M3");
}
```

Would any of you maybe know why the Arduino refuses to restart on reconnecting to the PC or a power source, and how to fix it?

Thanks in advance!

  [1]: https://i.stack.imgur.com/W7mCM.jpg
  [2]: https://i.stack.imgur.com/CLqsB.jpg

title: Arduino with LCD Display does not reset/restart/start on connection to power

Answers: 1

body:
You've tagged the question with both `nano` and `arduino-nano-33-iot`, but I'm guessing between the two you're using the latter, because on Arduinos with native USB (not a plain Arduino Nano) `while (!Serial) continue;` [waits][1] for a serial connection, e.g. Serial Monitor, to be connected.

This doesn't happen when you're on a power supply, or just connecting it to a machine without opening the port.

If you want blink an led inside this loop to see that it is in fact stuck there.

  [1]: https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial/


body:
I'm trying to use an Arduino Due to interface with an ADIS16364 IMU from Analog Devices ([product info here][1]) via SPI.

There are two modes for retrieving the measurements from this particular IMU (six 16 bit values, 3 acc, 3 gyros):

1. The first mode is, if I'm not wrong, the standard one with SPI, in which each successive transfer command retrieves the last data requested and indicates which one should be retrieved next.

2. The second possibility is a so called "burst mode". For this one you have to request the 0x3E00 register. After that, the IMU will burst out the six measurements (plus a few other bits of information like temperature and supply voltage). From the specs sheet:

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

The problem is, I can not manage to make the Arduino read the data using this burst mode. This is the code I'm using to test the communication:

    #include <SPI.h>
    #define SerialBT Serial2

    short supply, xgyro, ygyro, zgyro, xacc, yacc, zacc, xtemp, ytemp, ztemp, aux;
    volatile byte fDataIMUtoRead = 0;
    int pauseBetweenTransfers;

    void setup() {

      SerialBT.begin(230400);

      pinMode(52, OUTPUT);

      // Configure SPI
      SPI.begin(52);
      SPI.setClockDivider(52, 200); // 84e6/200 = 420kHz
      SPI.setDataMode(52, SPI_MODE3);
      SPI.setBitOrder(52, MSBFIRST);

      // Set sample rate
      float Fs = 1; // Target sampling frequency [Hz]
      float tb = 0.61035 * (Fs >= 12.7009) + 18.921 * (Fs < 12.7009);
      unsigned long tbsel = 0 * (Fs >= 12.7009) + 1 * (Fs < 12.7009);
      unsigned long Ns = (uint16_t) round((1000.0 - tb * Fs) / (tb * Fs));
      float Feff = 1000 / (tb * (Ns + 1));
      SerialBT.print("Selected freq: ");
      SerialBT.println(Feff, DEC);

      digitalWrite(52, LOW);  // Doesn't seem to be necessary
      SPI.transfer16(52, (0L << 15) | (0x36L << 8));                       delayMicroseconds(100);
      SPI.transfer16(52, (1L << 15) | (0x36L << 8) | (tbsel << 7) | Ns );  delayMicroseconds(100);
      SPI.transfer16(52, (0L << 15) | (0x36L << 8));                       delayMicroseconds(100);
      zgyro = SPI.transfer16(52, 0x00);
      digitalWrite(52, HIGH);

      SerialBT.print("SMPL_PRD = ");
      SerialBT.println(zgyro, HEX);

      attachInterrupt(3, availableIMUData, RISING);
    }

    void loop() {

    if (fDataIMUtoRead) {

    SerialBT.print("Loop... ");

    // Read values (standard mode)
    pauseBetweenTransfers = 100;
    digitalWrite(52, LOW); // Doesn't seem to be necessary

            SPI.transfer16(52, 0x0400, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
    xgyro  = SPI.transfer16(52, 0x0600, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
    ygyro  = SPI.transfer16(52, 0x0800, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
    zgyro  = SPI.transfer16(52, 0x0A00, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
    xacc   = SPI.transfer16(52, 0x0C00, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
    yacc   = SPI.transfer16(52, 0x0E00, SPI_CONTINUE); delayMicroseconds(pauseBetweenTransfers);
    zacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);

    digitalWrite(SS, HIGH);

    /*
    // Read values (burst mode)
    pauseBetweenTransfers = 5;
    digitalWrite(52, LOW);    // Doesn't seem to be necessary

             SPI.transfer16(52, 0x3E00);    delayMicroseconds(pauseBetweenTransfers);  // Request data burst
    supply = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
    xgyro  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
    ygyro  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
    zgyro  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
    xacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
    yacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
    zacc   = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
    xtemp  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
    ytemp  = SPI.transfer16(52, 0x0000, SPI_CONTINUE);  delayMicroseconds(pauseBetweenTransfers);
    ztemp  = SPI.transfer16(52, 0x0000);

    digitalWrite(52, HIGH);
    */

    SerialBT.println(zgyro, DEC); // Print the reading

    fDataIMUtoRead = 0; // Reser the "there is new data"-flag

    }
  }

void availableIMUData() {
  fDataIMUtoRead = 1; // Set the "there is new data"-flag
}

The standard way to communicate seems to work without any problem, provided that I set the right delays after each transfer16 command. But I'm not able to make the Arduino read the data in burst mode (commented in the code above).

So does anybody have any ideas on how to make the Arduino retrieve the readings in this burst mode? I understand this is a tricky unless you have (had) access to the same hardware, but any suggestion will be welcome.

Thanks a lot.

  [1]: https://www.analog.com/en/products/adis16364.html#product-documentation
  [2]: https://i.stack.imgur.com/v5CBQ.png
  [3]: https://i.stack.imgur.com/Fluov.png

title: SPI synchronization with Arduino DUE and ADIS16364 IMU

Answers: 1

body:
First of all, this may not related to your question, but you are using old SPI methods `setClockDivider()`, `setDataMode()`, and `setBitOrder()` that has been deprecated since 2014. It is recommend to use use transactional SPI APIs which I have some explanation [here](https://arduino.stackexchange.com/a/79760/40646).

>Why I actually need those delays?

If you read page 6 of [ADIS16364 datasheet](https://www.analog.com/media/en/technical-documentation/data-sheets/ADIS16364.pdf), there is a tSTALL time between each data transmission that could be as long as 75uS (when operating on Low Power mode), this value can be much lower if you operate on Normal or Bust mode.

> why this combination of delays with the 200 clock divider?

The clock divide set the clock used for the SPI SCLK rate, for Due a clock divide of 200 means 84,000,000 / 200 = 420,000Hz, Why this rate? again, you have to look into datasheet, on page 6 table 2, max fsck is 2MHz for Normal mode, and 1MHz for Bust mode, and only 300kHz at Low Power mode.

>Shouldn't this be done automatically by the SPI library?

This is a wrong perception, SPI library do nothing than handling the communication. All the timing requirements are component/chip specific, and therefore if you want to communicate with the chip at SPI communication level, you will have to deal with all the timing requirements yourself. Most of the people in the Arduino community get used of using some pre-written library which was written by someone who care to read the datasheet and provide high level abstract API so that users don't need to deal with all the timing.

>Any ideas on how to make the Arduino retrieve the readings in this burst mode?

**Update**

<s>As suggested by the datasheet, "To start a burst read sequence, **set DIN = 0x3E00**", what this means is that you need to **WRITE** into the register 0x3E00 first to setup the burst mode. Fig 11. of the datasheet indicate that a WRITE operation would have a set most significant bit to 1, so you will need to send `0x3E00 | 0x8000` or `0xAE00` for writing into register `0x3E00`. What you did is basically reading form `0x3E00`, not writing into `0x3E00`.</s>

**I re-read the datasheet and you are right, it should be okay to just send out `0x3E00`. I never use an Arduino Due before, but I realised that the SPI.transfer16() might send out the `0x00` first instead of `0x3E`. I modified the code to send out two bytes `0x3E` and `0x00` separately using `SPI.transfer()`**

I don't have the IMU, but I think the follow code should works for bust mode:

```
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE3));    //initialises SPI clock speed, mode and bit order
digitalWrite(SS, LOW);              // adjust this as per your chip select pin
SPI.transfer(0x3E);
SPI.transfer(0x00);
delayMicroseconds(1);               //bust mode only 1uS required as per datasheet
xgyro_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
ygyro_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
zgyro_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
xaccl_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
yaccl_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
zaccl_out = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
data16    = SPI.transfer16(0x0000);
delayMicroseconds(1);
digitalWrite(SS, HIGH);   // deselect slave
SPI.endTransaction();


body:
How could I estimate the max number of switches that I could connect to an Arduino Uno?

I am questioning if Arduino has enough power to simultaneously operate an X number of switches with no issues.

I am using an external power adapter of 12 volt/2 amps (barrel).

Here is the hardware: https://m.hellasdigital.gr/el/products/tank-pool-water-level-liquid-sensor-float-switch

title: Water level switches / reed switches and Arduino Uno

Answers: 1

body:
thank you a lot about your input it was very useful.
My source of issues was a faulty sensor. After I changed it things are smooth now.
I separated the power cables from the signal as well that is super important.

Thank you a lot about the valuable input!


body:
I've been searching for how to connect a SIM7100A module to an Arduino (Uno or Mega), but I haven't been able to find any posts anywhere, nor videos nor any kind of documentation that shows how to do it. Does anyone here know how to connect it so I can send simple AT commands to the module from the Arduino? (I just want to make GET requests and get GPS coordinates)
[![enter image description here][1]][1]

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

  [1]: https://i.stack.imgur.com/PMmMW.jpg
  [2]: https://i.stack.imgur.com/AP9sx.jpg

title: How to connect SIM7100A to Arduino?

Answers: 1

body:
Got it to work, in part thanks to the documentation that @Juraj posted.
My pinout is the following, in case anyone needs it:

SIM7100A -> Arduino Mega

SUPPLY -> 5V (the SIM7100A's SUPPLY pin powers the actual board, it's different from the VDD pin which is only for the Serial communication)

GND (both lower & upper) -> GND

VDD -> 3.3V

TXD -> RXD2

RXD -> voltage divider (5V to 3.3V) -> TXD2

Once the module is powered (the PWR LED is on), you gotta press the module's reset button for about 3 seconds and then wait for the NET and STA LEDs to turn on, then you can start sending AT commands to it.

I don't know if this will be the case for everyone, but for me, the serial communication through the SIM's USB debug port is with 9600 bauds, but the communication through the TXD and RXD pins is with 115200 bauds.


body:
I have one Arduino Uno which was **working fine** by below circuit([link][1]):
[![enter image description here][2]][2]

But when I have connected the new bought the **LM35 Ic** by the below connection:

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

The Arduino UNO don't **be recognized** by the my Ubuntu OS as you can see below:

[![enter image description here][4]][4]

And by **removing the LM35 connections**, the Arduino don't be recognized again. I have damaged **two Arduino Uno board** by **this mistake** and ...

So I don't know why this happened and for repairing the damaged circuits I hope find out **which part of the Arduino circuit** are probably damaged?

Thanks.

  [1]: https://github.com/Startup-Data/UN-Hakim-PCR/edit/main/Arduino/Temperature
  [2]: https://i.stack.imgur.com/zmYIz.jpg
  [3]: https://i.stack.imgur.com/C6FTQ.jpg
  [4]: https://i.stack.imgur.com/grgqd.png

title: About Corrupted LM35 IC and Arduino port problem

Answers: 0


body:
I've tried this code below but it doesn't stop it just rapidly switch direction that it looks like it's trembling I think because it always reads the void startF/R thats why it's trembling .

I need help on how to completely stop the stepper if it reads both sensor LOW

    if (sensLval== LOW || sensRval == LOW){
         steppStop();
    }

this is my void loop code below

        void startF()
      {
        motor1.step(10, FORWARD,SINGLE);

      }

        void startR()
      {
        motor1.step(10, BACKWARD,SINGLE);

      }

        void steppStop(){
      motor1.step(0, BACKWARD, SINGLE);

     motor1.step(0, FORWARD, SINGLE);
    }

        void loop() {
      sensRval=digitalRead(sensR);

    sensLval=digitalRead(sensL);

      if (sensLval == LOW)

    {
        startF();
      }

    if (sensLval== LOW && sensRval == LOW)

    {
         steppStop();
      }

      if (sensRval == LOW)

    {
        startR();
      }

    }

title: how do i make stepper stop if both sensors are LOW ? im using a adafruit l293d motor shield

Answers: 1

body:
Isolate your conditions.

You currently check for:

* *Both* sensors LOW at the same time **and**
* *Either* sensor LOW on its own

If *both* are low—don't check for *either* being LOW (which triggers `startX`.)

```cpp
if (sensLval == LOW && sensRval == LOW) {
    steppStop();
} else if (sensLval == LOW) {
    startF();
} else if (sensRval == LOW) {
    startR();
}
```

There may be other considerations as well, but this is enough to get past that issue.

---

Unrelated, but consistent indentation goes a long way towards code readability and helping others be able to reason about code in general. When posting code it's a good idea to format your code as code, [described here](https://arduino.stackexchange.com/editing-help) and when you are editing the question.


body:
I'm trying to make a simple GET request to a server (which has a static IP but does not have a name). I'm using [EtherCard][1] library and a cheap [ENC28J60 Ethernet Module][2]. The basic configurations are OK (I can get DHCP assignment and DNS lookup), but when I try to make a simple GET request with the `browseUrl` method, nothing happens. I've tried to call the page from the browser and everything works fine, so it's not a server issue. The code is the following:

    #include <EtherCard.h>

    // ethernet interface mac address, must be unique on the LAN
    byte mymac[] = { 0x54, 0x55, 0x58, 0x10, 0x00, 0x24 };

    const char website[] PROGMEM = "http://10.10.10.10"; // my server
    const char dnsLook[] PROGMEM = "google.com";

    byte Ethernet::buffer[700];
    uint32_t timer;
    Stash stash;

    // called when the client request is complete
    static void requestCallback (byte status, word off, word len) {
      Serial.print(">>>");
      Serial.print(status);
      Serial.print("-");
      Serial.print(status);
      Serial.print("-");
      Serial.print(status);
      Serial.println("<<<");
    }

    void setup () {

      Serial.begin(9600);
      delay (10000);
      int res = ether.begin(sizeof Ethernet::buffer, mymac, 8);

      if (res == 0)
        Serial.println( "Cannot access ethernet interface");

      const static uint8_t ip[] = {192,168,1,117};
      const static uint8_t gw[] = {192,168,1,1};
      const static uint8_t dns[] = {8,8,8,8};

      if (!ether.staticSetup(ip, gw, dns))
      {
          Serial.println("Cannot set static parameters");
      }

      // manually set netmask
      ether.netmask[0] = 255;
      ether.netmask[1] = 255;
      ether.netmask[2] = 255;
      ether.netmask[3] = 0;

      // dns lookup
      if (!ether.dnsLookup(dnsLook))
        Serial.println("DNS failed");
    }

    void loop () {
      ether.packetLoop(ether.packetReceive());
      if (millis() > timer) {
        timer = millis() + 10000;
        ether.browseUrl(PSTR("/page.php?"), "var=value", website, requestCallback);
      }
    }

  [1]: https://github.com/njh/ethercard
  [2]: https://www.amazon.it/Hiletgo-ENC28J60-Ethernet-modulo-Arduino-STM32/dp/B00WX1NRO0/

title: Simple GET request is failing silently

Answers: 1

body:
I made it by using `EthernetENC` library, as suggested by @Juraj.
To install the library, simply use the library manager and search for EthernetENC.
For those in need, below is a working code

    #include <SPI.h>
    #include <EthernetENC.h>

    byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };  // ethernet module MAC address
    IPAddress server(10,10,10,10);                        // server IP address, without DNS
    //char server[] = "www.site.com";                     // if your server has a DNS name, use this variable for connection

    // static configuration variables
    IPAddress staticIp(192, 168, 1, 217);
    IPAddress staticDnsServer(8, 8, 8, 8);

    EthernetClient client;                                // ethernet client object

    void setup() {
      // configure CS pin
      Ethernet.init(8);

      // begin serial connection
      Serial.begin(9600);

      // wait some seconds to let the module start
      delay(5000);

      // initialize ethernet module with static configuration
      Ethernet.begin(mac, staticIp, staticDnsServer);

      // wait to let the module properly initialize
      delay(1000);

      // connection to the server
      Serial.print("Connecting to: ");
      Serial.print(server);
      Serial.println("...");

      // notify successful connection
      if (client.connect(server, 80)) {

        Serial.print("Connected to ");
        Serial.println(client.remoteIP());

        // simple GET request
        client.println("GET /page.php?var=test HTTP/1.1");
        client.println("Host: 10.10.10.10");
        client.println("User-Agent: Arduino/1.0");
        client.println("Connection: close");
        client.println();

      } else {
        // connection failed notifiation
        Serial.println("Connection failed");
      }
    }

    void loop() {

      // if I got a response from the server, read and print to serial
      int len = client.available();
      if (len > 0) {
        byte buffer[80];
        if (len > 80) len = 80;
        client.read(buffer, len);
        Serial.write(buffer, len);
      }

      // disconnection
      if (!client.connected()) {

        Serial.println();
        Serial.println("Disconnected");
        client.stop();

        // stop execution
        while (true) {
          delay(1);
        }
      }
    }

at [this link][1], you can see how to properly connect this module to Arduino UNO.

  [1]: https://create.arduino.cc/projecthub/Sourcery/how-to-connect-the-enc28j60-to-an-arduino-efd0dd


body:
I built a custom board that uses a STM32F411CEU6. My problem is that tried to upload a simple blink sketch (I'm using Arduino IDE with STM32 libraries) and I get the error:

    ST-LINK SN  : 57FF72067166535645342467
    ST-LINK FW  : V2J37S7
    Board       : --
    Voltage     : 3.23V
    SWD freq    : 4000 KHz
    Connect mode: Under Reset

    Reset mode  : Hardware reset
    Device ID   : 0x431
    Revision ID : Rev A

    Device name : STM32F411xC/E
    Flash size  : 512 KBytes (default)
    Device type : MCU
    Device CPU  : Cortex-M4

    Memory Programming ...
    Opening and parsing file: Blink.ino.bin
      File          : Blink.ino.bin
      Size          : 11256 Bytes
      Address       : 0x08000000

    Erasing memory corresponding to segment 0:
    Erasing internal memory sector 0
    Error: failed to erase memory

    Error: failed to erase memory

    RUNNING Program ...
      Address:      : 0x8000000
    Warning: The core is locked up
    Start operation achieved successfully
    the selected serial port Start operation achieved successfully
     does not exist or your board is not connected

I'm using an ST-LINK V2 USB pen that works fine. I have a Black Pill with the same STM32 to use as a control and everything works ok.

Also, when I try to check the custom board with STM32CudeProgrammer, I get the error:

      22:16:27 :   Size          : 1024 Bytes
      22:16:27 :   Address       : 0x8000000
      22:16:27 : Read progress:
      22:16:27 : Error: Data read failed

  [1]: https://www.amazon.de/gp/product/B07YX83NSL/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1

title: STM32f4 Warning: The core is locked up

Answers: 1

body:
The solution:

 1. Open STM32CubeProgramer and click connect
 2. Click Option Bytes (OB) located in the left bar
 3. Select Read Out Protection and choose AA option
 4. Then select PCROP and uncheck the box
 5. Click apply


body:
I'm using two Arduino Megas in a project to read data from a bunch of analog sensors and then output PWMs on digital pins according to their value. These analog signals are also being plotted on a dash app.

I'm using pyfirmata, and the program runs perfectly with either one of the two boards connected. However, when I connect both boards, The second board (second in terms of its `pyfirmata.util.Iterator` object being instantiated second), will always report `nonetype` objects when calling `board2_some_analog_pin.read()`

I found essentially the exact same problem [here](https://stackoverflow.com/questions/65824060/problems-with-reading-analog-values-with-pyfirmata-on-two-arduino-megas)

**Putting the iterators on separate processes fixed the nonetype issue** for me too. However I want to know why this would fix things, because I want to be confident there isn't a threading-based solution to the nonetype problem before I start reprogramming everything to work with processes.

My instinct tells me it has to do with this code:
```
class Iterator(threading.Thread):

    def __init__(self, board):
        super(Iterator, self).__init__()
        self.board = board
        self.daemon = True

    def run(self):
        while 1:
            try:
                while self.board.bytes_available():
                    self.board.iterate()
                time.sleep(0.001)
            except (AttributeError, serial.SerialException, OSError):
                # this way we can kill the thread by setting the board object
                # to None, or when the serial port is closed by board.exit()
                break
            except Exception as e:
                # catch 'error: Bad file descriptor'
                # iterate may be called while the serial port is being closed,
                # causing an "error: (9, 'Bad file descriptor')"
                if getattr(e, "errno", None) == 9:
                    break
                try:
                    if e[0] == 9:
                        break
                except (TypeError, IndexError):
                    pass
                raise
            except (KeyboardInterrupt):
                sys.exit()

```
found on the pyfirmata github repo [here](https://github.com/tino/pyFirmata/blob/master/pyfirmata/util.py)

I've been searching around for days, but still have no clue why this would cause whichever board is tied to the second instance of the iterator object to only give nonetype objects as analog reads. It's not a serial communications problem, because `some_digital_pin.write(pwm)` works for both boards when both plugged in.

Any help or insight into this issue would be greatly appreciated, as well as tips on how to bypass this issue to allow both boards to read without using multiprocessing.

title: Pyfirmata util.Iterator causes serial communications issues with more than one Arduino

Answers: 0


body:
Hello all: I am very new to all of this and suspect that I am doing something wrong. I try to download the library using the IDE (Version 1.8.15) and get the error messageArduino: 1.8.15 (Windows Store 1.8.49.0) (Windows 10), Board: "Arduino Uno"

Error downloading https://downloads.arduino.cc/packages/package_index.json

Specified folder/zip file does not contain a valid library

Specified folder/zip file does not contain a valid library

I am trying to use a 4-20mA current loop board from NCD.io and this is the library that they say to use.

Thank you for your time

title: Has anyone had issues when trying to download the "CE_ARDUINO_LIB" from Github?

Answers: 0


body:
I am using the Arduino Nano every. Take this example where I am measuring two things A and B.

```c++
Loop{// this loop runs once every second
    //Read A,B
    //Change something using analogueWrite which would effect A,B values
    //Read A,B
}
```

Would the `analogueWrite` values have changed fast enough such that the third line would read the new and changed A,B values?

title: How fast does the Arduino execute code?

Answers: 1

body:
The Arduino Nano Every does not have analog outputs. The function
`analogWrite()` uses PWM as an ersatz of analog output. As soon as the
function returns, you know that the timer registers controlling the PWM
feature have been set to the proper duty cycle. The timer, however, will
complete the current PWM cycle using the previous settings. Only when
this cycle is over will it use the updated settings for the next one.
Completing the current cycle can take up to 2 ms.

Now, I wonder how the PWM cycle can have any effect on what you are
measuring. If you expect to measure something that depends on the
apparent “analog” value you are outputting, this can only work if your
circuit contains (or behaves like) a low-pass filter. In order to
convert the PWM to an analog value, the filter's time constant has to be
significantly longer than the PWM period. This in turn will cause a
corresponding lag, so your readings will take roughly one filter's time
constant to catch up with the value you are outputting.

Note that all this has absolutely nothing to do with how fast the
Arduino executes code.


body:
Im trying to run Timestamps.ino (an example sketch) from the sdfat.h lib into a mkrzero arduino.

This is the code I am running:
```
/*
 * This program tests the dateTimeCallback() function
 * and the timestamp() function.
 */
#include <SPI.h>
#include "SdFat114.h"
#include "sdios.h"

SdFat sd;

SdFile file;

// Default SD chip select is SS pin
const uint8_t chipSelect = 28;

// create Serial stream
ArduinoOutStream cout(Serial);
//------------------------------------------------------------------------------
// store error strings in flash to save RAM
#define error(s) sd.errorHalt(F(s))
//------------------------------------------------------------------------------
/*
 * date/time values for debug
 * normally supplied by a real-time clock or GPS
 */
// date 1-Oct-14
uint16_t year = 2014;
uint8_t month = 10;
uint8_t day = 1;

// time 20:30:40
uint8_t hour = 20;
uint8_t minute = 30;
uint8_t second = 40;
//------------------------------------------------------------------------------
/*
 * User provided date time callback function.
 * See SdFile::dateTimeCallback() for usage.
 */
void dateTime(uint16_t* date, uint16_t* time) {
  // User gets date and time from GPS or real-time
  // clock in real callback function

  // return date using FAT_DATE macro to format fields
  *date = FAT_DATE(year, month, day);

  // return time using FAT_TIME macro to format fields
  *time = FAT_TIME(hour, minute, second);
}
//------------------------------------------------------------------------------
/*
 * Function to print all timestamps.
 */
void printTimestamps(SdFile& f) {
  dir_t d;
  if (!f.dirEntry(&d)) {
    error("f.dirEntry failed");
  }

  cout << F("Creation: ");
  f.printFatDate(d.creationDate);
  cout << ' ';
  f.printFatTime(d.creationTime);
  cout << endl;

  cout << F("Modify: ");
  f.printFatDate(d.lastWriteDate);
  cout <<' ';
  f.printFatTime(d.lastWriteTime);
  cout << endl;

  cout << F("Access: ");
  f.printFatDate(d.lastAccessDate);
  cout << endl;
}
//------------------------------------------------------------------------------
void setup(void) {
  Serial.begin(9600);
  // Wait for USB Serial
  while (!Serial) {
    SysCall::yield();
  }
  cout << F("Type any character to start\n");
  while (!Serial.available()) {
    SysCall::yield();
  }
  // Initialize at the highest speed supported by the board that is
  // not over 50 MHz. Try a lower speed if SPI errors occur.
  if (!sd.begin(chipSelect, SD_SCK_MHZ(50))) {
    sd.initErrorHalt();
  }

  // remove files if they exist
  sd.remove("callback.txt");
  sd.remove("default.txt");
  sd.remove("stamp.txt");

  // create a new file with default timestamps
  if (!file.open("default.txt", O_WRONLY | O_CREAT)) {
    error("open default.txt failed");
  }
  cout << F("\nOpen with default times\n");
  printTimestamps(file);

  // close file
  file.close();
  /*
   * Test the date time callback function.
   *
   * dateTimeCallback() sets the function
   * that is called when a file is created
   * or when a file's directory entry is
   * modified by sync().
   *
   * The callback can be disabled by the call
   * SdFile::dateTimeCallbackCancel()
   */
  // set date time callback function
  SdFile::dateTimeCallback(dateTime);

  // create a new file with callback timestamps
  if (!file.open("callback.txt", O_WRONLY | O_CREAT)) {
    error("open callback.txt failed");
  }
  cout << ("\nOpen with callback times\n");
  printTimestamps(file);

  // change call back date
  day += 1;

  // must add two to see change since FAT second field is 5-bits
  second += 2;

  // modify file by writing a byte
  file.write('t');

  // force dir update
  file.sync();

  cout << F("\nTimes after write\n");
  printTimestamps(file);

  // close file
  file.close();
  /*
   * Test timestamp() function
   *
   * Cancel callback so sync will not
   * change access/modify timestamp
   */
  SdFile::dateTimeCallbackCancel();

  // create a new file with default timestamps
  if (!file.open("stamp.txt", O_WRONLY | O_CREAT)) {
    error("open stamp.txt failed");
  }
  // set creation date time
  if (!file.timestamp(T_CREATE, 2014, 11, 10, 1, 2, 3)) {
    error("set create time failed");
  }
  // set write/modification date time
  if (!file.timestamp(T_WRITE, 2014, 11, 11, 4, 5, 6)) {
    error("set write time failed");
  }
  // set access date
  if (!file.timestamp(T_ACCESS, 2014, 11, 12, 7, 8, 9)) {
    error("set access time failed");
  }
  cout << F("\nTimes after timestamp() calls\n");
  printTimestamps(file);

  file.close();
  cout << F("\nDone\n");
}

void loop() {}
```

And this is the error I get when I press any key into the serial.

```
Type any character to start
Can't access SD card. Do not reformat.
SD errorCode: 0X30,0X2
```

It's not and sd format problem, and I know that the chipselect pin for the SD is 28.

I have no idea what is wrong. Is it maybe a samd21 limitation with this library? is it there a samd21 lib for sd card?

I have written data in the sd card with other avr so I dont think the sd card is the problem.

Thanks

title: Can't access SD card when running timestamps.ino from sdfat.h lib on arduino MKRZero

Answers: 0


body:
Im trying to do OTA upload from Arduino IDE.

Uploaded BasicOTA to ESP-01 with flash size set to (FS:2mb, OTA 1019kb).
ESP-01 connects and shows up in Port selection, but when trying to upload I get

    Uploading.................................................

    14:40:35 [ERROR]: Error Uploading

Thats the only output I get.
Anyone had similar issue?

Thx

title: ESP-01 OTA Error uploading

Answers: 1

body:
The ESP-01 comes in two variants: blue, with 512KiB flash, and black, with 1MiB flash.

You have chosen an arrangement that needs 4MiB flash.  It won't fit.

Choose a suitable flash size for your board.


body:
I have an SHT30 sensor which is feeding to my Arduino via an RS485 connection. The readings are coming in as they should be for both temperature and humidity. The problem, however, is that the relative humidity I get from the SHT30 sensor is currently 45%, whereas the calculation of humidity from dry and wet bulb readings in the same conditions is 75%.

How can it be that my SHT30 reading differs by 30% from the actual calculated reading?

I confirm that all of the charts I have looked at place my relative humidity (given dry and wet bulb readings that I know are accurate) to be in the region of 75%. I know for certain, therefore, that it is my humidity sensor that is wrong.

Have you experienced this issue and, if so, how have you fixed it?

Many thanks in advance!

title: SHT30 giving wrong humidity

Answers: 0


body:
It is possible to access the Physical Pin 93, Pin PC11 on ATSAM3X8E in [Arduino Due][1]  from the Arduino IDE?

I am programming a Barebone ATSAM3X8E, and it do not seems to be allocated by [Arduino Due][2] nor by ATSAM3X8E for any other purpose than the PC Port.

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

  [1]: https://www.arduino.cc/en/Hacking/PinMappingSAM3X
  [2]: https://forum.arduino.cc/t/due-pinout-diagram/129258
  [3]: https://i.stack.imgur.com/mfC61.png
  [4]: https://i.stack.imgur.com/rJh43.png
  [5]: https://i.stack.imgur.com/ZIuZU.png

title: Accessing Physical Pins in Arduino Due from Arduino IDE

Answers: 1

body:
# Modifying/Making a variant

If you wanted to do it in an Arduino-like way it would require editing the Arduino Due [variant.cpp][1] or copying the making your own variant, say from a copy of the Due, and editing the `extern const PinDescription g_APinDescription[]` array to include an entry that matches for PC11.

## Example changes

As an experiment I made the following changes to files in the `packages/arduino/hardware/sam/1.6.12/variants/arduino_due_x` under the arduino15 directory.

In variant.cpp, an entry for in the `g_APinDescription` array is insert an index number 79, between the existing two entries (shown for context):

```c
  { PIOB, PIO_PB23B_SPI0_NPCS3,ID_PIOB,PIO_PERIPH_B,PIO_DEFAULT, PIN_ATTR_DIGITAL,                  NO_ADC, NO_ADC, NOT_ON_PWM,  NOT_ON_TIMER }, // NPCS3
  // Addition line here VVVV (this is the line for PC12, copied with PIO_PC12 changed to PIO_PC11
  { PIOC, PIO_PC11,          ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL,                  NO_ADC, NO_ADC, NOT_ON_PWM,  NOT_ON_TIMER }, //
  // 79 .. 84 - "All pins" masks

  // 79 - TWI0 all pins
  { PIOA, PIO_PA17A_TWD0|PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
```

This is a copy of the entry for PC12, with `PIO_PC12` changed to `PIO_PC11`.

In variant.h, `PINS_COUNT` changes to `80u`, because we've inserted  the pin:

```c
#define PINS_COUNT           (80u)
```

and later in the file the pin number associate with CAN are bumped up by one also because they're all numbered after the point of insertion:

```c
/*
 * Complementary CAN pins
 */
static const uint8_t CAN1RX = 89;
static const uint8_t CAN1TX = 90;

// CAN0
#define PINS_CAN0            (91u)
// CAN1
#define PINS_CAN1            (92u)
```

I programmed a sketch the blinks PC11 by way of `digitalWrite(79, state);` and carefully placed a logic probe on the the unrouted pin on the Due board, and it "blinks" just fine.  That's as far as I've tested.

# Direct control

Alternately you could control the pin in your code manually, doing what `digitalWrite` or `digitalRead` would normally do.  In other words, you could read the description of something like digitalWrite [here][2] and substitute all of the references that it would have gotten from `g_APinDescription` with hard-coded values.

  [1]: https://github.com/arduino/ArduinoCore-sam/blob/c43d4be/variants/arduino_due_x/variant.cpp
  [2]: https://github.com/arduino/ArduinoCore-sam/blob/c43d4be431bd5673f6bb26f83411bbd8f9ef89ef/cores/arduino/wiring_digital.c#L91


body:
    const int buzzerPin = 7;
    const int flamePin = 10;
    int Flame = HIGH;
    int redled = 8;
    void setup()
    {
      pinMode(buzzerPin, OUTPUT);
      pinMode(redled, OUTPUT);

      pinMode(flamePin, INPUT);
      Serial.begin(12000);
    }

    void loop()
    {
      Flame = digitalRead(flamePin);
      if (Flame== HIGH)
      {
        digitalWrite(redled, HIGH);
      int i=0;
      do {
        digitalWrite(buzzerPin, HIGH);
        tone(buzzerPin,450);
        delay(200);
        noTone(buzzerPin);
        delay(200);

      }while (i<2);
      }
      else
      {
        digitalWrite(buzzerPin, LOW);
        digitalWrite(redled, LOW);
      }
    }

title: I have a problem with this code where the buzzer won't work

Answers: 1

body:
**Here are the modifications I have done**

* I changed the Piezo Buzzer frequency to 3000 Hz
The green Button simulates the Flame signal
* Change the RED LED from pin 8 to Pin 13 so that I don't have to use an external LED

**Here is the simulation output**

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

Observe the onboard LED going HIGH and the buzzer going off. You can find the project link [**here**][2] where you can test with different Piezo buzzer frequency.

**Code**

    const int buzzerPin = 7;
    const int flamePin = 10;
    int Flame = HIGH;
    int redled = 13;
    void setup()
    {
      pinMode(buzzerPin, OUTPUT);
      pinMode(redled, OUTPUT);

      pinMode(flamePin, INPUT);
      Serial.begin(12000);
    }

    void loop()
    {
      Flame = digitalRead(flamePin);
      if (Flame== HIGH)
      {
        digitalWrite(redled, HIGH);
      int i=0;
      do {
        digitalWrite(buzzerPin, HIGH);
        tone(buzzerPin,3000);
        delay(200);
        noTone(buzzerPin);
        delay(200);

      }while (i<2);
      }
      else
      {
        digitalWrite(buzzerPin, LOW);
        digitalWrite(redled, LOW);
      }
    }

*Disclaimer: I am not the Wokwi creator but I support it since it is open source and free to use*

  [1]: https://i.stack.imgur.com/pTzPR.gif
  [2]: https://wokwi.com/arduino/projects/300993767428588045


body:
3x NEMA 17 Stepper Motors: https://www.amazon.com/gp/product/B00PNEQKC0/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1

3x DM542T Stepper Driver: https://www.omc-stepperonline.com/download/DM542T.pdf

Power supply: 12V, 30A

Arduino Mega: https://www.amazon.com/ARDUINO-MEGA-2560-REV3-A000067/dp/B0046AMGW0/ref=sr_1_3?dchild=1&keywords=arduino+mega&qid=1623258848&sr=8-3

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

I am currently trying to use the GRBL (Mega version 1.1f - https://github.com/gnea/grbl-Mega) and Universal G-code sender (UGS classic version 2.0.7 - https://github.com/winder/Universal-G-Code-Sender) to program my 3 NEMA 17 Stepper motors, but none of the motors move. I have tried powering just one NEMA motor using a simple arduino code successfully.
I successfully uploaded the GRBL Mega software onto the arduino and connected that with the UGS. Upon using the toggle buttons, the status shows that the coordinates are jogging, but my stepper motor does not move. I probed the pins with an oscilloscope as well and read a continuous 5V on pins 11 and 12, which I don't exactly understand. Shouldn't there be pulses sent to the pins used, not continuous voltage?

Here are my current connections:
V+ on driver is connected to V+ on power supply
V- on power supply is connected to GND on arduino and GND, DIR-, PUL- on the driver
The other four wires are connected from motor to driver.
DIR+ is connected to pin 5, and PUL+ is connected to pin 2

Please suggest anything I can try!

title: NEMA 17 Stepper motor + Arduino Mega + driver doesn't move using GRBL and UGS

Answers: 0


body:
i have some trouble to use i2c and the other pins at the same time.

im tring to control the attiny over i2c with a arduino and the attiny should control a 28byj-48 stepmotor.

i started to setup the i2c connection pin 0 and pin 2 is use for that. it is working fine but then i connected the stepmotor driver on pin 1,3,4,5 after connecting the 5 pin i lose my i2c connection.

here is the code from the attiny, nothing special

```
#include <TinyWireS.h>                // wrapper class for I2C slave routines

#define I2C_SLAVE_ADDR  0x29            // i2c slave address (38)
#define A 1
#define B 3
#define C 4
#define D 5
#define NUMBER_OF_STEPS_PER_REV 512

void setup(){
  pinMode(1,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  TinyWireS.begin(I2C_SLAVE_ADDR);      // init I2C Slave mode
}

void loop(){
  byte byteRcvd = 0;
  if (TinyWireS.available()){           // got I2C input!
    byteRcvd = TinyWireS.receive();     // get the byte from master
    //Blink(byteRcvd);           // master must wait for this to finish before calling Wire.requestFrom
    //byteRcvd += 10;                                                    // add 10 to what's received
    //TinyWireS.send(byteRcvd);           // send it back to master

    //             Blink(1);                  // show we transmitted
  }
}
```

title: Digispark Rev.3 Kickstarter ATTiny85 using all 6 pins

Answers: 2

body:
There is no such Digispark board as the Rev 3. There was going to be, but there was a mistake, so they went straight from Rev 2 to Rev 4. However unscrupulous Chinese counterfeiters are making "Rev 3" boards.

So... your mileage may vary since the components used on there could be of *any* dubious quality.

But to your problem: P5 is also the RESET pin.  If the fuses on that chip are set correctly then it can be used as an IO port. But being a counterfeit, who knows what they set the fuses to?

But if you *do* change the fuses you will have to rely on the power-on reset (plugging it in) to trigger uploads.

body:
As an addition to [Majenko][1]'s answer I can report having used many of the "Rev.3" counterfeits, every single one came with *chip default fuses* thereby **reset enabled**.

You can set the [RSTDISBL][2] fuse with your [Arduino][3], plus update the [micronucleus][4] bootloader in the process (freeing 0.4k).

Keep in mind setting this fuse will **disable ISP programming**, so you will need a working bootloader to reprogram the chip unless you revert it via [HV programming][5].

  [1]: https://arduino.stackexchange.com/users/4143/majenko
  [2]: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf#G1.2073549
  [3]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/ArduinoISP
  [4]: https://github.com/micronucleus/micronucleus
  [5]: https://www.instructables.com/How-to-unlock-Digispark-ATtiny85-and-convert-it-to/