text:
Can I test if something is connected to analog pin?
In my sketch I have a potentiometer connected to A0.  The value of the pot is used to adjust the speed of a connected item.
I have set the speed to have a default value, but doing analogRead() on a pin with nothing attached gives random values rather than using the default value.  The docs state "If the analog input pin is not connected to anything, the value returned by analogRead() will fluctuate based on a number of factors (e.g. the values of the other analog inputs, how close your hand is to the board, etc.)."  https://www.arduino.cc/reference/en/language/functions/analog-io/analogread/
How can I test whether something is connected to A0 and if not, use the default value?

Not in any general way, no, but it's unclear why this is a problem.

instead of connecting the pot between Vcc and Gnd, connect it between two data pins ... setting both the data pins to LOW should result in analog reading of near 0 V ... then set both to HIGH ... etc etc

@DaveNewton it is as a fallback value if pot doesn't exist.

In my sketch I have a potentiometer connected to A0 ... but doing analogRead() on a pin with nothing attached gives random values rather than using the default value. - Why is this an issue? - you say you have something connected, but you are asking how do you detect if nothing is connected. Do you, or do you not, have the pot connected to A0?

@NickGammon it makes the sketch more generic and acts as a fallback value if pot doesn't exist.

I agree with Boggyman's answer. A large-value resistor between A0 and Gnd would at least tend to give zero readings consistently. Although you wouldn't know then if the pot was just turned to its lowest setting. I don't know that there is any really reliable way to achieve what you want. There is no "default value" absent a pull-up or pull-down resistor. Possibly you could conclude that if you got lots of random values in a short time that there was nothing connected.

@NickGammon: Your last sentence is a summary of JRobert's answer. In practice, analog readings of floating inputs are not as random as you may expect, unless you have a strong capacitive coupling with a powerful noise source. You can artificially force the readings to have strong fluctuations though, as described in my answer.

Your last sentence is a summary of JRobert's answer - true, and being a comment it was not intended as an answer per se. I was commenting that there were a few different ways you could go about it. Stating the obvious, perhaps? :)

The input stage of the analog-to-digital converter is a sample-and-hold
capacitor. When you take an analog reading, the capacitor is connected
to the input pin, it is charged to the voltage you want to measure, then
it is disconnected from the input and it “holds” the voltage while the
conversion is in progress.
You can leverage this capacitor to detect whether your input pin is
floating. If you try to take an analog reading from a floating pin, the
sample-and-hold capacitor will not be able to charge or discharge
through it. You should then get a reading that is close to the
previous reading you took, although not exactly the same, as floating
pins a very prone to noise. Thus I suggest the following algorithm:

take a reading from a pin tied to GND, and discard this reading
take a reading from your input pin and record it
take a reading from a pin tied to +5V and discard it
take and record a second reading from your input pin

If the input pin is floating, the first recorded reading should be close
to zero, and the second one close to 1023.
Here is a test sketch demonstrating this approach. It uses
digitalWrite() to tie the required pins to GND and +5V, thus no
external connections are needed:
const uint8_t pin_input = A0;  // the one we are interested in
const uint8_t pin_low   = A1;  // will be tied to GND
const uint8_t pin_high  = A2;  // will be tied to +5V

void setup() {
    Serial.begin(9600);
    pinMode(pin_input, INPUT);
    pinMode(pin_low, OUTPUT);
    digitalWrite(pin_low, LOW);
    pinMode(pin_high, OUTPUT);
    digitalWrite(pin_high, HIGH);
}

void loop() {
    analogRead(pin_low);  // take a reading and discard it
    Serial.print(analogRead(pin_input));
    Serial.print(" ");
    analogRead(pin_high);  // take a reading and discard it
    Serial.println(analogRead(pin_input));
    delay(200);
}

And here is a sample output from an Arduino Uno:
167 710
271 748
287 753
287 751
284 748
281 746
279 741
271 736
268 733
264 732

It looks like the capacitor does not hold its charge very well across
consecutive readings. This is presumably caused by the parasitic
capacitance of the input pin, which partially charges and discharges the
sample-and-hold. Yet, the difference between consecutive recorded
readings (about 460) is still very high, and this very clearly shows
that the input pin is not connected to a stable voltage.

Take some number of analog readings over some period of time and look at the variation among the samples. Do this both with, and without, a potentiometer connected. You should see very stable readings with it connected, ranging over a few counts or less. Without it connected, the readings are likely to cover nearly the entire range A/D range.
A simple way to detect the pot would be to look at the difference between the highest and lowest readings. Pick a range that covers the "pot is connected" case. If the difference falls within that range, assume the pot is connected. Otherwise, assume it is not.
You could improve on this a number of ways, but a simple way would be to take, say, 50 readings, sort them by value, average the lowest 5 or 10 of them, and average the highest 5 or 10. Subtract those averages, and proceed as above.

The ADC input has a really high impedance (100 Meg).  All you need to do to get a consistent reading (of zero) is to connect it to ground through a suitable resistor.  100K will probably be fine, and you might be able to get away with 1 Meg.  It should be at least 10x bigger than your pot to avoid loading it when connected.

You are quite right, although such an arrangement would not distinguish between nothing connected and the pot turned to its lowest setting.


text:
ESP32 doesn't connect to Arduino. | could not open port 'COM2': WindowsError(5, 'Access is denied.')
ERROR:
serial.serialutil.SerialException: could not open port 'COM2': WindowsError(5, 'Access is denied.')

I've tried literally everything.

Drives checks out! | Silicon Labs CP210x USB to UART Bridge (installed!)
Restarting the computer didn't make any difference
Restarting apps and stuff
Arduino's Serial monitor is closed
The cable is ok! Brand new and testing with other cables (also tested) don't work
The led in the ESP is on and stable, I could upload the sketch wifi scan code once, it keeps looping and just works properly, but I cannot upload new data and/or update the code within the esp32
I've tried holding the buttons in every way possible, it doesn't make any difference.

++

help :(

Nothing else has the port open? It’s the correct port? Can you connect to it with a different machine?

Check whether the board appears as USB to serial CP210x or some variant of it on device manager. If it does  appear you can rule out a hardware issue.

if the port appears in the device manager when you plug the board in, then the hardware is working between windows and the UART bridge ... the access denied is a windows message that is probably not related to the UART bridge

@DaveNewton no I haven't tried connecting it to another machine.

@Coder9390 I'll update the question with the device manager's ports image

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
SPI.begin doesn't work after tristate
I am working on a ultra-low power project using an ATMEGA328P, a nRF24L01 and a 0.47F super-capacitor to measure various sensors akin to Gammon's solar power project. I have been having problems with keeping the current consumption of the nRF24L01 low which appears to be a common problem as noted here. I only have been able to get the current down during sleep to 950uA as opposed to 7uA. Power for the nRF24L01 comes from an AMS1117 that is switched on and off from a digital pin. Thus, during sleep the nRF24L01 isn't drawing power directly so the current must be coming from the SPI. According to Gammon's code, after the radio message is sent he sets the SPI pins as OUTPUT and LOW following SPI.end(), like so:
bool ok = radio.write (&reading, sizeof reading);
radio.startListening ();
radio.powerDown ();
SPI.end ();
// set pins to OUTPUT and LOW
for (byte i = 9; i <= 13; i++)
    {
    pinMode (i, OUTPUT);
    digitalWrite (i, LOW);
    }  // end of for loop

Since the current consumption is coming from the SPI, I decided to reverse this by setting the SPI pins to INPUT assuming that SPI.begin() would automatically set them back appropriately. At this point current during sleep was the expected 7uA but no messages were being sent. I checked around and found that there was a problem where SPI.end()  causes SPI.transfer() to hang even after a new SPI.begin(). Unfortunately the solution there didn't work in my case.
I tried to change the pins to OUTPUT when coming out of sleep but that obviously didn't work. One of the posts pointed out that the pins shouldn't be configured as output before calling SPI.begin() because SPIClass::begin() does not have code in it to do so, and that this is probably done so for a reason. Indeed, in Gammon's code, where he sets all pins to OUTPUT and LOW during setup in order to minimize current consumption, he skips the SPI pins:
  // set pins to OUTPUT and LOW
  for (byte i = 0; i <= A5; i++)
    {
    // skip radio pins
    if (i >= 9 && i <= 13)
      continue;
    pinMode (i, OUTPUT);
    digitalWrite (i, LOW);
    }  // end of for loop

What I don't understand is why is it possible to set the SPI pins as OUTPUT after SPI.end() and not do the same after coming out of sleep and just before SPI.begin()? Also, why is it that if I tristate the pins after SPI.end() the SPI bus doesn't appear to work, that is, SPI.begin() appears to hang?

Interesting problem. How do you know that "it hangs"? The forum thread you refer to is almost 10 years old and this exact problem got already fixed.

You're right. I am not sure that it "hangs". But apparently the problem hasn't been fixed because by simply using SPI.end() current is still flowing through the SPI bus.

I finally found an answer here. The exact problem is close to what I had thought: the MOSI pin isn't set low after SPI.end(). The solution is not to set the pin as INPUT as I had first thought, but to set the MOSI pin low by first adding
SPCR &= 0B10111111;

before putting the system to sleep (which disables the SPI) and then adding this line
SPCR |= 0B01000000;

after coming out of the sleep in order to re-enable the SPI.
Although this problem was already noted years ago and a fix apparently made, it still exists because SPI.end() should have disabled the SPI bus and it didn't, so this workaround is still needed.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
MAX31865 and PT100 readings problem
PT100 (3 wire) is connected to arduino uno as i believe i have them connected properly, i have checked other forums such as changing the capacitor to ferrite core, and probably changing up to 4 breakout boards to get the same result (getting crazy). I also tried switching 3,3v to 5v repeatedly and hence i would get various errors such as the following:
I am using the example from the adafruit example available from adafruit library with the instances:
Adafruit_MAX31865 thermo = Adafruit_MAX31865(10, 11, 12, 13);

// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RREF      4300.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL  1000.0

void setup() {
  Serial.begin(115200);
  Serial.println("Adafruit MAX31865 PT100 Sensor Test!");
  thermo.begin(MAX31865_3WIRE);  // set to 2WIRE or 4WIRE as necessary
}

and the error i always got:
RTD value: 0
Ratio = 0.00000000
Resistance = 0.00000000
Temperature = -242.02

Might not very an engineering way to troubleshoot things but i ordered the original adafruit MAX31865 breakout board instead.  Here is my setup

It looks like everything is hooked up correctly (assuming the trace cut and blobs on the sensor breakout are solid), but it'd be easier to understand the wiring with a schematic. You say you're using the PT100 but you're using the resistance value for the PT1000, which might matter. Hard to say if the sensor is wired to the board correctly. AFAIK you'd need to use only 5V power so the data aligns w/ the Uno's expected input ranges.

Thank you, would it be better to put some info that i knew about connecting the pt100 with the board? and yes apparently i forgot to change the RNOMINAL  1000.0 to RNOMINAL  100.0 but i would still get the same results: error.  As far as i know i have tested the pins of the pt100 with a multimeter to measure its resistance, between the blue-colored ones they are 2 ohm resistance. and between the red and the blues, they have around 109 ohm resistance, and this should be the part of the difference of the temperature measurement.

I would remove private: from the class and use the now available readRegister functions to see if the the chip is communicating correctly at all.  E.g. read the configuration register mentioned in the datasheet with readRgeister8 after the begin() call and see if the contents of it make sense.  Use of the writeRegister function to change one, and then read it back and see if it comes back.

I have a very similar issue - I actually ordered 12 of these boards and am only getting correct readings from 2 of them - the other ones (configured identically) just read "Temperature = -242.02, Fault 0x40, RTD Low Threshold." I've spent considerable time messing around with them to the point where I think it must be the breakout boards are just randomly faulty. I too will buy the adafruit version (10X the price is worth it if they work). Did you have any luck with the original?

Dear Philip C, yes apparently the original ones are worth the price, and it works instantly without even changing ferrite beads or others.


text:
How can I handle six SoftwareSerial ports for six Nova SDS011 Air Quality Sensors on Arduino MEGA?
First of all, thank you in advance.
I'm trying to connect six Nova SDS011 Air Quality Sensor (sensor specifications here) to an Arduino MEGA. I'm using the Nova Fitness Sds dust sensors library which relys on the SoftwareSerial library. As fas as I know, SoftwareSerial can handle a virtual serial port on any digital pin (with some limitations as seen on Arduino reference), but I don't know whether there is any limit on the number of ports that it can handle.
I have communicated successfully with four of them which are conected to the pins:

RX
TX
Sensor

13
12
1

10
11
2

51
50
3

53
52
4

XX
XX
5

XX
XX
6

The two sensors left (5 and 6) have been tested on the Arduino remaining free pins, but it couldn't listen to the ports. I checked if all sensors worked propperly separatedly, and they do, so I can dischart that the problem is related with a faulty sensor. The pins for the serial ports have been declared (for each sensor) as:
// Sensor 1
const uint8_t rxPin1 = 13;  // Brown wire
const uint8_t txPin1 = 12;  // Violet wire
SoftwareSerial sensor1(rxPin1, txPin1);
SdsDustSensor dust_sensor_1(sensor1);

As I have seen on Arduino Reference, I must use the .listen() and .isListening() functions in order to listen to a specific port:
void setup() {
  Serial.begin(9600);
  Serial.println("===========================================");

  // SDS sensors configuration
  dust_sensor_1.begin();
  dust_sensor_2.begin();
  dust_sensor_3.begin();
  dust_sensor_4.begin();
  dust_sensor_5.begin();
  dust_sensor_6.begin();

  sensor1.listen();
  dust_sensor_1.wakeup();
  delay(100);
  if (sensor1.isListening()) {
    dust_sensor_1.setQueryReportingMode();
    String status_mode_1 = dust_sensor_1.setQueryReportingMode().toString();
    while (!status_query.equals(status_mode_1)) {
      dust_sensor_1.setQueryReportingMode();
      status_mode_1 = dust_sensor_1.setQueryReportingMode().toString();
      Serial.print("Sensor 1 mode >> "); Serial.println(status_mode_1);
    }
    Serial.print("Sensor 1 mode >> "); Serial.println(status_mode_1);
  }
  dust_sensor_1.sleep();

  delay(1000);

  // Next sensors
}

The code from above is the same for each sensor, but I have condensed the whole setup() code in just one sensor.
If that code has worked for four sensors, it isn't strange to think that the same code should work for six too. I'm completely stuck at this point and I don't know what I should do. I will not write the loop() code untill the setup() works fine.
At last, when all problems will have been solved and the sensors will tested, I will swap the code into a state machine for a better performance. I will also change some variables that could be joined into a single variable (such as String status_mode_1 which can be just String status_mode; it can be shared with all sensors).
If you happen to need the whole code, please ask for it and then i'll post it.

What pins have you tried for the remaining sensors? Unrelated, but the code would be incrementally easier to reason about if the ports/sensors were stored in an array (and I'd recommend using only a singleNamingConvention).

Not all pins on the Mega and Mega 2560 support change interrupts, so only the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69).

@DaveNewton I have tried all of the remaining digital and analog pins. Regarding the array, I hadn't thought about it and yes, I should use singleNamingConvention, sorry. Juraj, I have seen that info on Arduino Reference web, and I tried all those pins at first, and only worked (for me) 10, 11, 12, 13, 50, 51, 52 and 53, the ones I wrote on the table.

Off the top of my head can't think of anything obvious. Have you tried a simple sketch with a single sensor on one of the available pins you haven't tried? (Another reason having the ports/sensors in an array is that it's much easier to make changes like that :)

I have tried with just one sensor, but with an Arduino UNO. I'll try what you say and I'll edit this comment ASAP.

TX pin can be any pin. only RX pins must support pin interrupt

I have just tried with one sensor using random pins and the specific, as @Juraj sugested. If I use digital pins it seems it works fine, but if I use an analog pin (A8, for instance) it looks it takes some more time to do the task. The behaviour is the same with the six sensors, on analog pins it seems it takes some more time. Yesterday I also tried with all free pins for TX and RX, and it didn't work; maybe, I was declaring a variable wrong, I don't know. I had already worked with SoftwareSerial, but with less sensors. Anyway, it seems it works now and I thank all of you ;)


text:
How to use Serial2 on Raspberry Pi Pico
I want to use Serial1 and Serial2 in a sketch in Arduino IDE for a Raspberry pi pico.
My goal is to communicate from the pico with two other Arduino boards.
I use Arduino 1.8.9 and the official board for Raspberry Pi Pico:
"Arduino Mbed OS RP2040 Boards by Arduino version 2.1.0"
Serial2 does not seem to be configured. When I compile
    #include <Arduino.h>
    void setup() {
        Serial2.begin(9600);
    }

    void loop(){}

I get:
"undefined reference to '_UART2_'".
I found some documents (not rpi pico specific) that state you can define a second UART like this:
    #include "wiring_private.h"
    Uart mySerial (&sercom3, 1, 0, SERCOM_RX_PAD_1, UART_TX_PAD_0); // Create the new UART instance assigning it to pin 1 and 0

But that throws
" 'Uart' does not name a type; did you mean 'sqrt'?"
Does anyone have an example of how to use Serial1 and Serial2 (2 serial communications to two other boards) on a Raspberry Pi Pico using Arduino-IDE?
Thanks a lot!

I found the solution after reading https://github.com/arduino/ArduinoCore-mbed/issues/210#issuecomment-849502556.
Although the proposed code did not compile as it was shown there.
UART Serial2(8, 9);  // did not compile

What worked for me was:
UART Serial2(8, 9, 0, 0);

Full code:
#include <Arduino.h>

UART Serial2(8, 9, 0, 0);

void setup() {
  Serial2.begin(9600);
  // ...
  Serial2.write("hello world");
}

void loop {}

I'm not using the "Mbed" board, I'm using the "Raspberry Pi Boards(1.9.7)" --> "Raspberry Pi Pico" board, and found that:
Serial1 uses hardware UART0
Serial2 uses hardware UART1
Serial1.begin(SOME_BAUDRATE); // defaults to TX on GP0 and RX on GP1
Serial2.begin(SOME_BAUDRATE); // defaults to TX on GP8 and RX on GP9
To change the default UART pins to other option, as long as it comply with the Raspberry Pi Pico pinout (look for UARTx_TX / UARTx_RX next to the pins), see the following example:
#include <hardware/pio.h>

gpio_set_function(12, GPIO_FUNC_UART); // change the TX default for Serial1 (UART0)
                                       // to be GP12

gpio_set_function(13, GPIO_FUNC_UART); // change the RX default for Serial1 (UART0)
                                       // to be GP13

Completely different situation since you're using a different board.


text:
How to get time from RTC after wake up from sleep?
I have a setup with an Arduino Pro Mini, a DS1307 RTC, a microSD shield and a microswitch. I've set an interrupt to the microswitch, so it'll wake up the Arduino when it changes status. Here is some relevant code:
void setup() {
  rtc.begin();
  pinMode(button, INPUT);
  SD.begin(chipSelect);

  /*Omitted the same write to file as in button_ISR()*/
}

void loop() {
  delay(5000);
  goToSleep();
}

void goToSleep() {
  sleep_enable();
  attachInterrupt(digitalPinToInterrupt(button), button_ISR, CHANGE);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  delay(500);
  sleep_cpu();
}

void button_ISR() {
    sleep_disable();
    detachInterrupt(0);
    rtc.begin();
    String data = (digitalRead(button))?"OPEN":"CLOSE";
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    if(dataFile) {
      DateTime now = rtc.now();
      dataFile.print(now.year(), DEC);
      dataFile.print('.');
      dataFile.print(now.month(), DEC);
      dataFile.print('.');
      dataFile.print(now.day(), DEC);
      dataFile.print(". (");
      dataFile.print(daysOfTheWeek[now.dayOfTheWeek()]);
      dataFile.print(") ");
      dataFile.print(now.hour(), DEC);
      dataFile.print(":");
      dataFile.print(now.minute(), DEC);
      dataFile.print(":");
      dataFile.print(now.second(), DEC);
      dataFile.print(";");
      dataFile.println(data);
      dataFile.close();
    }
    delay(1000);
}

If I don't call rtc.now(), and omit the DateTime prints, the code perfectly writes "OPEN" and "CLOSE" in the txt. I have the same dateTime writing inside the setup(), with "START", and it perfectly writes the current date/time.
What am I missing? How could I get the time from RTC after wake up?

You should not sleep in an ISR. You should not write to a file either. Actually, the best you can do is leave the ISR empty, and move all its contents to right after sleep_cpu();.

@EdgarBonet yup, this was the solution :) If you make it an answer, I'll accept it. Thanks!

You should not delay in an ISR, for two reasons:

Interrupts are disabled while the ISR runs, and delay() relies on
interrupts.

Interrupts are used to handle time-critical tasks. The longer the
interrupts are disabled, the larger the chances that one of those
time-critical tasks is handled too late. Thus, ISRs should execute as
fast as possible.

In this particular case, if we try to make the ISR as short as possible,
the optimal version is this:
void button_ISR() {}

Since the interrupt is meant to wake up the Arduino, and nothing more,
everything the ISR does can be done at wake-up, right after
sleep_cpu();.
A few more comments and suggestions:

set_sleep_mode(SLEEP_MODE_PWR_DOWN); can be done once and for all in
setup()

instead combining sleep_enable(), sleep_cpu() and
sleep_disable(), you can use a single call to sleep_mode()

you most probably do not need to reinitialize the RTC and re-open the
file at every loop iteration: do this only once, in setup()

String objects are not friendly to a small Arduino's memory; in this
case you can get rid of them by simply replacing the word String
with const char *

if you are using RTClib, you may want to use the
DateTime::toString() method, which can make your code
shorter and simpler.


text:
How to deal with global variables in a program which has more than 5 functions and every function accesses them without any problem?
I know that using Global Variables in programming may create lots of problems in long term , like , Bugs , Lags and more . I am working on a program which has more than 5 functions which need to access global variables something like this.
int Name;
int Age;
int Weight;
String EyeColour;

void AddValues(int N, int A , int W , String EC){
    Name = N;
    Age = A;
    Weight = W;
    EyeColour = EC;
}

// All the functions below use those Global Variables

void function2(){
    ...
}

void function2(){
    ...
}

void function3(){
    ...
}

void function4(){
    ...
}

 void function5(){
    ...
 }

But according to this article
I should avoid using global variables to avoid future problems so I wrapped them up inside a struct.
Like this.
struct Person{

int Name;
int Age;
int Weight;
String EyeColour;

}

Now my main question is, should I declare the structure variable globally? Will it avoid the problems which could be created by global variables ?
If I declare the struct variable globally will it be equivalent to declaring variables globally instead of the structure?
Or
Should I declare the structure variable inside all the functions instead of declaring globally?
So that all functions can work flawlessly without any global variable problems.

This seems to be a general C/C++ question rather than an Arduino question. To amswer the general question--it depends, looks like a canonical class example.

This is actually relevant to Arduino programming, or any chip with small memory.  The cited article is fine for big systems, but when memory is tight there are other considerations that may make it worth your time keeping track of globals.  In big systems we can expect the automatic stack handling to take care of everything in the background without having to think about stack and/or heap crashing into working memory.  Not so when you only have 2K total... and stack collisions can be pretty mysterious!

Dwelling on this question for academic purposes or extreme cases (where there's lots of data (i.e. audio sampling)) is great.  But most Arduino programs I have seen do not use that many variables.  So making Arduino sketch variables global (notice I'm not including Arduino libraries!) is likely fine.

globals are to be generally avoided when feasible, not 100% banned always.

Create a class from the 4 variables (I don't have a compiler at hand, so forgive any compiler errors):
class Person
{
public:
    void Person(int N, int A , int W , String EC);

private:
    int Name;
    int Age;
    int Weight;
    String EyeColour;
}

Create the implementation of Person in the Person.cpp file.
About the functions, if they only relay (or mostly rely) on the 4 properties (Name, Age, Weight, EyeColor), make the a method (function) inside the class.
Decide if a function should be in a method depends upon  many thing, but the most important question is: does it belong (well enough) to the class or not?
Now in the Arduino.ino you can make one instance (or more if you need more).
Person _person;

Preferably, I add an underscore for global variables (and instance variables).
Also, I would avoid using String as changing it will cause dynamic memory allocation changes, which can be very bad in a 2K SRAM system. Try to make constant string arrays (with a max length).

Better still, eye colour could be an enum...

@Majenko Indeed, if the number of possibilities is fixed (gender used to be a boolean)


text:
Serial.print() Inferferes with my digitalRead()
I'm running into issue properly reading a button connected to a digital I/O pin on my Adafruit Feather HUZZAH ESP8266 device.
I've implemented the debouncing script exactly as the Arduino provided example shows, but if I add a print statement to my setup loop:
void setup() {
  Serial.begin(230400);
  Serial.println("Starting");
  pinMode(buttonPin, INPUT_PULLUP);
}

I trigger a reading of the switch on every reset cycle. Commenting out the print statement will avoid the problem so it doesn't appear to be related to the debouncing script.
In addition, I can replicate the problem on any digital I/O pin even when there is no pin connected. Once I get past the setup function, everything works as intended. Here's my whole setup code (again, copied from the example):
const int buttonPin = 13;
int buttonState;
int lastButtonState = LOW;

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

void setup() {
  Serial.begin(230400);
  Serial.println("Starting");
  pinMode(buttonPin, INPUT_PULLUP);
  lastDebounceTime = millis();

}

void loop() {
  int reading = digitalRead(buttonPin);

  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;

      Serial.println("A");
    }
  }

  lastButtonState = reading;
}

And here's the output of my serial monitor (with no delays on reset):
Starting
A

I can avoid this by just ignoring the first button switch but it seems odd that this is happening and I can't find any explanations for what's going on.

Please not just include your setup code, but the whole code.

We can't either since we can't see your code ;) There's no particular reason writing to the serial port would "trigger a button read". However: serial writes are asynchronous, and adding a call to Serial.println adds to (a) time spent in setup, and (b) time spent doing "things" before the serial buffer is written out. It seems more likely there's a flaw in the debounce logic, particularly if lastDebounceTime is initialized to 0 (a Long Time Ago to the controller).

Added my loop code. @DaveNewton - I changed my setup to reset my lastDebounceTime to my last operation before entering my loop but still I print "A" on every reset.

Did you try moving the pinMode to avoid the period of floating?

I've tried putting it first and last in my setup with no effect. Would there be a time period needed for the digital read to "settle" or something?

The issue ended up that buttonState was never initialized in the example scripts so it begins != to the reading thus triggering as soon as the timer exceeds the debounce delay.  I was able to fix it simply by initializing the value to be the same as the value of lastButtonState.

I haven't really been paying much attention to this question; I just notice you've solved your own problem.  If what you've written above is an answer that follows from the information in the question and you think all of this would be useful to someone else, you can post your own answer to it.  Otherwise the question will likely float around in the system forever as unaswered, unless you delete it.

You need to initialise buttonState to the current signal state and initialise lastDebounceTime to the current time, something like this:
int buttonState = digitalRead(buttonPin);
unsigned long lastDebounceTime = millis();

Compare with this very simple debouncer I put on GitHub.

You're absolutely right! I'm not sure why I didn't catch that or why the Arduino provided sketch doesn't initialize the variables.

Initializing my buttonState solved my problem:
int buttonState = LOW;

In any case, be aware that writing in serial pauses the microcontroller for a few milliseconds!

@alessandromrc: For a few microseconds. Unless the TX buffer is full, in which case it can indeed take milliseconds.

@EdgarBonet You are right!


text:
Passing a two dimensional array to a function
I'm working on an led matrix project where I'm running a series of patterns made of bitmap frames.
Here's an example: https://vimeo.com/564184465
Right now I'm using a series of method calls named per pattern to run the animation:
void CSMatrix::runPattern(PATTERNS pattern, uint8_t totalRuns)
{
  for (uint8_t i = 0; i < totalRuns; i++)
  {
    switch (pattern)
    {
    case PATTERN_ZIG_ZAG:
      runPatternSpacedStripes();
      break;
    case PATTERN_ARROW_UP:
      runPatternArrowUp();
      break;
...
    }
  }
}

void CSMatrix::runPatternSpacedStripes()
{
  for (uint8_t i = 0; i < SPACED_STRIPES_LEN; i++)
  {
    renderFrame(SPACED_STRIPES[i]);
    FastLED.show();
    delay(100);
  }
}

void CSMatrix::runPatternArrowUp()
{
  for (uint8_t i = 0; i < ARROW_UP_LEN; i++)
  {
    renderFrame(ARROW_UP[i]);
    FastLED.show();
    delay(100);
  }
}

...

And the bitmaps used to control the matrix pixel states look like this (the functions beneath renderFrame basically say "if it's a 1, use this color, if it's a 0, use that color":
const byte SPACED_STRIPES[][8] = {
    {0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100,
     0b00011000},
    {0b01100011,
     0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100},
...
};
const int SPACED_STRIPES_LEN = sizeof(SPACED_STRIPES) / 8;

This is working fine, but having a bunch of identical methods to run each pattern is not great.
So, with this working I decided to refactor to make a common runTwoColorPattern method that could accept the pattern frames and the length to run the given pattern:
void CSMatrix::runTwoColorPattern(const byte *frames, const int length, int delayDuration)
{
  for (uint8_t i = 0; i < length; i++)
  {
    renderFrame(frames[i]);
    FastLED.show();
    delay(delayDuration);
  }
}

The problem I'm running into is figuring out how to properly pass the two dimensional array to the function.
I tried updating my switch statement by passing the pointer of SPACED_STRIPES into the runTwoColorPattern:
    switch (pattern)
    {
    case PATTERN_ZIG_ZAG:
      runTwoColorPattern(SPACED_STRIPES, SPACED_STRIPES_LEN, 100);
      //runPatternSpacedStripes();
      break;

But when I do I get the error

argument of type "const byte (*)[8]" is incompatible with parameter of type "const byte *"C/C++(167)

I've found that I can correct this by dereferencing the first item of the multidimensional array, (which would mean I'm passing the memory address to the first pointer element of the multi-dimensional array (I think)), but when I do this the pattern runs backwards and is jittery :|
https://vimeo.com/564184624
I'm not totally sure how to correct this. I'm still fairly new to pointers so I'm sure there's something I'm misunderstanding with passing a pointer for a multi-dimensional array, but I thought what I was passing was basically an address of where to start for the pointer, so I'm not sure why I'm hitting these snags or how to fix it.
Any suggestions?

You really don't need a 2D array for this - a simple 1D one will do and just use multiple-of-8 offsets to read each frame.

Aaaaaah that's true! I was running with this format b/c it was easy to visually parse and adjust the bitmaps by hand after generating them from an online calculator, but ultimately that format isn't needed. So to restate to make sure I understand: I can make a 1d array where each element is a single number representation of the frame and those numbers can be parsed 8 bits at a time to get the rows within the frame, right?

No, you'd just have a big "blob" of 8 bit values. Exactly as you have now, but without the },{ between each frame. Then frame 0 starts at offset 0. Frame 1 at offset 8. Frame 2 at offset 16, etc. Basically &frames[i * 8]

ah, even simpler. I'll give it a try and when i have it working I'll post an answer. Thanks for the help!!

A 2D array would be passed as const byte frames[][8]. However you really don't need the complexity of a 2D array - you can do it with a 1D array.
Your array would look like:
const byte SPACED_STRIPES[] = {
     0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100,
     0b00011000,

     0b01100011,
     0b11000110,
     0b10001100,
     0b00011000,
     0b00110001,
     0b01100011,
     0b11000110,
     0b10001100,
...
};

And you reference frames within it as a multiple of 8 of the index.  Using your existing code it would look like:
void CSMatrix::runTwoColorPattern(const byte *frames, const int length, int delayDuration)
{
  for (uint8_t i = 0; i < length; i++)
  {
    renderFrame(&frames[i * 8]); // Take the address of the first value of the frame at a multiple of 8
    FastLED.show();
    delay(delayDuration);
  }
}

Awesome, this worked! I updated my pattern and the method and now the animations are running as expected. Implementing the changes also helped me understand exactly what you were going for; the structure of the multi-dimensional array helped me visually, but isn't necessary for the parsing. The other added benefit of doing it this way is that now that it's a flat array I can send through arbitrary sized blobs for different sized matricies (16x16, 32x32 ...) and just parameterize the multiplier for grabbing the pointer index. Thanks again for the help!

Re “const byte *frames[8]”: you mean const byte (*frames)[8].

@EdgarBonet I have never seen that format before in my life. I actually meant frames[][8]. Is (*frames)[8] some newer C++ syntax that didn't exist when I was taught C at uni?

AFAIK, (*frames)[8] is ANSI C, maybe even K&R C.

Well, I have only ever come across brackets like that when working with function pointers.

@EdgarBonet I have been scouring the interwebs, and I have found exactly one example using that format, with no explanation of what it is or how it works. I found one that uses (*name)[X][Y], which claims to be passing a pointer to a 2D array, and that I can completely understand. I think (*name)[X] is passing a 2D array as a pointer to a 1D array. Valid, but kind of a hack. Nowhere seems to use it, all examples either being *name[] or **name, or name[][X]

You will find a couple of examples, with explanation, if you search for “C pointer to array” on stackoverflow. It's not a hack, it's standard syntax, albeit confusing enough for most people to avoid it. name[][X] is implicitly translated by the compiler into (*name)[X], but this translation is done only within function parameter declarations. See also How do I declare a pointer to an array? and How to pass a two-dimensional array in the C FAQ.

The error message is quite explicit:

argument of type "const byte (*)[8]" is incompatible with parameter
of type "const byte *"

If you want to pass SPACED_STRIPES to the method, it is going to be
passed as const byte (*)[8], i.e. pointer to arrays of 8 byte. You
can just set the parameter type accordingly:
void CSMatrix::runTwoColorPattern(
    const byte (*frames)[8], const int length, int delayDuration)
{
    // body unchanged
}

Thanks for this answer. I ended up going with the suggestion to simplify the array, but this answer helps me understand the error I was getting. I didn't realize I could write the method signature with the parens around the pointer.


text:
ESP32 sending data of type uint16_t(or anything except for uint8_t and char*) over bluetooth(classic) serial
I'm making a custom gamepad with an ESP32 and the joystick output is read by an ADC using uint16_t analogRead(uint8_t pin);. Now that I want to send the data and receive and parse it, I ran into a problem. The BluetoothSerial library I'm using only has this function for sending data:
size_t write(uint8_t c);

And the only other function I know of is this:
size_t Print::printf(const char *format, ...);

However, I don't want to convert the data to characters. Is there a way of sending integer/float/double etc bytes directly without converting them to characters?

Send it as two bytes?

How? I am not very familiar with this type of low level byte manipulation. I'll be glad if someone helped me out :)

@DaveNewton what's more, how do I distinguish the high and low bytes when they are received at the other end?

They'll be received in the order sent and can be shoved back together in whatever endian-ness is required. Splitting it up is masking and shifting, e.g., https://stackoverflow.com/questions/53367838/how-to-split-16-value-into-two-8-bit-values-in-c, https://forum.arduino.cc/t/changing-a-16bit-binary-number-into-two-8-bit-byte/44940, and so on.

@davenewton I have done just that(I searched for it and got the second forum post myself) and got it working with ~93% success rate. It seems that I have to allot a larger buffer than I'm sending or the success rate drops to 15-20%. And by larger buffer I mean at least 3 times larger. I'm sending 4 16-bit integers and I'm using two 0's for the beginning and the end, so I'm checking for that and the known largest ADC integer value after parsing. I also have to time it correctly or it doesn't work (10 ms delay). Is this common?

Without seeing any code it’s impossible to guess what might be happening.


text:
Prevent timeout while exchange data between two stm32
I am trying to exchange data (str data) between two STM32 throughout Lora connectivity. Both STM32 has a lora module and the connection between them is working fine. Based on two functions:
T_eError_eErrorType eDataPlane_eReceiveData_Cmd (uint32_t in_uiTimeout, uint8_t* out_pucData, uint8_t inout_pucLength, T_stSx1276_eRxPacketStatus out_pstRxPacketStatus)

T_eError_eErrorType eDataPlane_eSendData_Cmd (uint8_t* in_pucData, uint8_t in_ucLength)

I am trying to send and receive messages instantly. I discovered a huge problem: for example I am trying to send a data which has a duration equal to 300ms while the timeout of receiving the data is fixed to 3000 ms. It may, in one rare case, be a loss of such a data, when the data arrives at the time of 2800 ms of the timeout of the receiver. Such a problem is similar to the exchange of data in the UART interface when using the blocking mode (HAL_UART_Receive (&huart1, UART1_rxBuffer, 12, 5000);).
My question is how to garantee receiving the data without losing any byte and by using a receiving with timeout function.
Thanks in advance.


text:
Invalid use of void expression (how to use function pointer with input)
I'm defining an attachinterrupt and I'm running into an error. The line in question is:
void setup() {
   attachInterrupt(digitalPinToInterrupt(stallsense1), changedirection(1), RISING);
   attachInterrupt(digitalPinToInterrupt(stallsense2), changedirection(2), RISING);
}

and the error I'm getting is:
error: invalid use of void expression
attachInterrupt(digitalPinToInterrupt(stallsense2), changedirection(2), RISING);
                                                                                ^
exit status 1
invalid use of void expression

The idea is I have one function changedirection and two possible inputs, either 1 or 2.
I believe the issue is where I've called the function changedirection(1). I want to simply tell attachinterrupt to call the function changedirection with an input of either 1 or 2. How would I do this?

attachInterrupt expects a simple pointer to function taking no arguments and returning nothing (void).
So, really there's no way to directly do what you're talking about.  There's no currying ability builtin.  You can define your own functions like
void proxy_changedirection_1() {
    changedirection(1);
}

And then attachInterrupt specifying proxy_changedirection_1, or you can use a lambda with no captures for the same purpose:
attachInterrupt(
    digitalPinToInterrupt(stallsense1),
    [] () {
        changedirection(1);
    },
    RISING
);

Thank you very much. The lambda notation is closer to what I had envisioned coming from python.

What happened is you wrote a void expression where an expression of type 'pointer to function of void returning void' (i.e., no arguments and no return value), was expected. The name of a function with no parentheses for an argument list is an expression of type 'pointer to function' taking whatever arguments & types that named function was declared to expect, and returning whatever type that named function was declared to return.
But if you write the parentheses with it, now you've written an expression that 1) would (if it were valid) get evaluated during the call to attachInterrupt() - much earlier that you want it to be! - and return a value of that return type rather than the type you expected.
@timemage has offered two ways to solve this.


text:
Trying to use Serial to communicate between two D1 Mini's
I'm trying to connect two D1 Mini's together as a POC.
There is a switch on one and a 7 segment display on the other
I have the pins setup from TX>RX and RX>TX
First ESP8266:
int SWITCH_PIN = D5;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(SWITCH_PIN, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
}

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

  if(digitalRead(SWITCH_PIN) == HIGH)
  {
    Serial.println(1);
    digitalWrite(LED_BUILTIN, HIGH);
  }
  else
  {
    Serial.println(0);
    digitalWrite(LED_BUILTIN, LOW);
  }
}

Second ESP8266:
#include "DigitLedDisplay.h"
DigitLedDisplay ld = DigitLedDisplay(D6, D5, D0);

void setup() {

  Serial.begin(115200);

  ld.setBright(10);
  ld.setDigitLimit(8);

  for (long i = 0; i < 100; i++) {
    ld.printDigit(i);
    delay(25);
  }

}

void loop() {
  delay(1000);
  if(Serial.read() == 1)
  {
    ld.printDigit(11111111);
  }
  else if (Serial.read() == 0)
  {
    ld.printDigit(22222222);
  }
  else
  {
    ld.printDigit(33333333);
  }
}

As far as I can tell the second ESP8266 isn't getting anything from the first. What am I doing wrong?
Thanks in advance for the help

You forgot to ask a question.

updated with a questions now

Serial.println(1); sends '1', not 1, so use Serial.read() == '1'

Sigh...
Thanks for that
I actually get the correct data back sometimes, but the output seems to swap between correct and the "else" status constantly

Thanks to Juraj it was an easy fix
Missing quotes around the text and changing some code
void loop() {
  if (Serial.available() > 0)
  {
    // read the incoming byte:
    incomingByte = Serial.read();
  }
  if(incomingByte == '1')
  {
    ld.printDigit(11111111);
  }
  else if (incomingByte == '0')
  {
    ld.printDigit(22222222);
  }
}

adding "if (Serial.available() > 0)" works to make it only update when the serial buffer is full
The delay was also causing issues with where it was located so just removed that

this will ld.print every loop if incomingByte is '0' or '1'


text:
Maximum distance for sensor
I'm creating a project with some ESP32's running off PoE and I need to add some temperature/humidity sensors up to 5m away from the ESP chip
I assume there is a maximum cable distance?
What is the best way to overcome this distance, preferably without having to inject power or use WiFi?

What sensor do you have exactly?

I haven't picked one for this project yet, thought I should work out the limitations first

The limitations are defined by how the device communicates. How the device communicates is defined by what the device is. You need to look for a device that fits your criteria. FYI: digital is often more reliable over long distances than analogue, and different digital protocols have better long distance reliability than others.

Thinking about these
https://www.aliexpress.com/item/4000125526434.html?spm=a2g0o.productlist.0.0.18cf23fcVrprv3&algo_pvid=c1feb228-eb55-4733-8f4d-98797185eb30&algo_exp_id=c1feb228-eb55-4733-8f4d-98797185eb30-2

That could do the trick, although I don't know what exact type that is. Something with an I2C interface (like BMEXXX/BMPXXX) should work reasonably with 5m of cable. I would rather not try DHT11's.

Also, please frame your project.  For instance, if you are making 100s I2C temper sensors products, some will certainly not work over meters distance as I2C was designed to be used between chip on the same PCB.  Maybe in the same case.  For that matter, if you are willing to spend the money and convert I2C or enhance it with additional HW you can get many meters out of the physical layer.

FWIW SparkFun has an I2C extension system based on NXP's PCA9615.

I have successfully tested different I2C devices with 10m of cable. So it can work, but probably is not guaranteed to.

I would use an lm334 as a temp-dependent constant current source, then measure the voltage it produces on a fixed resistor with the ADC; cable length is then completely irrelevant to the equation (could be a mile) as series circuits have identical current at all node points. You could also use a PTC or NTC thermistor as a divider to feed a BJT's base as a very simple dynamic current source.


text:
A9G gsm module not displaying message body after receiving SMS
I am trying to receive an SMS on my arduino and print it out to the serial monitor. I am using the A9G gsm/gps module for doing that. Here is the code for it
#include <SoftwareSerial.h>

//Create software serial object to communicate with A6
SoftwareSerial mySerial(10, 11); //A6 Tx & Rx is connected to Arduino #3 & #2

void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(115200);

  //Begin serial communication with Arduino and A6
  mySerial.begin(115200);

  Serial.println("Initializing...");
  delay(1000);

  mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
  updateSerial();

  mySerial.println("AT+CMGF=1"); // Configuring TEXT mode
  updateSerial();
  mySerial.println("AT+CNMI=2,2,0,0,0"); // Decides how newly arrived SMS messages should be handled
  updateSerial();
}

void loop()
{
  updateSerial();
}

void updateSerial()
{
  delay(500);
  while (Serial.available())
  {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available())
  {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }
}

The code works and I get a response but the response does not include the body of the message. This is the response I got after sending "hello" to it;
CIEV: "MESSAGE",1
+CMT: "+233201729573",,"2021/06/18,12:20:03

As you can see it rightly sends me a notification but it does not include the "hello" which is the actual message I want to receive. Can anyone help me out?

I have sorted that out for sometime now. It turns out for some reason SerialSoftware was truncating my messages because the serial buffer size was too small. All I had to do was increase the buffer size to a higher number in the SoftwareSerial.h file and it worked.

Your serial reception code is much much much too primitive to be of any use.
You're waiting for 0.5 seconds for data to come in, which gets stored in a 64 byte buffer. Then you read out the contents of that 64 byte buffer.
Anything more than 64 bytes gets discarded.
You need to read the data actively as it comes in (NO delay()!) looking for specific things in the data (OK, ERROR, your text message response, etc) until the whole response from the modem has been received.

I recently jsut found out that I could change from 64 byte buffer to a much higher buffer. Which is what I did and now it works. However I am only able to do this on a windows pc and not from a linux system which is what I use.

Just to add up, after searching for the SoftwareSerial.h file and finding out its location and changing the serial buffer size, I am able to get it working on a linux system(ubuntu) now. Thanks.


text:
Arduino Mega as a EEPROM Programmer for Winbond W29EE011 memories
I'm trying to use my Arduino Mega as an EEPROM memory writer. For this project, besides my Arduino Mega, I use an SD Card module, an LCD display and two push buttons to handle the events. Inside the SD card I have the binary files to be written into the EEPROM.  Except for the burning process, my sketch seems to be correct. The user selects the memory size option (I'm only using the total memory size of 128kb), the file is written into the EEPROM. Apparently, the file is written. But when I use my other sketch to check the data written into the EEPROM, on the serial monitor, I only see bytes like FF and 0. Nothing else.
I think my problem is really in the process of writing the bytes, because of poor handling of the Output Enable, Chip Select and Write Enable pins. My data and address pin configuration, follows the logic of the Arduino Mega's port handling. PORT as the data pins and PORTC, PORTL and PORTG as the address pins. I will call the data pins dbit and the address pins abit, right? so, following this idea, my configuration with the Arduino Mega's ports looks like this:
Data pins:
dbit0 = 22,
dbit1 = 23,
dbit2 = 24,
dbit3 = 25,
dbit4 = 26,
dbit5 = 27,
dbit6 = 28,
dbit7 = 29.
Address pins:
abit0 = 37,
abit1 = 36,
abit2 = 35,
abit3 = 34,
abit4 = 33,
abit5 = 32,
abit6 = 31,
abit7 = 30,
abit8 = 49,
abit9 = 48,
abit10 = 47,
abit11 = 46,
abit12 = 45,
abit13 = 44,
abit14 = 43,
abit15 = 42,
abit16 = 41.
Here is the EEPROM writer code.(UPDATED)
  #include <avr/pgmspace.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

unsigned long addr = 0;

int oe = 9;
int cs = 10;
int we = 11;

unsigned long fileSize = 0;

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

pinMode(we, OUTPUT);
  pinMode(cs, OUTPUT);
  pinMode(oe, OUTPUT);
 digitalWrite(we, HIGH);
  digitalWrite(oe, HIGH);
  digitalWrite(cs, HIGH);
 DDRA = B11111111;
  PORTA = 0x00;

  DDRL = B11111111;
  PORTL = 0x00;

  DDRC = B11111111;
  PORTC = 0x00;

  DDRG = B11111111;
 PORTG = 0x00;

Serial.println("Now, erasing chip...");
DDRA = B11111111;
 delayMicroseconds(700);
 writeEEPROM(0x5555, 0xaa);
 writeEEPROM(0x2aaa, 0x55);
 writeEEPROM(0x5555, 0x80);
writeEEPROM(0x5555, 0xaa);
writeEEPROM(0x2aaa, 0x55);
writeEEPROM(0x5555, 0x10);
delayMicroseconds(50);

  delay(2500);

 Serial.println("All right! all done!");
    delay(2500);
     Serial.println("EEPROM Size will set to 0x2."); // just for test
 delay(2500);

PORTA = 0;
  PORTC = 0;
  PORTL = 0;
 PORTG = 0;

  }

  void loop(){

 dumpAndburn();
 while(1);// don't call this function anymore!!!!!!
  }// void loop

   void dumpAndburn(){

fileSize = 0x2; // just for test
  digitalWrite(oe, HIGH);
  digitalWrite(we, HIGH);

 while (addr < fileSize){/*

    https://www.dataman.com/dataman-eprom-memory-size-chart */

protect(); // is this right?
  writeEEPROM(addr, 0Xa5);// test
addr++;

}

  digitalWrite(oe, HIGH);
  digitalWrite(we, HIGH); //write disable
  digitalWrite(cs, HIGH);

  Serial.println("The process is done. Please, turn off the hardware.");

    }//void dumpAndburn

void writeEEPROM(int adr, byte values) {

  digitalWrite(oe, HIGH); // output disable
  delayMicroseconds(0.01);
  PORTA = values;  // this is the DATA
  //delayMicroseconds(0.05);
  PORTC = lowByte(adr); // lower byte of the address (first 8 bits)
  PORTL = highByte(adr); // upper byte of the address (only 5 bits are used, the address is a 13 bit number)
 PORTG = highByte(adr); // upper byte of the address (only 5 bits are used, the address is a 13 bit number)
  delayMicroseconds(0.05);
  digitalWrite(cs, LOW);  //  |CE goes LOW  // Chip enable
 delayMicroseconds(0.07);

   digitalWrite(we, LOW);  //  |WE goes LOW  // Write enable

  delayMicroseconds(0.07);
  digitalWrite(we, HIGH); //  |WE goes HIGH // Write disable
  delayMicroseconds(0.15);
  digitalWrite(cs, HIGH); //  |CE goes HIGH // Chip disable

}

void protect(){
  DDRA = B11111111; // set portA as outputs.
 delayMicroseconds(700);
   writeEEPROM (0x5555, 0xAA);
  writeEEPROM (0x2AAA, 0x55);
   writeEEPROM (0x5555, 0xA0);
    delayMicroseconds(10);

  }

Here is the EEPROM read code.
#include <avr/pgmspace.h> //necessário para Wire.h
#include <Wire.h>  //necessária, por conta do I2C
#include <SPI.h>

int oe = 9;
int cs = 10;
int we = 11;

void setup()
{

  int adr = 0;

pinMode(we, OUTPUT);
  pinMode(cs, OUTPUT);
  pinMode(oe, OUTPUT);
  digitalWrite(we, HIGH);
  digitalWrite(oe, HIGH);
  digitalWrite(cs, HIGH);
 DDRA = B00000000;
  PORTA = 0x00;

  DDRL = B00000000;
  PORTL = 0x00;

  DDRC = B00000000;
  PORTC = 0x00;

DDRG = B00000000;
PORTG = 0x00;

  Serial.begin(115200);
  for(int z=0; z<2; z++){
    delay(1000);
    }

printContents();
  }

  void loop(){

  }

byte readValue (int adr) {
  digitalWrite(we, HIGH); // disable write mode
  PORTC = lowByte(adr); // lower byte of the address (first 8 bits)
  PORTL = highByte(adr);// upper byte of the address (only 5 bits are used, the address is a 13 bit number)
 PORTG = highByte(adr);

  digitalWrite(oe, LOW);
  PORTA = 0;
  byte r = 0;

  delay(1); // we need a little delay to switch from input to output (at least 500 microseconds)
   digitalWrite(we, HIGH);
  digitalWrite(cs, LOW);
  //delayMicroseconds(0.09);
  digitalWrite(oe, LOW);
 // delayMicroseconds(0.045);

  // read the data
  r = PINA;
digitalWrite(we, HIGH);
  delayMicroseconds(1);
  digitalWrite(cs, HIGH);
  digitalWrite(oe, HIGH);
 // delayMicroseconds(0.09);
  return r;
}

void printContents() {
    DDRA = B00000000; //  portA as Inputs ports
  delayMicroseconds(500);
 int adr = 0;
byte value = 0;
byte checkValue;

//adr*=128;//test

while (adr < 0x2 ) { // 0x2 just for tests
    checkValue = readValue (adr);

Serial.print(adr, HEX); Serial.print(" : "),Serial.println(checkValue, HEX);
  adr++;
}

}

Here is the link to the memory datasheet.
link
And when I try to see the content, I get the following results:
0 : 0
1 : 0

why can't retrieve 0: A5 1: A5 ?
Please guys, help me.
Any help will be greatly appreciated.
Thank you.
Best wishes.

Timing is absolutely critical when writing that kind of EEPROM. Your serial prints will be breaking that timing, and you must think in 128 byte pages - load a page at the right speed then delay the right amount of time to trigger a write.

@Majenko , I really appreciate your comment. Thanks a lot! I think I will try to use a char buffer of 128, change the byte writing and see if I get any results.  Thank you very much for this important information.

@jsotola, I'm really sorry about this, but, I can't do it now. I'm going to my house. I need to do this with my notebook. Sorry. Thank you.

Dear friends, I have made an update to the code. I took out the serial printing of the bytes to be written. I based this on a Serial EEPROM design. I created a 128 byte buffer. But is my reasoning correct? because I still don't get the bytes that seem to be written into memory.

If you read the datasheet (page 6) carefully, you will see that "The W29EE011 is shipped with the software data protection enabled. To enable the software data protection scheme, perform the three-byte command cycle at the beginning of a page load cycle", what this means is that you need to write 0xAA to addr 0x5555, 0x55 -> 0x2AAA, and '0xA0->0x5555` before you write the address you want to access first.

BTW, you should format your code and shorten you code when post your question, if your problem is about EEPROM, all the codes about display, button are not relevant.

Thank you, Sir @hcheung, I will try to perform the byte command cycle.

Dear Friends. I have updated my code(and also formatted it). But I still have the same problems. What could I be doing wrong?


text:
Program an lcd display with 12 pins
I have a screen just like this (is the datasheet). My question is,
Can I use it to an Arduino board?

you probably can use it ... it is unknown what the user experience will be like ... you have not included a link to the actual datasheet

Can you tell me how, I don't know if exists any library for this type of screen. This is the only datasheet that I found. I tried to find more information's about it  and zero success.

first, you have to find a datasheet for the LCD control IC that is used in that display

Can be this ones ? https://imgur.com/a/e5DD9U4

The datasheet is here, it provided sufficient info to experiencing with. But it probably not worth the effort to write the library.


text:
I develop an earthquake detector but when it detects a movement, the alarm doesn't stop from ringing
This is the code that I used. Actually, I use to code: for Arduino sofware and processing IDE software.
Arduino Source Code/Program:
#include<LiquidCrystal.h> // lcd Header
LiquidCrystal lcd(7,6,5,4,3,2); // pins for LCD Connection

#define buzzer 12 // buzzer pin
#define led 13 //led pin

#define x A0 // x_out pin of Accelerometer
#define y A1 // y_out pin of Accelerometer
#define z A2 // z_out pin of Accelerometer

/*variables*/
int xsample=0;
int ysample=0;
int zsample=0;
long start;
int buz=0;

/*Macros*/
#define samples 50
#define maxVal 20 // max change limit
#define minVal -20 // min change limit
#define buzTime 5000 // buzzer on time

void setup()
{
    lcd.begin(16,2); //initializing lcd
    Serial.begin(9600); // initializing serial
    delay(1000);
    lcd.print("EarthQuake ");
    lcd.setCursor(0,1);
    lcd.print("Detector ");
    delay(2000);
    lcd.clear();
    lcd.print("Calibrating.....");
    lcd.setCursor(0,1);
    lcd.print("Please wait...");
    pinMode(buzzer, OUTPUT);
    pinMode(led, OUTPUT);
    buz=0;
    digitalWrite(buzzer, buz);
    digitalWrite(led, buz);
    for(int i=0;i<samples;i++) // taking samples for calibration
    {
        xsample+=analogRead(x);
        ysample+=analogRead(y);
        zsample+=analogRead(z);
    }

    xsample/=samples; // taking avg for x
    ysample/=samples; // taking avg for y
    zsample/=samples; // taking avg for z

    delay(3000);
    lcd.clear();
    lcd.print("Calibrated");
    delay(1000);
    lcd.clear();
    lcd.print("Device Ready");
    delay(1000);
    lcd.clear();
    lcd.print(" X Y Z ");
}

void loop()
{
    int value1=analogRead(x); // reading x out
    int value2=analogRead(y); //reading y out
    int value3=analogRead(z); //reading z out

    int xValue=xsample-value1; // finding change in x
    int yValue=ysample-value2; // finding change in y
    int zValue=zsample-value3; // finding change in z

    /*displying change in x,y and z axis values over lcd*/
    lcd.setCursor(0,1);
    lcd.print(xValue);
    lcd.setCursor(6,1);
    lcd.print(yValue);
    lcd.setCursor(12,1);
    lcd.print(zValue);
    delay(100);

    /* comparing change with predefined limits*/
    if(xValue < minVal || xValue > maxVal || yValue < minVal
            || yValue > maxVal || zValue < minVal || zValue > maxVal)
    {
        if(buz == 0)
            start=millis(); // timer start
        buz=1; // buzzer / led flag activated
    }
    else if(buz == 1) // buzzer flag activated then alerting earthquake
    {
        lcd.setCursor(0,0);
        lcd.print("Earthquake Alert ");
        if(millis()>= start+buzTime)
            buz=0;
    }
    else
    {
        lcd.clear();
        lcd.print(" X Y Z ");
    }

    digitalWrite(buzzer, buz); // buzzer on and off command
    digitalWrite(led, buz); // led on and off command

    /*sending values to processing for plot over the graph*/
    Serial.print("x=");
    Serial.println(xValue);
    Serial.print("y=");
    Serial.println(yValue);
    Serial.print("z=");
    Serial.println(zValue);
    Serial.println(" $");
}

Processing IDE Code/Program:
import processing.serial.*;
PFont f6,f8,f12,f10;
PFont f24;
Serial myPort; // The serial port
int xPos = 0; // horizontal position of the graph
float y1=0;
float y2=0;
float y3=0;

void setup ()
{
    // set the window size: and Font size
    f6 = createFont("Arial",6,true);
    f8 = createFont("Arial",8,true);
    f10 = createFont("Arial",10,true);
    f12 = createFont("Arial",12,true);
    f24 = createFont("Arial",24,true);
    size(1200, 700);

    // List all the available serial ports
    println(Serial.list());
    myPort = new Serial(this, "COM10", 9600);
    println(myPort);
    myPort.bufferUntil('\n');
    background(80);
}

void draw ()
{
    serial();
}

void serial()
{
    String inString = myPort.readStringUntil('$'); // reading incomming date from serial
    if (inString != null)
    {
        // extracting all required values of all three axis:
        int l1=inString.indexOf("x=")+2;
        String temp1=inString.substring(l1,l1+3);
        l1=inString.indexOf("y=")+2;
        String temp2=inString.substring(l1,l1+3);
        l1=inString.indexOf("z=")+2;
        String temp3=inString.substring(l1,l1+3);

        //mapping x, y and z value with graph dimensions
        float inByte1 = float(temp1+(char)9);
        inByte1 = map(inByte1, -80,80, 0, height-80);
        float inByte2 = float(temp2+(char)9);
        inByte2 = map(inByte2,-80,80, 0, height-80);
        float inByte3 = float(temp3+(char)9);
        inByte3 = map(inByte3,-80,80, 0, height-80);
        float x=map(xPos,0,1120,40,width-40);

        //ploting graph window, unit
        strokeWeight(2);
        stroke(175);
        Line(0,0,0,100);
        textFont(f24);
        fill(0,00,255);
        textAlign(RIGHT);
        xmargin("EarthQuake Graph (SESMIOGRAPH)",200,100);

        fill(100);
        strokeWeight(100);
        line(1050,80,1200,80);

        strokeWeight(1);
        textAlign(RIGHT);
        fill(0,0,255);
        String temp="X:"+temp1;
        Text(temp,100,95);

        fill(0,255,0);
        temp="Y:"+temp2;
        Text(temp,100,92);

        fill(255,0,0);;
        temp="Z:"+temp3;
        Text(temp,100,89);

        //ploting x y and z values over graph
        strokeWeight(2);
        int shift=40;

        stroke(0,0,255);
        if(y1 == 0)
            y1=height-inByte1-shift;
        line(x, y1, x+2, height-inByte1-shift) ;
        y1=height-inByte1-shift;

        stroke(0,255,0);
        if(y2 == 0)
            y2=height-inByte2-shift;
        line(x, y2, x+2, height-inByte2-shift) ;
        y2=height-inByte2-shift;

        stroke(255,0,0);
        if(y2 == 0)
            y3=height-inByte3-shift;
        line(x, y3, x+2, height-inByte3-shift) ;
        y3=height-inByte3-shift;

        xPos+=1;

        if (x >= width-30) // go back to begining
        {
            xPos = 0;
            background(80);
        }
    }
}

void Line(int x1, int y1, int x2, int y2)
{
    float xx1=map(x1,0,100,40,width-40);
    float xx2=map(x2,0,100,40,width-40);
    float yy1=map(y1,0,100,height-40,40);
    float yy2=map(y2,0,100,height-40,40);

    line(xx1,yy1,xx2,yy2);
    xx2=map(100,0,100,40,width-40);
    yy2=map(0,0,100,height-40,40);
    line(xx1,yy1,xx2,yy2);

    strokeWeight(1);
    for(int i=1;i<21;i++)
    {
        yy2=map(i*10,0,200,height-40,40);
        yy1=yy2;
        line(xx1,yy1,xx2,yy2);
    }
    yy2=map(100,0,100,height-40,40);
    yy1=map(0,0,100,height-40,40);
    for(int i=1;i<41;i++)
    {
        xx1=map(i*5,0,200,40,width-40);
        xx2=map(i*5,0,200,40,width-40);
        line(xx1,yy1,xx2,yy2);
    }

    textAlign(RIGHT); // 100 degree
    // result+=yy1;
    fill(255);
    strokeWeight(1);
    textFont(f12);
    for(int i=-10;i<11;i++)
    {
        String result="";
        result+=5*i;
        ymargin(result, x1,y1);
        y1+=5;
    }

    x1=0;
    y1=0;
    strokeWeight(1);
    textFont(f10);
    for(int i=0;i<41;i++)
    {
        String result="";
        result+=28*3*i;
        xmargin(result, x1,y1);
        x1+=5;
    }

    textAlign(RIGHT);
    textAlign(RIGHT);
}

void ymargin(String value, int x1, int y1)
{
    float xx1=map(x1,0,100,40,width-40);
    float yy1=map(y1,0,100,height-40,40);
    text(value,xx1-5,yy1+5);
}

void xmargin(String value, int x1, int y1)
{
    float xx1=map(x1,0,200,40,width-40);
    float yy1=map(y1,0,100,height-25,25);
    text(value,xx1+7,yy1);
}

void Text(String value, int x1, int y1)
{
    float xx1=map(x1,0,100,40,width-40);
    float yy1=map(y1,0,100,height-25,25);
    text(value,xx1,yy1);
}

I cannot see anything in your code that could be a cause for this
behavior. So maybe the cause is outside the code.
How do you simulate an earthquake? I guess you manually move the sensor
somehow. It may well happen that, after moving it, it doesn't settle in
exactly the same orientation it was before. When this happens, the
acceleration of gravity will be in a slightly different direction, and
your calibration will not be valid anymore. You can check for this
condition by watching the displayed values: if they settle to something
almost constant but large (more than 20 in absolute value), then that is
what is happening.
If this is the case, a possible solution would be to redo the
calibration a couple of seconds after detecting an earthquake. I would
suggest a technique that is, in my view, more elegant: calibrate
continuously, i.e. update the calibration every few microseconds.
The idea is that, instead of computing a set of offsets once and for
all, you low-pass-filter the raw readings and use these smoothed
readings as offsets. When you subtract the offsets from the readings,
you are implementing in essence a high-pass filter.
Here is a tentative implementation of this idea. I made the readings
periodic in order to have some control on the time constant of the
filter. In practice, you would have to adapt the time constant to the
requirements of your experiment:
// Constants to be adjusted, times are in microseconds.
const uint32_t readingPeriod   = 10e3;  // 10e3 us = 10 ms
const float filterTimeConstant = 10e6;  // 10e6 us = 10 s
const float filterConstant = readingPeriod / filterTimeConstant;

// Periodically updated filtered accelerations.
float accelX, accelY, accelZ;

// Internal state of the filter.
uint32_t lastTimeReading = 0;
float offsetX, offsetY, offsetZ;

// Call this from setup()
void initializeOffsets() {
    offsetX = analogRead(x);
    offsetY = analogRead(y);
    offsetZ = analogRead(z);
}

// Call this from loop()
void updateAccelerations() {
    // Take the readings only every readingPeriod us.
    if (micros() - lastTimeReading < readingPeriod)
        return;
    lastTimeReading += readingPeriod;

    // Read the sensors.
    int readingX = analogRead(x);
    int readingY = analogRead(y);
    int readingZ = analogRead(z);

    // Update the offsets.
    offsetX += filterConstant * (readingX - offsetX);
    offsetY += filterConstant * (readingY - offsetY);
    offsetZ += filterConstant * (readingZ - offsetZ);

    // Update the filtered accelerations.
    accelX = readingX - offsetX;
    accelY = readingY - offsetY;
    accelZ = readingZ - offsetZ;
}

Thank you so much. I will try your suggestion.

What part of my code should I put your code?

@ChristianMarasigan: It's written in the comments. Please don't just copy-paste this without understanding at least the general principle. Look at the comments. If something does not make sense, ask.

I would convert the outputs to Integers from Double and see if it's still 'ringing'.
The description suggests it is creating a feedback loop (critically damped) and you have to set a lower limit of those values that also shut the device down.
So, if you are currently reading precision of < 0.00001 ( in any axis) add a break in the program.
Big old guess but good luck.

Thank you. I will try it.

Just a guess, but is the vibration from the buzzer sufficiently strong to trigger the accelerometer? If so, once the buzzer sounds after detecting an earthquake, it might just keep triggering itself.
To fix this, you probably need to take some sample accelerometer readings to see how strong the buzzer vibrations are compared to the signal from an earthquake. You could then look to change your calibration or try to filter out the signal from the buzzer.
Alternatively, you might need to physically isolate the buzzer from the accelerometer.


text:
ESP8266-01 module "AT" command testing not responding
Firstly I have connected the Arduino UNo to Esp8266-01 Module and uploaded the Simple Blink Sketch using Arduino Uno and It responded correctly as in the Blue Led Light on Esp8266-01 was blinking correctly. Now for AT Commands I uploaded Blank Sketch to Arduino Uno and then on serial monitor with baud rate as 115200 typed in AT but no output is seen on Serial Monitor , Please Help Why Esp8266-01 Module not responding to AT Commands

the sketch replaced the AT firmware

When using it as a WiFi modem, you communicate with it using AT-command, and by default that is what most of ESP8266 module does, it shipped with At-command firmware. When you using an ESP8266 as an MCU, you flash the ESP8266 with Arduino sketch, which overrides the AT-Command firmware and upload it with Arduino bootloader, and allow the ESP8266 to be used as a stand-alone MCU like an Arduino.

The "AT" commands are provided by a specific sketch (firmware). The chip can only hold one sketch at a time - that sketch currently is your "blink" sketch.
If you want to have AT commands then you have to put the correct AT command firmware on the chip, removing your Blink sketch in the process.


text:
What happens if Millis() method variable goes out of it's capacity?
I am now working on a project which is expected to last at least 5 years from the time it is completed. In that project, i can not use delay() for some purposes so I am using millis() method
unsigned long Then = 0;
unsigned long Threshold = 1000;

void setup(){
    // Codes
}

void loop(){
    unsigned long Now = millis();
    if(Now-Then>=Threshold){
        // Execute a function or functions
        Then = Now;
    }
}

Now in this code wee can see the variable 'Then' and 'Now' are getting updated whenever threshold is met.
So now, suppose after a certain period of time (without any switch off), if any one of the two ever-updating variables which are 'Now' or 'Then' gets a value which is out of range for 'unsigned long' type
Will the ic continue to behave normally or will it malfunction?
Thank you!

let say millis() rolled over to 5 and the last count was 12345678: (5-12345678) > 1000; no problem.

In the unsigned arithmetics it results into distance between those two numbers, so it'll be fine. (negative numbers are stored in two's complement)

Well I don't care about rollovers or overflows until my system starts malfunctioning.


text:
Eleminate noise from a Relay in ArduinoFFT
I have built a circuit with an Arduino Nano to measure frequency from my music, it's basically this schema but I changed the code a little bit to fit my needs.
My problem is I want to add a Relay (I have an arduino single relay module) to the circuit and when I connect the signal on my 5v, it create a lot of noise in the frequency I get from ArduinoFFT.
What my code is doing is getting an average of the frequency to detect if music is currently playing. Here is a sample of data I get when there is no music playing:
2 2 2 4 1 0 0: 1
2 2 4 1 0 0 1: 1
4 4 1 0 0 1 0: 1
1 1 0 0 1 0 4: 1
0 0 0 1 0 4 1: 1
0 0 1 0 4 1 5: 1
1 1 0 4 1 5 3: 2
0 0 4 1 5 3 2: 2
4 4 1 5 3 2 0: 2
1 1 5 3 2 0 0: 1

Here, this is with music (good old rock :) ):
16 16 22 17 20 21 29: 20
22 22 17 20 21 29 28: 22
17 17 20 21 29 28 22: 22
20 20 21 29 28 22 25: 24
21 21 29 28 22 25 28: 25
29 29 28 22 25 28 27: 26
28 28 22 25 28 27 32: 27
22 22 25 28 27 32 27: 26
25 25 28 27 32 27 29: 28
28 28 27 32 27 29 23: 27

And finaly when I connect the relay (with arduino digital pin or if I jump it with the 5v, it the same result):
5 5 5 6 4 4 7: 5
5 5 6 4 4 7 5: 5
6 6 4 4 7 5 4: 5
4 4 4 7 5 4 4: 4
4 4 7 5 4 4 5: 4
7 7 5 4 4 5 4: 4
5 5 4 4 5 4 4: 4
4 4 4 5 4 4 4: 4
4 4 5 4 4 4 6: 4
5 5 4 4 4 6 4: 4

The problem with this is that when I'm playing smooth music, the numbers are not that high, it's basically the same as when the relay is on.
Here is a schema of what I did, it's my first try, let me know if anything is not fine with it.

simulate this circuit – Schematic created using CircuitLab

How are you trying to connect this relay and can you show us the noise you get?

Separate the relay power from Arduino, if that not what you want, we can only guessing because you didn't provide much info for troubleshooting.

I added more details on the data I have and a picture of my setup.

Please consider a schematic; it’s difficult to see what’s going on here.

@DaveNewton, here it is, it's my first attempt to create a schema so, I hope everything is fine with it ;)

what are you switching with the relay? If it's DC, I would use a MOSFET instead.

@dandavis, no, it's AC.


text:
Touch Sensor and Potentiometer - Need some help
I'm using an Arduino Nano with a capacitive touch sensor and a potentiometer. I'm trying to get my code to differentiate between three different program states.

One is when my touch sensor is NOT being touched.
Two is when my touch sensor IS being touched.
And three is when my touch sensor is being touched AND a potentiometer is being moved at the same time.

I'm having trouble picking up the second program state, when I'm simply touching the fader but not moving the potentiometer. Program state 1 works great, but program state 3 activates even when there's no data coming in from the potentioeter.
Here's the code. And ideas?
#include <CapacitiveSensor.h>
#define rxPin 4
#define txPin 1

const byte touchSend = 2;
const byte touchReceive = 7;

byte minimumCp = 200; // Raise if the fader is too sensitive (0-16383)

bool touched = false; //Is the fader currently being touched?

CapacitiveSensor touchSensor = CapacitiveSensor(touchReceive, touchSend);

void setup() {
  touchSensor.set_CS_AutocaL_Millis(0xFFFFFFFF);
  pinMode(rxPin, INPUT );
  pinMode(txPin, OUTPUT);
  Serial.begin(57600);
}
void loop() {
  int faderPos = analogRead(A7);
  int lastfaderValue;
  int totalCp =  touchSensor.capacitiveSensor(30);
  if (totalCp <= minimumCp) {  // Not Touching Fader
      touched = false;
      Serial.println("Not Touching Fader");
      delay(15);}
  if ((faderPos == lastfaderValue) && (totalCp > minimumCp)) { // Touching Fader
      touched = true;
      Serial.println("Touching Fader, NOT Moving");
      delay(15);}
  if ((faderPos != lastfaderValue) && (totalCp > minimumCp)) { // Touching Fader and Moving
      touched = true;
      Serial.println("Touching Fader, Moving");
      delay(15);}
  lastfaderValue = faderPos; }

Your lastfaderValue is always equal to faderPos.

Every time you enter loop you’re comparing the pot input with an arbitrary value that you think is the last pot value, but since it’s local to loop, it isn’t. You may have not intended that to be a local variable. I’d add that you’ll probably want a minimum pot delta as well since simultaneous reads may not report the same value even if it’s not being moved.

Figured it out.
I had the lastfaderValue integer in the wrong spot. It works when I put it at the beginning of the code (before the setup).
I also added a tolerance, so that the potentiometer can still fluctuate slightly when I'm not touching it.
Works well now.


text:
Motor response is lagging
I've got a DC motor connected to an Arduino Nano, L298N H-Bridge and a 12v Power supply. I'm trying to make it respond to incoming MIDI data a bit quicker. Right now, it seems awfully slow, and lags in response to quick value changes. I'm using MIDI to send data into my Arduino, so my baud rate is limited to 31250.
The issue is mainly with my DAW (Ableton), as my motor responds quickly when I try to control it with a fader on my MIDI keyboard.
Note: I'm also using a potentiometer and a capacitive touch sensor in this code. I'll try to simplify it as much as I can so I can isolate the issue
Here's the code:
#include <SoftwareSerial.h> // MIDI Input
#include <CapacitiveSensor.h>
#include <MIDI.h> // MIDI Output
#define txPin 1
#define rxPin 4

SoftwareSerial midiSerial (rxPin, txPin);

const byte touchSend    = 2;//Send pin for Capacitance Sensing Circuit (Digital 7)
const byte motorPWM     = 3;
const byte motorDown    = 5;
const byte motorUp      = 6;
const byte touchReceive = 7; //Receive pin for Capacitance Sensing Circuit (Digital 8)
const byte wiper        = 7; //Position of fader relative to GND (Analog 0)

int incomingCommand;
int incomingNote;
int incomingVelocity;
byte motorSpeed = 75; // Raise if the fader is too slow (0-255)
byte minimumCp  = 200; // Raise if the fader is too sensitive (0-16383)
byte tolerance  = 10; // Raise if the fader is too shaky (0-1023)
double faderMax = 0; //Value read by fader's maximum position (0-1023)
double faderMin = 0; //Value read by fader's minimum position (0-1023)
bool touched = false; //Is the fader currently being touched?
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay    = 10;    // the debounce time; increase if the output flickers
int lastfaderValue    = 0;

byte ch1Vol = 224;
byte fullVel = 127;
byte ch_1 = 1;
byte Db_1 = 1;

CapacitiveSensor touch = CapacitiveSensor(touchReceive, touchSend);
MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  touch.set_CS_AutocaL_Millis(0xFFFFFFFF);
  midiSerial.begin(31250);
  MIDI.begin(MIDI_CHANNEL_OMNI);
  while (!Serial);
  pinMode(motorDown, OUTPUT);
  pinMode(motorUp, OUTPUT);
  pinMode(motorPWM, OUTPUT);
  pinMode(rxPin, INPUT );
  pinMode(txPin, OUTPUT);
  analogWrite(motorPWM, motorSpeed);
  calibrateFader(); }

void calibrateFader() {
  digitalWrite(motorUp, HIGH);
  analogWrite(motorPWM, 100);
  delay(300);
  digitalWrite(motorUp, LOW);
  faderMax = analogRead(wiper) - tolerance;
  digitalWrite(motorDown, HIGH);
  analogWrite(motorPWM, 100);
  delay(300);
  digitalWrite(motorDown, LOW);
  faderMin = analogRead(wiper) + tolerance; }

void loop() {
  int faderPos = analogRead(wiper);
  int faderMIDI = faderPos / 8;
  int faderHiResMIDI = ((faderPos *16) - 8191);
  while ( midiSerial.available() > 0 ) {
    int commandByte = midiSerial.read();
    int noteByte = midiSerial.read();
    byte velocityByte = midiSerial.read();
    midiSerial.write( commandByte);
    midiSerial.write( noteByte);
    midiSerial.write( velocityByte);
    incomingCommand = commandByte;
    incomingNote = noteByte;
    incomingVelocity = velocityByte*8; }

 { int totalCp =  touch.capacitiveSensor(30);
 if ( (millis() - lastDebounceTime) > debounceDelay) {
    if (totalCp <= minimumCp) { touched = false; // Not Touching Fader
      if (incomingCommand == ch1Vol) { updateFader(incomingVelocity); } }
    if ((faderPos == lastfaderValue) && (totalCp > minimumCp)) { touched = true; // Touching Fader
      MIDI.sendNoteOn(Db_1, fullVel, ch_1);
      digitalWrite(motorDown, LOW);
      digitalWrite(motorUp, LOW); }
    if (((faderPos > lastfaderValue+1) or (faderPos < lastfaderValue-1)) && (totalCp > minimumCp)) { touched = true; // Moving Fader
      MIDI.sendPitchBend(faderHiResMIDI, ch_1);
      digitalWrite(motorDown, LOW);
      digitalWrite(motorUp, LOW); }
    lastfaderValue = faderPos;
    lastDebounceTime = millis(); //set the current time
} } }

void updateFader(int position) {     //Function to move fader to a specific position between 0-1023 if it's not already there
  if (position < analogRead(wiper) - tolerance && position > faderMin && !touched) {
    digitalWrite(motorDown, HIGH);
    while (position < analogRead(wiper) - tolerance && !touched) {}; //Loops until motor is done moving
    digitalWrite(motorDown, LOW); }
  else if (position > analogRead(wiper) + tolerance && position < faderMax && !touched) {
    digitalWrite(motorUp, HIGH);
    while (position > analogRead(wiper) + tolerance && !touched) {}; //Loops until motor is done moving
    digitalWrite(motorUp, LOW); } }

It probably because those while() {} (wait until...) codes that are blocking.

About what lack are we talking here exactly? Is it the delay between sending a command and the fader starting to move? Or is it the fader not reacting directly when it already received a command? From your code the former should be rather short (a bit more than 10ms I think), while the latter will be a bit greater than the time that the motor needs to drive the fader to its previously commanded position (because of the while loop).

There's a fundamental flaw in your serial reading code. Read: https://majenko.co.uk/blog/reading-serial-arduino

Good point. @zRockafellow You are checking for more than zero bytes being available, but then you read 3 bytes. You cannot be sure, that all these bytes where already received. Maybe just check for 3 bytes being available

I tried replacing the while() codes with if, but I found that the motor stopped responding to data completely. I'll try rewriting that section without any while loops.

@Majenko I changed the '0' to a '2' in the Serial reading code. This made my motor move a tiny bit after receiving data, and stop responding completely. Change the '2' back to '0' & I can move the motor freely again.

@chrisl The fader's not reacting directly when it receives a command. It's receiving a number between 0 and 127, and if I have any quick movements, the data coming into serial skips quite a bit of information to get to the new value, which makes my motor jump around as well

I'm wondering if simply getting a faster processor would do it? I'll try running this same code, but instead of using an Arduino Nano, I'll use a Mega. Or perhaps it's time to get a teensy

You have to just read the serial properly. Read one byte (the command byte) then use that to determine how many other bytes should be read, then read those in one at a time as they arrive. Only once all the bytes for a command have arrived do you act on it.

your code shows unclear thinking ... for instance, every if statement in updateFader contains && !touched ... just test that first on its own .... actually, you don't even have to test it because of touched = false; just before updateFader is called

I took out the boolean 'touched' part of the code entirely - Didn't make a difference to the functionality, but thanks for pointing that out. The motor still runs smoothest when I use the code "Serial.available > '0'". I've tried every combination of the number 0-3, and that one is definitely the smoothest

@Majenko, I'm not sure I understand what you mean. If it works best when reading the Serial as is, is that still not the proper way?


text:
Arduino MPU error
This is my code -
// Basic demo for accelerometer readings from Adafruit MPU6050

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>

Adafruit_MPU6050 mpu;

void setup(void) {
  Serial.begin(115200);
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit MPU6050 test!");

  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  Serial.print("Accelerometer range set to: ");
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    Serial.println("+-2G");
    break;
  case MPU6050_RANGE_4_G:
    Serial.println("+-4G");
    break;
  case MPU6050_RANGE_8_G:
    Serial.println("+-8G");
    break;
  case MPU6050_RANGE_16_G:
    Serial.println("+-16G");
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  Serial.print("Gyro range set to: ");
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    Serial.println("+- 250 deg/s");
    break;
  case MPU6050_RANGE_500_DEG:
    Serial.println("+- 500 deg/s");
    break;
  case MPU6050_RANGE_1000_DEG:
    Serial.println("+- 1000 deg/s");
    break;
  case MPU6050_RANGE_2000_DEG:
    Serial.println("+- 2000 deg/s");
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }

  Serial.println("");
  delay(100);
}

void loop() {

  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* Print out the values */
  Serial.print("Acceleration X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");

  Serial.print("Rotation X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);
  Serial.print(", Z: ");
  Serial.print(g.gyro.z);
  Serial.println(" rad/s");

  Serial.print("Temperature: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");

  Serial.println("");
  delay(500);
}

and this is my error-
Adafruit MPU6050 test!
Failed to find MPU6050 chip
Adafruit MPU6050 test!
Failed to find MPU6050 chip

wires are connected properly

Please try the I2C Scanner sketch. That will show you if any device is found on the bus and which address it has. When I remember correctly the MPU6050 also has address pins to change the address. Maybe your MPU has a different address, than the library uses by default (seems to be 0x68 according to the library code on github)

If I had a nickel for every time I thought the wires were connected properly...

the address is 0x68 I checked it

Knowing the address, there's not a lot in the begin() function that can make it fail that isn't ultimately a wiring problem.  Determining (e.g. via Serial.println) which of these return statements is being executed may be of some use.

Have you checked with the I2C scanner sketch? You didn't specify that. I mentioned that sketch because it also confirms, that the I2C bus is working. And please share a schematic of your wiring

hey @timemage
https://jpst.it/2xPxh
This code is working but I want to use the other code, if it was a wiring problem then the code I mentioned now wouldn't work right? that's why I said the wiring is correct.                                                                                by the way, thank yout for helping me I really appreciate it.

hi @chrisl I checked with the i2c scanner the and it says the address is 0x68, by the way, thank you for helping me I really appreciate it.

I haven't looked at your other code and probably won't for a while.  But in short, no.  In particular the speed of the bus is under control of code and crappier wiring (the bus lines themselves and pullup resistors) support slower speeds.

Mhh, your code is just the basic_readings example from the Adafruit_MPU6050 library, so I would think that it is correct (the library is used by so many others without problems, so I don't think the library is at fault here). For me that doesn't leave much to analyze here. At that point I would normally check the wiring (and try pullup resistors like 4.7kOhm on the I2C lines, if not already done). I now that it worked with your other code, which is not using the library, but I cannot thing of anything else here.

If you have a logic analyzer (great tool, really cheap as USB device, like 10 bucks) you can monitor the I2C lines and look, what actually gets send and responded on the bus.


text:
How can the SAMD21 chip knows when the on-board NINA W102 restarts
I am building a project that requires the SAMD21 microcontroller to send a resetToFactory signal to the NINA W102 on Arduino Nano 33 IoT. My plan is that, once the W102 receives the signal will do NVS formatting and restart itself, and then I need the SAMD21 to restart afterward by an event triggering from the W102(W102 needs to finish the restart cycle first), see the figure.

The communication protocol is SPI as the WIFININA lib does.
I have few attempts by trying to read the GPIO voltage from W102, however, it doesn't work because SPI on SAMD21 side will just hang until the W102 finished the restart even though I remove the waitForSlaveReady() for receiving the reply, so I can't get any event triggering.
By the way, I can't simply use the RESET_N because the program won't know to do the NVS formatting first.
Does anyone have related experience or ideas? Thank you very much.
Best regards,
Edwin Lu

I have solved this later I post the question.
The solution is using the fact which SPI on the SAMD21 will hang while W102 restarts, so I just set the SAMD21 restart immediately after the program continues.
Best regards,
Edwin Lu


text:
12V Relay not clicking
Trying to power the 12V relay from an Arduino to make an automatic cocktail maker.  Looking to power 12V water pumps off of the relay.  However, the relay is not clicking, only getting the light.
The connections FROM the Arduino TO the relay is as follows:

Arduino
Relay

5V
VCC

GND
GND

pin 3
IN1

Also pictures of circuit are provided. The Arduino is powered by USB laptop.

Have you set pin 3 to be an output?

What kind of relay or relay module are you using?

12V relay controlled by 5V arduino? You need a 5V relay or 12V supply for relay.

True, if you already connected the relay to pin 3, just test if the pin is still working as it might have drawn too much current, you should use a 5v relay or a 12 volt power source with a transistor.

The O.P. had intended to include more than the one image, but their markdown had been mangled.  Corrected, you can see this answers the pinMode question by Majenko and gives at least some degree of answer for StarCat.

@SBF, the relay board image that wasn't rendering in the original post confirms for you.

The digitalWrite() commands in your code use “quoted” values (such as “LOW” and “HIGH”) for the second operand. I dont’t think that will work correctly. Try to use the conventional LOW and HIGH. For example digitalWrite(relay, HiGH).

Please see why we shouldn't post images of text :)

After search the internet,
i believe the 12v relay need 12v to click.
You may check these :
https://handtoolsforfun.com/how-to-connect-a-12v-relay-board-to-arduino/
https://www.instructables.com/Connecting-a-12V-Relay-to-Arduino/

The problem is, we have no idea which relay board is used. The first link you point to whoes a relay board that looks like the one in the question but then goes on to explain nothing about that boards’ particulars. It even shows a relay controlled by a transistor, without the optical isolators that are clearly on the board. However, I think these relay boards do need a +12V connection.


text:
Can an MCP2515 CANBUS controller be used for two-way communication?
I tried searching code for an MCP2515 with Arduino on Arduino Forums, Instructables, Electronics Hub, YouTube, etc.
All of them showed code for a transmitter node and a receiver node, sensors on one node, and result on the other end.
Can we connect two Arduinos using an MCP2515 and communicate TWO WAY?

I never used CAN bus myself, but what you could do is one of the following:

Letting the transmitter send a specific (short) message to the receiver. In case the receiver has something to transmit, it sends a specific reply back, so the transmitter can request the receiver to send the actual message to be sent. The disadvantage is that polling is needed.
If you want the receiver to be able to send its message as fast as possible, add a separate wire next to the CAN bus communication. If that line is LOW or HIGH (decide yourself), then the transmitter can 'immediately' send a message to have the receiver send its actual message.

Thanks! Tx Arduino runs only tx code, and Rx Arduino runs only rx code. So, it's not possible for Rx to transmit anything back. And, using CAN is for reducing no. of wires used, but that's a nice idea.

By your first point, I'll try to merge the tx & rx commands, and temporarily make TX Arduino receive data, and vice versa.

Let us know how you do!

Per the Bosch specification, which is readily available,  The CAN bus does arbitration automatically by a defined priority on a bit by bit basis. To send a message with the MPC2515 you load it and when the bus becomes available it will transmit it, if there is an error it will retry many times (internal counter) and if it fails you will know. When a message is sent it must receive an ACK in a specified part of the can frame. This can be generated by any node. Your internal protocol needs to determine if the right node got the message.

---Yes---
It should work nicely. They operate only in simplex mode (sending or receiving) to the outside world. Internally they also monitor what they are sending for error checking etc. From the user point they would appear to be bidirectional because they can switch between send and receive messages rapidly, message by message. Of course the bus speed helps. You can get upto 1 Meg with these. I use Cory Fowler's "mcp_can.h". You can get it at: "https://github.com/coryjfowler/MCP_CAN_lib". The library has both send and receive .ino files, get them to work first.  Since CAN is priority Based NDA Non Destructive Arbitration the higher priority message will prevail regardless of who else is on the bus or is sending a message.
Do not forget to put jumpers on the module to terminate the bus. Note the bus gets terminated only at the physical ends. The bus design impedance is 60 Ohm, the termination resistors are 120 ohms.
You simply combine the send and receive sections of code in your module, nothing special to do. You initialize both send and receive at the same time with basically the same information.  You will find the information for this in the setup() section of the code. Be sure to check crystal frequencies, I have seen both 8 and 16 Mhz crystals on these boards.
Per the Bosch specification, which is readily available,  The CAN bus does arbitration automatically by a defined priority on a bit by bit basis. To send a message with the MPC2515 you load it and when the bus becomes available it will transmit it, if there is an error it will retry many times (internal counter) and if it fails you will know. When a message is sent it must receive an ACK in a specified part of the can frame. This can be generated by any node. Your internal protocol needs to determine if the right node got the message.
By the time your external logic can determine it wants to send a message and send a signal it will have already been sent in a standard CAN setup. Any number of modules can start transmitting but the arbitration will weed them out and the highest priority message will get through. Every node will receive every message, depending on its filtering etc it may accept it or ignore it. You can pole or take an interrupt any time it receives a message etc.