text:
DC motor and buzzer blink without delay code
So I am trying to put together a code for 4dc motors, buzzer, ultrasonic and lcd to work together,. they will together make up a small car. when the distance to the ultrasonic is smaller than 10cm, the buzzer makes a random sound, and a funny face. Meanwhile the motors will stop for 2 seconds, goes back for 2 seconds and do a turning motion for 8 seconds. However. I do not want to use the delay function for the motors since it will cause the buzzer to sound too slowly. I know I need to do a blink without delay code, I am trying to implement this but am having trouble right now: the motors will stop when I put in the motor stop function, but it will not go backwards.. I know there are some timing issues but how can I fix this?
please see attached the code and wiring diagram.
Thank you sooo much !!!!
#include <LiquidCrystal.h>
#include <NewTone.h>

#include<AFMotor.h>
#define trigPin A1
#define echoPin A0

AF_DCMotor motor1(1,MOTOR34_1KHZ);
AF_DCMotor motor2(2,MOTOR34_1KHZ);
AF_DCMotor motor3(3,MOTOR34_1KHZ);
AF_DCMotor motor4(4,MOTOR34_1KHZ);

LiquidCrystal lcd(8, 9, 4, 7, 12, 13);

int buzzerPin = A2;
int notes[] = {262};
int dur = 100;
int maximum = 100;
long duration;
int distance;
int distanceUltra;
unsigned long previousBuzzerMillis = 0;
unsigned long previousDCStopMillis = 0;
unsigned long previousDCBackMillis = 0;
unsigned long currentMillis = 0;
const unsigned long DCStopInterval =2000;
const unsigned long DCBackInterval =2000;

byte a[]={
  B10001,
  B10001,
  B10101,
  B10101,
  B01010,
  B00000,
  B00000,
  B00000
  };

byte b[]={
  B00000,
  B00010,
  B00100,
  B01000,
  B01000,
  B01000,
  B01000,
  B01000
  };

byte c[]={
  B00000,
  B01000,
  B01000,
  B01000,
  B01000,
  B01000,
  B00100,
  B00010
  };

byte h[]={
  B00000,
  B01000,
  B00100,
  B00010,
  B00010,
  B00010,
  B00010,
  B00010
  };

void setup() {

  Serial.begin(9600);
  lcd.begin(16,2);
  pinMode (trigPin, OUTPUT);
  pinMode (echoPin, INPUT);
  lcd.createChar(0,a);
  lcd.createChar(1,b);
  lcd.createChar(2,h);
  lcd.createChar(3,c);

  pinMode(buzzerPin, OUTPUT);
  }

void loop() {

  currentMillis = millis();
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  distance = duration*0.034/2;

  Serial.print("distance:");
  Serial.println(distance);

  lcd.clear();
currentMillis = millis();

  if (distance <= 10){

    stopDCMotorStop();
    //stopDCMotorBack();

    }

  else{
    motor1.setSpeed(100);
    motor1.run(BACKWARD);
    motor2.setSpeed(100);
    motor2.run(BACKWARD);
    motor3.setSpeed(100);
    motor3.run(BACKWARD);
    motor4.setSpeed(100);
    motor4.run(BACKWARD);
      }

  if (distance <= 10){

    lcd.setCursor(5,1);   //set lcd faces
    lcd.write((char) 3);
    lcd.setCursor(5,0);
    lcd.write((char) 1);
    lcd.setCursor(9,1);
    lcd.write((char) 201);
    lcd.setCursor(9,0);
    lcd.write(2);
    lcd.setCursor(6,0);
    lcd.write("x");
    lcd.setCursor(8,0);
    lcd.write("x");
    lcd.setCursor(7,1);
    lcd.write("o");
    }

    if (distance <= 10){
      randSound(maximum);
    }

}

void randSound(int maximum){
  NewTone(buzzerPin, random(maximum, 10*maximum),dur);
  delay(maximum);
  noNewTone(buzzerPin);
}

void stopDCMotorStop(){

  if (currentMillis-previousDCStopMillis<= DCStopInterval) {
    motor1.setSpeed(0);
    motor1.run(RELEASE);
    motor2.setSpeed(0);
    motor2.run(RELEASE);
    motor3.setSpeed(0);
    motor3.run(RELEASE);
    motor4.setSpeed(0);
    motor4.run(RELEASE);
    previousDCStopMillis =currentMillis;
    }

  }

void stopDCMotorBack(){

  if (currentMillis-previousDCBackMillis<= DCBackInterval) {
    motor1.setSpeed(100);
    motor1.run(FORWARD);
    motor2.setSpeed(100);
    motor2.run(FORWARD);
    motor3.setSpeed(100);
    motor3.run(FORWARD);
    motor4.setSpeed(100);
    motor4.run(FORWARD);
    previousDCBackMillis =currentMillis;
    }
  }

use a state machine ... explore FSM ... https://duckduckgo.com/?q=fsm+arduino

use a variable to keep track of the state of the system ... when distance is below 10 cm, then set state to 1 ... states would be something like  0 no change ... 1 stop motors and go to state 2 ... 2 stay in state 2 for two seconds then go to state 3 ... 3 turn on reverse and go to state 4 ... 4 stay in state 4 for two seconds then go to state 5 ... 5 start turn and go to state 6 ... 6 stay in state 6 for eight seconds and go to state 7 ... etc. etc.


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.

source: Stack Exchange

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

sort: votes


text:
Collection of functions for arduino IDE
I am having troubles creating a collection of functions to be used in Arduino sketches and libraries. What I want is not a class, but simply a group of functions which do not require an object to be called; general utilities that can be helpful in any Arduino sketch, like an average of analog reads, or a little statistical tool.
Suppose I write a file called Utilities.h    (I am not sure .h is the right extension to use in this case):
Utilities.h
#ifndef Utilities_h
#define Utilities_h
#include <Arduino.h>

void utility1(...){
...
}

float utility2(...){
...
}

//and so on

#endif

I then save this file in ../Arduino/libraries/Utilities. Whenever I want to use my utilities from this file directly in a sketch I type #includethe full path to the file (#include <Utilities.h>  won't work).
The real problem is if I want to use this collection of functions in a library, like in the following example.
myClass.h
#ifndef myClass_h
#define myClass_h
#include "full path to Utilities.h"

class myClass{
 private:
  int a;
 public:
  myClass();
};

#endif

myClass.cpp
#include "myClass.h"

myClass::myClass(){
 a = utility2(...);
}

Whenever I try to #include <myClass.h>  in my sketches and compile, I get 'multiple definition' error messages for the functions on my  Utilities.h.
So to summarize, my question is: how can I create a collection of functions that can be used both in a sketch and in a library for Arduino?

You need to "split" your library.
Placing full functions inside a header file (.h) is bad form and causes the exact problem you are seeing. Every time you include the header file you create an entirely new copy of the function. This can only work if the functions are static, which means that they exist, and are contained entirely within, the function in which the header is included in. All outside access to them is completely cut off and they become "local" to the file. That means you can have multiple copies of them in one program. However that is wasteful of space since you are duplicating your code.
Instead you need to have the code itself in a .cpp file, which gets compiled separately and then linked with your sketch at the end of compilation, and just pointers to the functions you have written in your .h file.
Utilities.h:
extern void myFunction();

Utilities.cpp:
void myFunction() {
    blah blah
}

The .h file just contains a prototype for the functions which tells the compiler that "This function is defined elsewhere. Find it later on when you link."
It's only the .h file that is included in libraries and sketches, etc, so only the prototype that is duplicated between files. The .cpp is compiled separately and thus only compiled the once, so you don't get the code duplicated.
One caveat with this is that your sketch must include the library you have written so that the IDE knows to look for .cpp files within it to compile. And you must use #include <Utilities.h> for it to be able to work that out. Using a full path rather than just <Utilities.h> means that you break all portability and the IDE may not know to look for .cpp files in there, or even where to actually find it when compiling.  Note as well that the IDE needs to be restarted after creating a new library, which is why it may not be able to find it in your experiments.

Thanks a lot, I thought that the format .h + .cpp  was exclusively for classes.

No, the keyword class denotes a class. .h + .cpp is normal programming practice and procedure and has nothing at all to do with classes. You can create classes inside a .ino file if you want.

What about the externkeyword? Is it essential? I never used it inside an header file while declaring methods of a class

It is not essential, no. It used to be required, but now it is entirely optional. I like to keep it in there as a reminder that "this function is implemented elsewhere". It is only required now for variables - functions have it implicitly automatically in modern compilers.

Oh and class methods aren't external, they are part of a class. An "extern" function is a raw function, not a class member. they are very very different beasts.

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


text:
Problem understanding how to program DS3231 RTC
I need to send a pulse to an Arduino at every one hour. I don't need day, month, year etc. I just want a pulse from DS3231 at every 1 hour through the square wave pin.
https://github.com/NorthernWidget/DS3231
I have included this library but I can't anyhow understand how to generate an pulse at each hour using this library. Is it possible?
My requirement is simple. I need a pulse at my Arduino interrupt pin at each hour.
#include <DS3231.h>
#include <Wire.h>

void setup()
{
  Wire.begin();
  EICRA |= 0b00000011;
  EIMSK |= 0b00000001;
  sei();
 // No clue on how to setup DS3231 for getting a pulse at each hour
}
ISR(INT0_vect)
{
  // This function will be executed in each hour
}
void loop(){}

Look at the documentation that you've reference and see the turnOnAlarm() function.  I didn't dig into it but that should get you started.

I checked that too. The example was too complicated. But as far as I have understood from the example that I have to check the alarm status through I2C.

In that case let me suggest that you try some simple exercises before diving into a relatively complex device like the DTC3231.  If you just learn about how to set and read the time that would be a good start.

DS3231 address is 104. Instead of using that large complicated header, send simple frame.
For 1 sec pulse the frame will be :
S 208 A 14 A 0 P
N.B. Here address is 7 bit value 104. And a extra bit for R/W operation.
In the Arduino wire library,  you don’t need to include the R/W bit. So,just write 104.
For hourly Alam set the INT bit of control register and send simple frame like this.
Don't make things complicated using the header.

See the documentation at:
DTC3231 Library Documentation
Where there is the section on alarm bits and setting alarms:
        // Alarm functions

        void getA1Time(byte& A1Day, byte& A1Hour, byte& A1Minute, byte& A1Second, byte& AlarmBits, bool& A1Dy, bool& A1h12, bool& A1PM);
/* Retrieves everything you could want to know about alarm
 * one.
 * A1Dy true makes the alarm go on A1Day = Day of Week,
 * A1Dy false makes the alarm go on A1Day = Date of month.
 *
 * byte AlarmBits sets the behavior of the alarms:
 *  Dy  A1M4    A1M3    A1M2    A1M1    Rate
 *  X   1       1       1       1       Once per second
 *  X   1       1       1       0       Alarm when seconds match
 *  X   1       1       0       0       Alarm when min, sec match
 *  X   1       0       0       0       Alarm when hour, min, sec match
 *  0   0       0       0       0       Alarm when date, h, m, s match
 *  1   0       0       0       0       Alarm when DoW, h, m, s match
 *
 *  Dy  A2M4    A2M3    A2M2    Rate
 *  X   1       1       1       Once per minute (at seconds = 00)
 *  X   1       1       0       Alarm when minutes match
 *  X   1       0       0       Alarm when hours and minutes match
 *  0   0       0       0       Alarm when date, hour, min match
 *  1   0       0       0       Alarm when DoW, hour, min match
 */
        void getA2Time(byte& A2Day, byte& A2Hour, byte& A2Minute, byte& AlarmBits, bool& A2Dy, bool& A2h12, bool& A2PM);
            // Same as getA1Time();, but A2 only goes on seconds == 00.
        void setA1Time(byte A1Day, byte A1Hour, byte A1Minute, byte A1Second, byte AlarmBits, bool A1Dy, bool A1h12, bool A1PM);
            // Set the details for Alarm 1
        void setA2Time(byte A2Day, byte A2Hour, byte A2Minute, byte AlarmBits, bool A2Dy, bool A2h12, bool A2PM);
            // Set the details for Alarm 2
        void turnOnAlarm(byte Alarm);
            // Enables alarm 1 or 2 and the external interrupt pin.
            // If Alarm != 1, it assumes Alarm == 2.
        void turnOffAlarm(byte Alarm);
            // Disables alarm 1 or 2 (default is 2 if Alarm != 1);
            // and leaves the interrupt pin alone.
        bool checkAlarmEnabled(byte Alarm);
            // Returns T/F to indicate whether the requested alarm is
            // enabled. Defaults to 2 if Alarm != 1.
        bool checkIfAlarm(byte Alarm);
            // Checks whether the indicated alarm (1 or 2, 2 default);
            // has been activated.

UPDATE:
Based on your comment:

I checked that too. The example was too complicated.

You need to spend some time gaining a familiarity with some of the basic Arduino and AVR functions.  To make this work you're going to not only need to understand how to talk to the RTC via I2C but also how to enable and respond to a pin interrupt in the AVR.  You have the ISR function there but you have not done anything to enable any interrupt source.

Trust me, I know how to enable external interrupt (also pin change interrupt of ATMEGA328p). EICRA |= 0b00000011; EIMSK |= 0b00000001;sei(); You are asking for this. Isn't it? I didn't included these as the question is about RTC instead of ISR function.

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


text:
Powering Arduino with reverse car lights?
I'd like to build a reverse car sensor using Arduino
When we select reverse gear, the reverse lights powers, so we can take electricity from them.
My question is can i power my Arduino directly from the reverse lights wires, or should i use regulators or anything else?

What board are you using? Most boards already have a regulator on it.

Use a switching regulator such as the LM2596. You can get a ready board from eBay for about US$1

can i use car phone charger as a regulator?

It depends very much on the car and your Arduino. There are two factors to consider:

Leeching power off lights can have an adverse effect on the car's ability to sense a blown bulb.
Many Arduinos have a 2 second delay while the bootloader executes (some even have 8 seconds).

If your car doesn't sense blown bulbs (most modern ones now do, even cheap ones) and you can work without a bootloader (programming directly with a USBasp for example) to avoid the power-on delay, then it may be possible, yes.
As has been mentioned by others, using a switching regulator is the best method for powering the board as it avoids excess power loss through heat (which can especially be a problem in confined spaces). I would recommend not using one of the cheap eBay modules, but instead using a proper "cigarette lighter" to USB adaptor (available from all good gas stations priced $5) which is designed to work with automotive voltages. A car's 12V power has transients in excess of 50V sometimes (back EMF from the spark generation) and the electronics have to be able to cope with that - those cheap eBay modules aren't designed for that and could die taking your Arduino with it.

This is just to top off the other answers. If you have a fairly modern car that runs on LED lights, you can easily use that voltage. MOST LEDs run from around 3-6V soyou might want to measure the voltage. If everything is good, then you can connect the positive of the LED to the 5V of your Arduino and GND to GND.

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


text:
Why do we need to amplify the signal of an electret?
I do understand from my reading that I should amplify the signal from an electret to be able to read it with an Arduino. I'd love to know the science behind that, why should we amplify the signal to be able to get a correct reading ?

You may find Electronics Stackexchange useful for questions like this.


text:
Arduino based Fan controller for PC
My fellow programmers,
I'm planning on creating a fan controller for my PC using an Arduino Duemilanove and a generic motor sheild. (Fan controllers are not exactly cheap here and i'd rather spend my money on an SSD than on a fan controller =)
On a normal scenario, I want my fans to spin slowly, just to keep some air flowing but not enough to make too much noise. Obviously, they should turn on at full speed (or so) during a demanding scenario, like playing a game.
My idea is to use a usb port to communicate with Windows, so that my arduino knows when a demanding application was started. Is there an easy way to do this or should I buy myself some cheap temperature sensors, place them on the more important parts and control my fans with these temperature readings?
I'd also like to have an option to turn of the communication between the arduino and whatever informs it about the computer usage, so that I can program it in order to test a different algorithm.
Thanks for any help!

Yes you can. One of the options is using Visual Studio if you are Windows user (using built in library is enough to meet your 'option to turn off' needs). There so many examples of serial communication using either C# or C++ with Arduino, so you can do communication between Laptop - Arduino via serial cable or even built in bluetooth in laptop (with extra bluetooth module for Arduino).
The most simple setup is your laptop act as master and arduino as slave. Arduino does not need any information about what program is running, instead just waiting command from Laptop wether to turn off or turn down the fan
You can read  information from your PC (for Windows), such as temperature or battery level

Any Arduino with a USB interface can communicate with a PC via pseudo-serial ports (that is, serial-over-USB links).  If you have a PC program that somehow monitors what processes are running, your plan of telling the Arduino to speed up the fan when certain programs are running is practical to do.
On Linux systems, fan speed can be controlled by user programs like fancontrol-gui and tpfanco.  Probably similar programs are available on Windows and Mac systems.  Your Arduino could measure temperatures and send them to the host OS for fan speed control.  Or vice versa, your PC could use DBus or ACPI calls to measure its chip temperature and send it to the Arduino to control a fan.
Note, there's a thermometer built in to several ATmega devices.  Its resolution isn't great and due to chip thermal mass it might not respond quickly, but you might find it worthwhile to experiment with.  For example, see §24.8, Temperature Measurement, on page 247 of the document Atmel-8271J-AVR-ATmega-Datasheet_11/2015, which says to select the internal 1.1 V ADC voltage reference, read ADC channel 8, and scale the result per Table 24-2 to get °C.

authors: Анатолий Соколов


text:
using pull-up resistors with A-star 32u4 on putput pins?
Okay probably not the first time this has been asked, but really, I search all over the internet and was not able to find this.
I want to drive LEDs on the output on some of my pins. Is it required to put a pull-up resistor or current limiter resistor on these? or can I just plug the LED into the output, and the other end of the LED to +vcc? Are there example schematics someplace that will show this?
thoughts? suggestions?
thanks.

Have you asked Google?

You always should use a resistor.
Simply the following schematic should be used.
The resistor value can be calculated as follows:
(V + Vfwd = I * R) => R = (V + Vfwd) / I
V is 5.0 V
Vfwd is the forward voltage of the LED (this differs per type/color/brand)
I is normally max. around 20 mA (but can be briefly more if the LED does not continuously lights)
Normally R is between 100 and 500 R, but can differ if you want to add multiple LEDs.

simulate this circuit – Schematic created using CircuitLab


text:
Having Arduino read a video game screen
I want to connect my Arduino to my tv screen while playing a playstation/XBox game. When a certain screen comes up (like say when you die the same screen pops up) then I want Arduino to catch that and then trigger another device on and off. How might I be able to trigger something by having arduino read the screen then trigger something on and off?

This is image decoding (decoding the HDMI or composite output) there is no way an Arduino is powerfull enough to analyze the image in a viable amount of time. Plus the output of HDMI (or worst composite) is rendered so there would need to be interpolation of the colors, paterns,...
You need something WAY more powerfull than a 16MHz uController for this kind of work.

Not a chance. The Arduino doesn't even have a fraction of the processing power needed, and only about 0.0000000001% of the memory you would need. Instead you need to use something more realistic. Maybe a Raspberry Pi with a video capture dongle and OpenCV?

There's actually not a lot of processing that needs to be done to recognize a steady computer-generated image (or a distinguishing part of one).  But you do need some ability sample (even if only one detail at a time) with an analog bandwidth comparable to the video one, and an ATmega can't do that at the resolution of a modern game system.  So at the least this would require some clever external circuitry that could be basically told "give me the value of the pixel at X, Y in the next frame" and then run that many times to check details until you've decided the game is sitting on that screen.

@EvanB, You can help improve the site who's objective is to accumulate good questions and answers by either accepting answers that work for you or refining your question (edit it) in hopes of getting a better answer.

Most Arduino platforms contain a very low power embedded processor.  As such it is very unlikely such a device will decode an NTSC or PAL signal let alone modern digitally compressed video.
Instead consider using a light sensor attached to your monitor.  This is more in line with what, for instance, the Arduino Uno is capable of.  If you can identify a spot on the monitor that will only change to a certain brightness at the conclusion of a game, you could look for that brightness level using a light sensor attached to the monitor and connected to an Arduino.
Here is a tutorial about using a light sensor with an Arduino.  Most of the circuit is for the display of which you need not bother with.


text:
unbrick Nano RP2040 connect using Uno
I think I have bricked my Nano RP2040. How do I unbrick using a Uno or Mega? I found instructions for using another Nano, but only have the one.

are you certain that the unbricking instructions are Nano specific?

I don't think you can unbrick it like a regular Arduino Nano, since there isn't a bootloader that is programmed into the RP2040 chip.

You don't actually need a Uno or mega to unbrick the device.
You need to place a jumper wire between the GND and REC pins.
This will force the bootloader to load, a mass-storage device will appear on the computer. You can than upload a UF2 file to the drive to restore it.
You can read more about it in the arduino documentation.
https://docs.arduino.cc/tutorials/nano-rp2040-connect/rp2040-01-technical-reference#forcing-bootloader
If it is really bad you might also need to use a flash_nuke.uf2 file first. This removes all files on the Arduino Nano RP2040 connect.

Thank you, Bonnom. Got the Nano working again.


text:
I am trying to automate my sun shade on my back porch with a Nema17 Stepper motor
I am very new to Arduino (and fritzing so please excuse my poor layout).
I am trying to automate my patio sun shade, eventually it will incorporate a photocell but I wanted a proof of concept first with buttons. The first and last buttons represent limit switches and the middle button represents a toggle switch (which will eventually become the photocell).
An example of what I am trying to do is;
If the upper limit switch is active and I press the toggle button, the stepper runs until it hits the lower limit switch, if the lower limit switch is active and I press the toggle button then the stepper should run the other direction until it hits the upper limit switch.
I have serial prints to show what is happening, if I hold either of the "limit switches" then the serial monitor displays (rather spams) the corresponding print line, however the stepper motor is not moving how I would expect it to. I have to be holding a limit switch and holding the toggle for it to move in a direction, even then it only moves approximately 1 step per second. If I release the limit switch and continue to hold the toggle then the stepper steps one back and one forward for the duration that I depress the switch. The code I have is based off of someone attempting the same thing but with a DC motor, I tried to accommodate it to a stepper motor and am having trouble.

    // constants won't change. They're used here to set pin numbers:
const int uplimitPin = 9;     // pin number for upper limit switch
const int togglebuttonPin = 10;     // pin number for the toggle switch
const int downlimitPin = 11;     // pin number for the lower limit switch
const int dirPin =  2;      // direction pin for stepper
const int stepPin =  3;      // step pin for stepper

// variables will change:
boolean uplimitState = 0;         // variable for reading the status of the upper limit switch
boolean togglebuttonState = 0;         // variable for reading the toggle switch status
boolean downlimitState = 0;   // variable for reading the status of the lower limit switch

int shadePosition = 2;  // Tells progam what position the shade is in

/**
 *  setup inputs for switches and outs for motor pins
 *  serial begin to read the switches to test for errors
 */
void setup() {
    // initialize the stepper pins as outputs:
    pinMode(dirPin, OUTPUT);
    pinMode(stepPin, OUTPUT);
    // initialize the pushbutton pins as an inputs:
    pinMode(uplimitPin, INPUT);
    pinMode(togglebuttonPin, INPUT);
    pinMode(downlimitPin, INPUT);
    Serial.begin(9600);
}

/**
 * this function turns motor foward
 */
void shadeDown() {
     // turn motor foward:
    digitalWrite(dirPin, HIGH);
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(1000);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(1000);
}

/**
 * this function turns motor backwards
 */
void shadeUp() {
     // turn motor in other direction:
    digitalWrite(dirPin, LOW);
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(1000);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(1000);
}

/**
 * Stop the motor form moving
 */
void stopShade() {
  digitalWrite(stepPin, LOW);

}

/**
 *
 */
void loop() {
   // read the state of the pushbutton value:
   uplimitState = digitalRead(uplimitPin);
   togglebuttonState = digitalRead(togglebuttonPin);
   downlimitState = digitalRead(downlimitPin);

   // check if the limit is active. If it is, the limitState is HIGH:
   if (uplimitState == HIGH) {
      shadePosition = 2;
      Serial.println(F("The shade is up"));
      stopShade();
   }else if (downlimitState == HIGH) {
      shadePosition = 1;
      Serial.println(F("The shade is down"));
      stopShade();
  }

  if (togglebuttonState == HIGH) {
    if( shadePosition  == 1 ){
      shadeUp();
      delay(100);
      shadePosition = 2;
      delay(100);
    }else if (shadePosition == 2 ) {
      delay(100);
      shadeDown();
      delay(100);
      shadePosition = 1;
    }

  }
}

System State Machine
As JRobert suggested, a state machine would make the code a lot cleaner! Below is some pseudocode (I'll leave the debugging up to you ;)) of how you might set that up.
When you break up your system into 4 distinct states, it's easy to reason about what should be happening at each state and what is required to get to the next state. You can draw a diagram showing this (google "state machine") to help you reason.
...

enum SystemState {
    SystemState_Opening,
    SystemState_Closing,
    SystemState_Open,
    SystemState_Closed
};

void main()
{
    // Set initial state
    SystemState state;
    if (digitalRead(upLimitState))
    {
        state = SystemState_Closed;
    }
    else
    {
        state = SystemState_Open;
    }

    // Run state machine
    while (1)
    {
        switch (state)
        {
            case SystemState_Closed:
            {
                if (digitalRead(toggleButtonPin))
                {
                    state = SystemState_Opening;
                }
                break;
            }
            case SystemState_Open:
            {
                // TODO: Implement this yourself!
                break;
            }
            case SystemState_Closing:
            {
                if (digitalRead(upLimitState))
                {
                    state = SystemState_Closed;
                }
                shadeUp();
                break;
            }
            case SystemState_Opening:
            {
                // TODO: Implement this yourself!
                break;
            }
    }
}

What's Wrong With Your Code
The actual issue with the code you provided is that you're only calling the shadeUp() function once. You need to call it many times to send the step pin many pulses to rotate the motor.
Each time you send a pulse to the step pin (eg. shadeUp()), you rotate the motor by one step (or microstep) which is likely only 1.8 degrees!

Assuming you're asking how debug the unexpected behavior your described (and not having any steppers on-hand to have a go at your code) I'll offer some observations and suggestions.
Pushbuttons "bounce" (not really, but their output signal looks like they bounce). For the limit switches, you won't really care - the first make (and I'm assuming positive logic, for simplicity of the discussion) tells you that the shade has reached it's limit, and you don't need to (probably shouldn't!) wait for the switch to settle before stopping the shade. The 'break' of a limit switch is uninteresting except possibly to confirm that the shade is moving when you expected it to, and again, who cares about the bounces? But the toggle button's bounces may well confound your logic unless you debounce it (can be done either electrically or in software - search the topic). And even though the eventual photocell may not bounce (or it may: are there shade-trees within it's view, f/ex?), right now, you're testing with a button which certainly does.
This is a would be a good application to implement as a state-machine, and even if you don't do that formally, diagramming a state-machine to operate your shade should make it clear what your code will need to do. If you're new to software as well as to Arduino, learning about state-machines might be a longer detour than you want to take at the moment, but if this kind of control system is what interests you, you will encounter them sooner or later, because they model your control system pretty directly, both graphically (because you usually sketch them out first) and in software.
State diagrams turn out to be one of the best tools a software designer has to communicate the details of a proposed control system between them and the typically-non-software-trained people who are the experts at building and/or using the devices being automated (think printing presses, copiers, assembly robots, .... ). The picture says it all.


text:
Find OK or ERROR in serial string
I am trying to figure out how to capture the OK or the ERROR from a SIM800l.
I have tried
mySerial.println("AT");
while (mySerial.available() > 0 ) {
String str = mySerial.readString();
Serial.println(str);
     if (str.equals("OK")) {
        Serial.println("ok");
     } else {
        Serial.println("unknown");
     }
   }

But I always getting nothing back?

Does this answer your question? Comparing a String after reading it from Serial fails. The issue is that the string read from the serial port also contains a closing "newline" character so the comparison fails. You need to strip off the newline.

You can use .indexOf to find characters in a String. It returns a -1 if a match is not found. See https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/indexof/
mySerial.println("AT");
String str;

while (mySerial.available() > 0 )
{
    str = mySerial.readString();
    Serial.println(str);

    if (str.indexOf("OK") != -1)
    {
        Serial.println("ok");
    } else if (str.indexOf("ERROR") != -1)
    {
        Serial.println("error!");
    } else {
        Serial.println("unknown");
    }
}


text:
Timer 1 "Set on Compare Match" in Normal Mode - Not working
I'm using the hardware timers on the 328 for phase angle control of a triac with zero-crossing detection. I am encountering some strange behavior with the "Set on Compare Match" feature not working as expected on Timer1. I am attempting to replicate the red "gate" trace here: https://playground.arduino.cc/Main/ACPhaseControl/, but with my own implementation in code.
Before building the triac and zero-cross detection circuit, I am using another timer (Timer0) to simulate a 120Hz AC square wave (2x the 60Hz frequency because the double crossing pulse will arrive twice a cycle).
The output of the synthesized AC square wave is fed into an external interrupt pin (INT0) with a jumper. The correct functionality of the program is a short pulse to fire the triac at some phase delay relative to the zero crossing interrupt event (another example: https://www.homemade-circuits.com/wp-content/uploads/2020/07/half-phase-control.jpg)
I configure Timer 1 in normal mode, and define compare levels for both OCR1A and OCR1B. OCR1A is the "phase delay" from zero crossing at which to fire the triac, and OCR1B sets the duration of the pulse used to fire the triac. In my code, Method 1 is working and producing the intended output, while Method 2 is not working (output is always ON). For brevity, I am highlighting the differences between the two methods below, and the rest of the code is the same.
Method 1:

Set OC1A to do nothing on compare (normal port operation) TCCR1A=0;
"Manually" turn on the pin inside of the interrupt handler for output compare A. It will later be turned off in the interrupt handler for output compare B: PORTB=(1<<PORTB1);

This produces the following (correct) output. In the oscilloscope screenshot, the yellow trace is the simulated AC square wave, and the green trace is to be the gate voltage on the triac.
https://i.sstatic.net/tpSAw.png
Method 2:

Enable the OC1A "Set at compare match" bit in the TCCR1A register:
TCCR1A |= (1 << COM1A1) | (1 << COM1A0);
In theory, this means that I don't have to manually turn on the pin inside the interrupt handler for compare A, because it's already been turned on for us by the Compare Match Output Unit.

https://i.sstatic.net/45tFA.png
Note that in both methods, I still need to "manually" turn off the pin inside the output compare B interrupt handler because OC1A and OC1B are not the same physical pin: PORTB=0;
In Method 2, the pin is held ON, with no indication that the interrupt handler for output compare B is doing anything. My mental model of the port is that as long as the bit in the data direction register is set for that port, both the output compare unit and CPU can write to the pin. It appears that the pin is always being held ON, even after it is turned OFF by the CPU. Does the compare unit lock/latch the pin until the next clock cycle, or am I missing something else? Some tips here would be much appreciated.
I can prove that the output is indeed connected to OC1A because OC1A is PB1 which is connected to the oscilloscope and is being toggled in Method 1. I have vertically scaled OC1A (green) for readability against OC0A.
I have been referencing Section 13 of https://www.sparkfun.com/datasheets/Components/SMD/ATMega328.pdf for most of this task.
My code below for Method 1 is presented. To get Method 2, toggle the comments on the indicated lines.

#define F_CPU 16000000L

#include <avr/io.h>
#include <avr/interrupt.h>

/*
For reference:
OCR1A = turn_on_timer_level
OCR1B = turn_on_timer_level + pulse_width

*/

int timer0_ac_sim_val = 64;    // Measured in clock ticks with prescale=1024
int turn_on_timer_level = 500;    // Measured in clock ticks with prescale=64
int pulse_width = 200;    // Measured in clock ticks with prescale=64

ISR(INT0_vect){
    // ISR at output compare A of timer 0 turns on timer 1 - simulates what happens when a zero crossing rising edge is detected on a 120Hz AC sine wave
    TCCR1B |= (1<<CS11) | (1<<CS10);
    TCNT1 = 0;
}

ISR(TIMER1_COMPA_vect){
    // ISR at output compare A of timer 1 turns on the pin
    PORTB = (1<<PORTB1);   // Turn on the pin COMMENT FOR METHOD 2
}

ISR(TIMER1_COMPB_vect){
    TCCR1B = 0; // Turn off the timer
    PORTB = 0;  // Turn off the pin
}

int main(){

    // Timer 0 setup for a 120Hz square wave on OC0A
    DDRD |= (1<<PD6);

    TCCR0A = 0x0;
    TCCR0A |= (1<<COM0A0) | (1<<WGM01);  // Set the output to toggle on compare

    TCCR0B = 0x0;
    TCCR0B |= (1<<CS02) | (1<<CS00);     // Configure with a prescale of 1024 and start clock

    OCR0A = timer0_ac_sim_val;  // Calculate this value for a 120Hz square wave, doesn't change.

    // Enable external interrupt 0 to trigger on a rising edge - set the External Interrupt Control Register
    EICRA |= (1<<ISC01) | (1<<ISC00);
    EIMSK |= (1<<INT0);

    // Global interrupt enable
    sei();

    // Timer 1 setup
    DDRB |= (1<<PORTB1);

    TCCR1A = 0x0;   // No pin action on output compare
    // TCCR1A |= (1 << COM1A1) | (1 << COM1A0);    // Set OC1A on compare match UNCOMMENT FOR METHOD 2

    TCCR1B = 0x0;   // Disable clock

    OCR1A = turn_on_timer_level;  // Delay between OC0A rise and OCR1A trigger
    OCR1B = turn_on_timer_level + pulse_width;   // Delay between OC0A rise and OCR1B trigger

    // Enable timer 1 interrupts
    TIMSK1 |= (1<<OCIE1A) | (1<<OCIE1B);

    while(1){
    };
}

My mental model of the port is that as long as the bit in the data direction register is set for that port, both the output compare unit and CPU can write to the pin.

Your assumption is incorrect. See section 13.11.1 of the datasheet you linked.

If one or both of the COM1A1:0 bits are written to one, the OC1A output
overrides the normal port functionality of the I/O pin it is connected to.

Thus, the "normal" functionality being overridden precludes your changing the pin yourself. You would need to set those bits to zero in the ISR to reclaim the use of the port, and set them back to one when required.

Perfect! I missed that in the datasheet when I was reading. Thanks so much.

For those who might be interested, after fixing the problem I decided to implement the same functionality using Fast PWM mode instead of CTC mode. In trying to debug my original issue, I came across a similar post, to which one of the answers was:
https://arduino.stackexchange.com/a/30529/89096

The PWM modes manage pin at both ends of the cycle.
The point of the CTC modes is that they manage the pin only at one end of the >count, but allow you to manage the other end explicitly.
To manage both ends explicitly, you use normal mode.

I didn't fully realize what that meant until now, but it clicked. In PWM mode, the hardware timer takes care of the pin toggling for us, on both sides of the waveform. We would use Normal or CTC modes if we wanted to do manage one or both sides of the waveform differently. But my application fits perfectly in the Fast PWM category, so I decided to implement that as well. This saves an ISR by not making the CPU "manually" toggle the pin on and off each time. The only difference is that the output is on OC1B (PORTB2) now instead of OC1A (PORTB1).
#define F_CPU 16000000L

#include <avr/io.h>
#include <avr/interrupt.h>

int timer0_ac_sim_val = 64;    // Measured in clock ticks with prescale=1024
int turn_on_timer_level = 400;    // Measured in clock ticks with prescale=64
int pulse_width = 100;    // Measured in clock ticks with prescale=64

ISR(INT0_vect){
    // ISR at output compare A of timer 0 turns on timer 1 - simulates what happens when a pulse is received from the zero crossing detector
    TCCR1B |= (1<<CS11) | (1<<CS10) | (1<<WGM13) | (1<<WGM12);
    TCNT1 = 0;
}

ISR(TIMER1_COMPA_vect){
    // ISR at output compare A of timer 1 turns on the pin
    TCCR1B = 0; // Turn off the timer
}

int main(){
    // Timer 0 setup for a 120Hz square wave on OC0A
    DDRD |= (1<<PD6);

    TCCR0A = 0x0;
    TCCR0A |= (1<<COM0A0) | (1<<WGM01);  // Toggle mode - non-PWM

    TCCR0B = 0x0;
    TCCR0B |= (1<<CS02) | (1<<CS00);     // Configure with a prescale of 1024, start clock

    OCR0A = timer0_ac_sim_val;

    // Enable external interrupt 0 to trigger on a rising edge - set the External Interrupt Control Register
    EICRA |= (1<<ISC01) | (1<<ISC00);
    EIMSK |= (1<<INT0);

    // Enable interrupts
    sei();

    // Timer 1 setup - 16 bit resolution with a prescale of 8 gives a max period of 1/(16e6/8/65536) = 32.78ms
    DDRB |= (1<<PORTB2);

    // Set WGM12 (CTC) to 1 and start the timer with a prescaler of 1024   -> This starts the timer in CTC mode
    TCCR1A = (1<<COM1B1) | (1<<COM1B0) | (1<<WGM11) | (1<<WGM10);  // Set COM1B1 and COM1B0 to 1 for inverting mode. For fast PWM set WGM11 and WGM10
    TCCR1B = 0x0;   // Start with clock disabled

    OCR1A = turn_on_timer_level + pulse_width;
    OCR1B = turn_on_timer_level;

    // Enable timer 1 interrupts
    TIMSK1 |= (1<<OCIE1A);

    while(1){

    }


text:
USB serial communication arduino nano and jetson nano
I want to communicate between Jetson nano and arduino nano through serial.
I wrote a simple script to test functionality but I receive strange data
here is the arduino code
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

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

  Serial.println("work fine");
  delay(10000);
}

and this is the python code run on jetson nano
import serial
import time

arduino = serial.Serial('/dev/ttyUSB0', 9600, timeout=1)

while True:
  try:
     data = arduino.readline()
     if data:
        print(data)
        print('Hi Arduino')
  except:
     arduino.close

the output is
b'\x17\x0f\t\x0b\x01\x06\t\x0e\x15\r\n'
Hi Arduino

if tried different baud rates but nothing change.
when is use serial monitor on windows it works fine.

start by sending only one character every second

Wondering if this might be a UTF conversion problem.

refer to ASCII tables ... data bits are being dropped ... working in hex makes it clear ... the arduino sends 77, 6F, 72, 6B, 20, 66, 69, 6E, 65, 0D, 0A and the Jetson receives 17, 0F, 09, 0B, 01, 06, 09, 0E, 15, 0D, 0A ... possibly a speed mismatch, or the data buffer is being swamped by incoming data

regarding the speed, is there parameter other than baud rate that can cause mismatch?
I sent character "I" each 10 sec, but received b'\t\r\n'

Asynchronous serial transmission has 3 additional parameters: number of data bits, usage of parity, number of stop bits. A common set is 8-N-1, meaning 8 data bits, no parity, 1 stop bit. You need to check these. A mismatch on the number of stop bits is harmless, as long as the sender uses more than the receiver.

I also belive its to do with the following line,
 data = arduino.readline()

Try the following,
while True:

try:
     arduino.flushInput() // Clear buffer

     data = arduino.readline()

     // decode the bytes into str format, 'utf-8' arg should work
     data.decode('utf-8')

     // strip the \r\t in the str output
     data.strip()
     if data:
        print(data)
        print('Hi Arduino')
  except:
     arduino.close

See if this resolves your problem.
Note: I used an ESP32 and python script with the above-mentioned changes and it worked for me.
Also, as mentioned in the comment section some of the information might be missing in the output 'b'\x17\x0f\t\x0b\x01\x06\t\x0e\x15\r\n' this is not something reproducible for me. Just for reference my byte string output without the modifications was b'work fine\r\n' not 'b'\x17\x0f\t\x0b\x01\x06\t\x0e\x15\r\n'

double-check Arduino write speed,
double-check python serial connection baud rate,
include the py script correction

see if this helps resolve your problem.

This stackoverflow question/answer implies that .readline() needs to be converted to a string.
import serial
ser = serial.Serial("COM11", 9600)
while True:
     cc=str(ser.readline())
     print(cc[2:][:-5])

I agree w/one of the comments to that answer that it might be better written as:
import serial
ser = serial.Serial("COM11", 9600)
while True:
     cc=str(ser.readline())
     cc=cc.decode("utf-8")
     print(cc)

readline() returns numbers ... it's returning non-printable characters

... returns "Bytes" then?

there is no difference between text and bytes  ... it's all bytes ... the difference is how you present those bytes to the user ... the python code is printing text because it escapes non-printable characters ... the escape character is the \


text:
ESP8266 not sending text message to telegram bot
I've been trying to get my esp8266 to send a message to a telegram bot as soon as it connects to the wi-fi, whenever it encounters an obstacle, or whenever an SOS push button is pressed. But I didn't receive any message on telegram whenever I tested for either of the mentioned cases. Let me know if anything is wrong with the code and please suggest ways to make it work.
#include <ArduinoJson.h>
#include <ArduinoJson.hpp>

#include <Servo.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

#define trigPinF 2 // Front sensor trig pin
#define echoPinF 0 // Front sensor echo pin
#define trigPinL 5 // Left sensor trig pin
#define echoPinL 4 // Left sensor echo pin
#define trigPinR 14 // Right sensor trig pin
#define echoPinR 12 // Right sensor echo pin
#define ledPin 13 // LED pin
#define vibPin 15 // Vibration motor pin
#define buttonPin 16 // Button pin
#define servoPin 3 // Servo pin

const char* ssid = "XXXXX";
const char* password = "XXXXX";

#define token "XXXXXXXXXXXXXXXXX"
#define telegramChatId "XXXXXXXXXX"

WiFiClientSecure client;
UniversalTelegramBot bot(token, client);

Servo servo;

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

 pinMode(trigPinF, OUTPUT);
 pinMode(echoPinF, INPUT);
 pinMode(trigPinL, OUTPUT);
 pinMode(echoPinL, INPUT);
 pinMode(trigPinR, OUTPUT);
 pinMode(echoPinR, INPUT);
 pinMode(ledPin, OUTPUT);
 pinMode(vibPin, OUTPUT);
 pinMode(buttonPin, INPUT);
 servo.attach(servoPin);

 WiFi.begin(ssid, password);
 Serial.println("Connecting to WiFi...");
 while (WiFi.status() != WL_CONNECTED) {
 delay(1000);
 Serial.print(".");
  }
 Serial.println();
 Serial.println("WiFi connected");

 bot.sendMessage(telegramChatId, "Bot started up", "");
}

void loop() {
  long durationF, distanceF, durationL, distanceL, durationR, distanceR;
 digitalWrite(trigPinF, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPinF, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPinF, LOW);
  durationF = pulseIn(echoPinF, HIGH);
  distanceF = durationF * 0.034 / 2;
 digitalWrite(trigPinL, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPinL, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPinL, LOW);
  durationL = pulseIn(echoPinL, HIGH);
  distanceL = durationL * 0.034 / 2;
 digitalWrite(trigPinR, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPinR, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPinR, LOW);
  durationR = pulseIn(echoPinR, HIGH);
  distanceR = durationR * 0.034 / 2;

 if (distanceF < 30) { // Front obstacle detected
 digitalWrite(ledPin, HIGH);
 digitalWrite(vibPin, HIGH);
 bot.sendMessage(telegramChatId, "Obstacle detected!");
 if (distanceL > distanceR) { // Turn towards the direction with more space
 servo.write(90 + (distanceL - distanceR));
    } else { // Turn towards left if both directions have same space
 servo.write(90 - (distanceR - distanceL));
    }

    String message = "Obstacle detected!";
 bot.sendMessage(telegramChatId, "Obstacle detected!");
  } else {
 digitalWrite(ledPin, LOW);
 digitalWrite(vibPin, LOW);
  }

 if  (digitalRead(buttonPin) == LOW) { // Button pressed
    String message = "Button pressed!";
 bot.sendMessage(telegramChatId, "Button pressed!");
  }

 delay(100);
}

what about the message Bot started up? ... why did you not say anything about that?


text:
Creating variable inside if statement (conditional signed vs unsigned int)
I have an SPI chip that I would like to read out with an Arduino. Some of the registers are signed int others are unsigned int. I am writing a function to read any register.
A simplified version:

readRegister(byte thisRegister, char type) {

  if(type == 's'){
    signed int result;
  }else{
    unsigned int result;
  }

  // take the chip select low to select the device:
  SPI.beginTransaction(SPISettings(2500000, MSBFIRST, SPI_MODE3));
  digitalWrite(SlaveSelectPin, LOW);

  //now get the value
  result = SPI.transfer16(thisRegister);

  // finish up
  digitalWrite(SlaveSelectPin, HIGH);
  SPI.endTransaction();

  // return the result:
  return (result);
}

readRegister(0x4B87,'s')  //read signed int register
readRegister(0xB357,'u')  //read unsigned int register

However this doesn't work since the variable result is created inside the if statement so the scope is wrong. I get error: 'result' was not declared in this scope on the SPI.transfer() line.
How to solve this?

You can't have a function that return two different types of variable. Easiest solution would be to use two function; readRegister and readRegisterSigned. Alternatively, since SPI.transfer only returns an 8 bit value, and int is 16 bit, you could just use signed int for both returned values.

Sorry, I have editted the question so it reads SPI.transfer16, my mistake.
It seems like a horrible waste of repeating code to write 2 allmost identical functions (the real function has more lines).
Could I return the result as signed long no matter what the original type was?

A long would work. You could also implement the readRegisterSigned function as signed int readRegisterSigned(byte thisRegister){return (unsigned int)readRegister(thisRegister);}. Or just typecast at the calling end. I.e. (unsigned int)readRegister(0x4B87,'s');

Hmm, I understand what you are suggesting I think. But I don't follow the steps of your first example. Is this correct?: I read in the bits of an signed integer (from the SPI slave) into an unsigned int variable result,I return that from my function readRegister and I cast that return to unsigned again, but then I return it from a function that yields a signed int. And it gives me the correct value? In what steps is the value actually changing?

'cast' and 'conversion' are not the same thing, though casting native types may involve conversion. If you cast between signed and unsigned types of the same size, you are really only advising the compiler to treat this value as being of the new type. In the expression (uint8_t)signedVariable, you are really telling the complier: "trust me on this: signedVariable's value is really 8-bit unsigned".

Sorry. It should have been signed int readRegisterSigned(byte thisRegister){return (signed int)readRegister(thisRegister);}. My bad.

You could try something like this:
int16_t readRegister(byte thisRegister) {
  int16_t result;

  // take the chip select low to select the device:
  SPI.beginTransaction(SPISettings(2500000, MSBFIRST, SPI_MODE3));
  digitalWrite(SlaveSelectPin, LOW);

  //now get the value
  result = SPI.transfer16(thisRegister);

  // finish up
  digitalWrite(SlaveSelectPin, HIGH);
  SPI.endTransaction();

  // return the result:
  return (result);
}

uint16_t readUnsignedRegister(byte theRegister) {
  return (uint16_t) readRegister(theRegister);
}

Another alternative is to define a "universal" data type, i.e. a union and necessary cast operators.
union univ16_t {
  uint16_t as_uint16;
  int16_t as_int16;

  univ16_t(int value)
  {
    as_int16 = value;
  }

  operator uint16_t()
  {
    return (as_uint16);
  }

  operator int16_t()
  {
    return (as_int16);
  }
};

This allows the function to have the following form:
univ16_t readRegister(byte thisRegister) {
  int result;

  // take the chip select low to select the device:
  SPI.beginTransaction(SPISettings(2500000, MSBFIRST, SPI_MODE3));
  digitalWrite(SlaveSelectPin, LOW);

  //now get the value
  result = SPI.transfer16(thisRegister);

  // finish up
  digitalWrite(SlaveSelectPin, HIGH);
  SPI.endTransaction();

  // return the result:
  return (result);
}

With the two possible assignments.
uint16_t reg1 = readRegister(...);
int16_t reg2 = readRegister(...);

Cheers!

It would be better to have the main function returning unsigned int because otherwise you are loosing precision and the compiler will winge.

Signed ints are capable of being stored in unsigned int, but unsigned its are not [technically] capable of being stored in signed ints if the compiler is being pedantic.  This is because an unsigned int can store a number between 0 and 0xFFFF where as a signed int can store numbers between -(0x7FFF) and 0x7FFF
So if you have a compiler that is doing type checking then you will get problems if you cast an unsigned int to an int, because you might loose data.
That said an unsigned in, int, char, long, float or double is just a series of sequential bits held in memory, so if you know what you are doing you can convert a char into an unsigned long and back again.  Or you can go the whole hog and store all your variables as void*.
So to answer the question I think you function should be this:
uint16_t readRegister(const byte theRegister);

If you want to read a value then you should just call:
uint16_t reg1 = readRegister(0x4B87);
int16_t  reg2 = static_cast<int16>(readRegister(0xB357));

If you really want a separate function then you might be better just #defining it.
#define readSignedRegister(r) {static_cast<int16>(readRegister(r))}
// And you would call it like this.
int16_t  reg2 = readSignedRegister(0xB357);

EDIT to correct the type typo and remove word aligned.

You said: “word aligned”. Not on the AVR-based Arduinos. And it's int16_t, not int_16.

Thaks @EdgarBonet - corrected.

One final option that isn't mentioned in any of the above solutions - Create a function that returns both as separate parameters.
I'm not sure why you would ever do this over Mikael Patel's solution, yes it's then a single function but it's not as nice to use. But it is a possible option.
The only possible advantage in using this pass by reference method of returning the value is that it allows the option for the read function to return a flag indicating whether the read failed or not (timeout, invalid address etc...). And even then it would still be more logical to have two functions, one for signed and one for unsigned.
void readRegister(byte thisRegister, int16_t *signedValue, uint16_t *unsignedValue) {

  unsigned int result_u;

  // take the chip select low to select the device:
  SPI.beginTransaction(SPISettings(2500000, MSBFIRST, SPI_MODE3));
  digitalWrite(SlaveSelectPin, LOW);

  //now get the value
  result_u = SPI.transfer16(thisRegister);

  // finish up
  digitalWrite(SlaveSelectPin, HIGH);
  SPI.endTransaction();

  if (signedValue)
    *signedValue = (int16_t)result_u;
  if (unsignedValue)
    *signedValue = result_u;
}

void someOtherFunction() {
  uint16_t unsignedRead;
  int16_t signedRead;

  readRegister(0x4B87,&signedRead,NULL);  //read signed int register
  readRegister(0xB357,NULL,&unsignedRead); //read unsigned int register

  //read the register as both signed and unsigned (fairly pointless)
  readRegister(0xA55A,&signedRead,&unsignedRead);

  //read the register and throw the result away
  readRegister(0xA55A,NULL,NULL);
}

Based on the comments by Gerben and JRoberts, this is the answer I distilled (correct me if I misunderstood):
Since you need to define a return type of the function anyway, you cannot have a function returning one of two datatypes based on the input.
So there are basically four approaches:

Write two seperate functions
Have only one function and use datatype casting on the result
Combination of the above, where the second function is only a wrapper for the first function but with datatype casting.
Return both unsigned int and signed int register values as a signed long

Some extra info:
2.
When you cast between signed and unsigned of the same size, you are not changing the bits, you are just changing the way they are being interpreted. So that would work perfectly.
my_signed_register = (signed int)readUnsignedRegister(0x4B87)
my_unsigned_register = readUnsignedRegister(0xB357)

3.
 The same thing can be done in a function:
signed int readSignedRegister(byte theRegister) {
  return (signed int) readUnsignedRegister(theRegister);
}

(Also see the answer of Mikael Patel)
4.
If you want to use one function only, you could set the return type of the function to signed long. Because to represent both signed and unsigned ints you need signed long. You then read in the bits from the SPI.transfer in signed (or unsigned, whatever you like) and then change to signed long based on the type given in the function call 's' or 'u'.


text:
Why can't I declare variables inside an if statement?
I have a void function that helps me set the time on my arduino clock. I need to use the same function twice - once for the alarm and once for the actual time. The variables I am defining need to equal either alarmHours and alarmMinutes, or hours and minutes. This was my solution:
void setting(int i){
 if(i==0){
  int mi=alarmMinutes;
  int ho=alarmHours;
 }else if(i==1){
  int mi=minutes;
  int ho=hours;
 }
//more code later
}

I got an error saying that ho and mi are undefined.
I fixed this like this:
void setting(int i){

 int mi;
 int ho;

 if(i==0){
  mi=alarmMinutes;
  ho=alarmHours;
 }else if(i==1){
  mi=minutes;
  ho=hours;
 }
}

This solved the problem. Why couldn't I use the first option if I passed in a 0 or a 1 to the parameters of the function?

Declaring a variable inside a block means that they only exist within that block. Once the block is exited, they become inaccessible.

Before, I thought that only applies to functions. I guess it applies to all blocks of code, including the if statements.

Specifically, it applies to the nearest pair of enclosing braces, {}.

The problem with doing it how you originally did is that the variables you initialized inside the if statement do not go onto the else statement.
That is why your solution is correct. You need to declare your variables before going inside of a block in order to use them.
There are uses for declaring a variables inside of a block.. but this is not one of them as you realized and fixed.


text:
How to interpret accelerometer data to get decimals from -255 to 255
I'm using gy-521 module and I'm wondering how can i get useful readings from it so that i could work with the data that I'm receiving.
I want for AcX and AcY variable values to be from -255 to 255.
How to make this work.
sample data that I'm getting right now
X = 16380 Y = -64
X = 8116 Y = 3520
X = 12564 Y = 8728
X = -12652 Y = 1296
X = -17732 Y = -2420
X = -14576 Y = -2264

;
#include<Wire.h>
const int MPU_addr=0x68;
int16_t AcX,AcY;
void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  Serial.begin(9600);
}

void loop(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);
  AcX=Wire.read()<<8|Wire.read();
  AcY=Wire.read()<<8|Wire.read();

  Serial.print("X = "); Serial.print(AcX);
  Serial.print(" Y = "); Serial.println(AcY);

  delay(333);
}

And what are the values you are actually getting from it?

X = 16380 Y = -64
X = 8116 Y = 3520
X = 12564 Y = 8728
X = -12652 Y = 1296
X = -17732 Y = -2420
X = -14576 Y = -2264

Use this code:
AcX = map(AcX, -32768, 32767, -255, 255);
AcY = map(AcY, -32768, 32767, -255, 255);

Of course, you won't be able to store the resulting value in int8_t since its range is from -128 to 127.
Here you can read more about Arduino map() function.

Or just divide the values by 128 (the same as a right-shift by 7 bits).

That is correct. However, by using map() you can tweak the input/output ranges. The sensor maybe doesn't return values below some threshold and in that case using shift would result in lower resolution of the output.

could you give me an example

For example, if you notice the sensor never returns values below -25000 you can use AcX = map(AcX, -25000, 25000, -255, 255); to increase the output resolution. Of course, the maximum value that sensor returns, in that case must not be above +25000. If the maximum value is e.g. 26000 then you must use AcX = map(AcX, -26000, 26000, -255, 255);


text:
Where is the inaccuracy of my arduino thermistor circuit coming from?
I've setup four thermistors and a known resistor in series and connected them to the 3.3V output (as I've heard it's cleaner than the 5V) of an Arduino Uno (with the 3.3V also connected to ARef to increase accuracy), with the four analog inputs testing the voltage drop across each thermistor to determine its resistance, and hence temperature.
But even with no change in the thermistor temperatures, the voltages I get from the arduino vary significantly. See below an example readout of the four arduino inputs (with thermistor temperatures/resistances same throughout):
230 424 634 849
212 412 597 819
241 415 611 857
204 413 654 845
The accuracy I come out with is around 5-10 degrees - way more than I expected. Why is this? And what can I do to get it down to less than one degree? Many thanks
UPDATE:
A MASSIVE THANKYOU to all those who helped me on this, particularly @NickGammon, @Talk2 and most of all @JRobert for the brilliantly clear and simple to follow circuit instructions to follow, all of which helped to thoroughly solve my problem! The sensor works great now, many thanks!!

Have you check your thermistor specs for their rated accuracy ? Also your 3.3v Vref how stable is it ? Maybe attach a schematic and thermistor p/n may help providing a better answer.

Perhaps if you post your code? And the thermistor model? Are those analog input readings? If so, a reading of around 200 is only 20% of the range of the ADC (which can go up to 1023) so any errors are going to be amplified by 5.

Hi Andre and Nick, thanks for your comments. The thermistors are ATC Semitec 104GT-2 Gt Thermistor 100k 3% - rated %3 - but I've checked them with a multimeter and they're not source of this error. They'll flicker a KOhm (about 1%) either side of their resistnace but will not vary more than that. Some of the values above change 15% between readings. The 3.3Vref I was told was better than the 5V, that's all I know. I can draw you a schematic but its a very simple circuit as described with no extra bells and whistles so far

I can also post my code if you want but I don't see how it would help as the values above are literally the analog values themselves as measured by the arduino (using ARef as well). The code simply takes the analog input values, and converts them into temperatures using the steinhart equation. It also takes an average but this doesn't really help.

Nick, good point about how the voltage of each thermistor is being described by only 20% of the 1023 range of the analog inputs - but if this were to blame wouldn't this mean the values varied less, rather than more as you can see above?

You did set analogReference(EXTERNAL) before connecting AREF to 3.3V, right?

Please do show a schematic - or at the very least a photograph of your setup.

Hi Edgar, what do you mean by 'before'? My setup code sets analogreference(EXTERNAL), before the loop code if that's what you mean. But the 3.3V and ARef pins are already physically connected before I plug the arduino into the laptop.

@Andre and Majenko please see picture above

Wouldn't it be better to connect the themistors individually, instead of all in series? Inaccuracies in one sensor, will influence the others. Also, since you can only read one analog pin at a time, the value of the previously read themistor could have changed, when reading the next. I think you are also losing some range, as you have to share the range between 4 readings.

@Gerben how do you mean individually? Do you mean have one arduino per thermistor?

No. You have wired it so that each reading will be influenced by the values from the other thermistors. Why not have each one wired with their own resistor (for the voltage divider)? In fact, why have four anyway? They are all adjacent aren't they?

if this were to blame wouldn't this mean the values varied less, rather than more as you can see above? - yes perhaps, but the calculated temperature will lose precision. You will be converting 0-200 into degrees when you could be converting 0-1023 into degrees.

What I would like you to do is remove the "thermistors in series" effect. Take a single thermistor, and your 100k resistor, and take some readings. ie. +5V --- 100k --(A0)-- thermistor --- Gnd - see if a) It gives the desired temperature; and b) Do they vary by such a large amount?

My bad, as long as analogReference(EXTERNAL) is done before the first analogRead(), you are fine. 2) Now, I just did a small experiment. For lack of a suitable thermistor, I used an LDR with a 10 kΩ pullup. Out of 4399 readings, I only got 4 distinct values: 572 (11 times), 573 (1698 times), 574 (2599 times) and 575 (91 times). The RMS amplitude of the fluctuations was about 0.53 ADC steps. All this with the 5V reference.

Why are you using the voltage divider and measuring by parts? As @nickgammon points out, you are measuring only a 1/5 of full scale at each measurement, meaning your resolution is down by 5:1 over what the A/D is capable of. Also, the divider network comes to around 500KOhms. Work out the current through that and you get a very feeble <7 microAmps. The wires are antennas that could well be contributing noise at a significant fraction of that level.
Is there a reason for the divider circuit? Could you use a single thermistor from Vcc to Gnd plus a resistor in a 2-way divider? That will have the advantages of:

Using (more of) the full range of A/D;
Taking only one reading instead of several (and the several are necessarily skewed in time since you're multiplexing the one A/D);
A larger current (ok, only 33 microAmps, but 5x better than before);
Presumably less pickup into the network than with 5 leads. Keeping the measurement lead as short as possible may help, too.

Update:
Then you probably want a 2-component divider for each temperature you need to measure, paralleled between the power rails. I just guessed, not calculated, the resistances of R1, R3, R5, & R7. You'll want to estimate the maximum and minimum temperatures of interest in each channel and pick values that will give you the best ranges without drawing excessive currents when the thermistor values are low.

simulate this circuit – Schematic created using CircuitLab

No I need four temperature sensors for purpose. Could using smaller resistance thermistors help?

I still think that by connecting the thermistors in series you are summing the errors. So if the first one has a 1% error (or some jitter) then that will vary the voltage being received by the second one, and so on. I'm testing with a thermistor and a 100k resistor (not your thermistor exactly) and I am seeing a couple of mV jitter (probably noise being picked up).

Without exactly knowing part names, models and source code is difficult to tell what to expect. But a few techniques can be used to improve the stability of an analog reading. Here a few things you might want to consider:

Use INTERNAL vref of 1.1V, this is a very stable voltage reference
Use a stable/good quality series resistor, with little tolerance, like 1%
Add a 22pF capacitor, connecting the analog input to ground. This helps stabilizing the signal
Perform multiple consecutive readings, let's say 5 readings, and use the average. You might also want to remove the biggest and lowest values before averaging.

Hi Talk2, thanks very much for the suggestions. The parts are Arduino Uno SMD A000073 Board Rev3, ATC Semitec 104GT-2 Gt Thermistor 100k 3%, and Vishay CNS020 Series Radial Thin Film Resistor 100kΩ ±0.02% 0.5W ±10ppm/°C.

The values above are literally printouts of analog inputs (using Aref again), so the source code doesn't explain the variance in values there.

I do use an average in the main code, but it doesn't really help as the intial inputs are so variable.

What exactly do you mean by adding a 22pf capacitor between input and gnd? Do you mean wire the thermistors to the analog inputs and then from there to GND across the capacitor?

If I changed the 10 bit Uno for a 12 bit Due board, do you think that would improve the quality of the readouts?

or would it just increase the resolution, rather than the accuracy or precision of the analog readings above?

From 10bits to 12bits you only going to get more resolution. The Arduino analog ports are quite good for what you need. Why are you chain all the sensors? Have you tried with a single one? The capacitor needs to be between the Analog port and ground, so it works like a "buffer" to stabilize the voltage output from the voltage divider made of the Thermstor and the Resistor.

I may be mistaking, but what you did is a voltage divisor where you read the voltage across resistors in series (your thermistors).
When resistors are in series as you know you add their value. So A4 is reading the value across TR1+TR2+TR3+TR4. A3 is reading the value across TR1+TR2+TR3 and so forth.

Yes Andre I had worked that out - my code takes this into account. By taking the differential between voltage readings all the resistance values can be worked out. But I don't think any of this is relevant unfortuately as the analog readings themselves, before even being processed by the code at all, are so instable as you can see.

You did look at this reference right :
https://www.arduino.cc/en/Reference/AnalogReference


text:
ESP32 - BLE does not connect/restart after light sleep
noob in arduino here.
I'm trying to connect via BLE after the ESP32 wakeups from light sleep. I have tried many different things, but none of them work. Everything works fine before the device sleeps the first time. Could you guys please give some ideas of what is wrong? the official docs are terrible.

    btStop();
    delay(1000);
    esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
    Serial.println("Going to light sleep now");
    esp_light_sleep_start();
    btStart();

I finally found the answer, you just need to advertise again the service after it sleeps. First you need to define this:
#if CONFIG_PM_ENABLE
// Configure dynamic frequency scaling:
// maximum and minimum frequencies are set in sdkconfig,
// automatic light sleep is enabled if tickless idle support is enabled.
// esp_pm_config_esp32c3_t pm_config = { // old version
esp_pm_config_t pm_config = {
        .max_freq_mhz = 160, //  e.g. 80, 160,
        .min_freq_mhz = 80, // 40
#if CONFIG_FREERTOS_USE_TICKLESS_IDLE
        .light_sleep_enable = true
#endif
    };
ESP_ERROR_CHECK( esp_pm_configure(&pm_config) );
#endif // CONFIG_PM_ENABLE

Then in your loop you could do something like:
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
Serial.println("Going to light sleep now");
esp_light_sleep_start();
Serial.println("depois do sleep start");
BLEDevice::startAdvertising();


text:
ARDUINO DC Motor Control over IR Sensor INPUT
I'm working on a school project where I'm building a small convyeor belt using an ARDUINO, DC motor and IR sensor for moving object detection so my color sensor can read color value.
I'm using single mosfet IRFZ44N to control DC motor. I can control DC motor using mosfet normally as turning it ON/OFF using digitalWrite using an arduino.
So, I want to stop convyeyor belt for 500ms when IR sensor detects HIGH and let color sensor read color of object and then let object move ahead normally on belt.
I have written below code but the IR sensor detect object but motor never stops running.
#define IR_COLOR 34

const int MOTORpin = 32;
const long onDuration = 1000;// OFF time for LED
const long offDuration = 1000;// ON time for LED
int MOTORState =HIGH;// initial state of LED

boolean MOTOROnFlag          = true;

long rememberTime=0;

void setup() {
  pinMode(IR_COLOR, INPUT);
  pinMode(MOTORpin,OUTPUT);// define MOTORpin as output
  digitalWrite(MOTORpin,MOTORState);// set initial state
}

void loop() {

  int state = digitalRead(IR_COLOR);

 if( state == false )
 {
    if( (millis()- rememberTime) >= onDuration){
    MOTORState = LOW;
    rememberTime=millis();
    }
 }
 else if(state == true)
 {
    if( (millis()- rememberTime) >= offDuration){
    MOTORState =HIGH;// change the state of LED
    rememberTime=millis();// remember Current millis() time
    }
 }

 digitalWrite(MOTORpin,MOTORState);// turn the LED ON or OFF

}// loop ends

you have no IR sensor code

@jsotola IR_COLOR is IR Sensor.

what is IR_RED then?

@jsotola It was made for future work but the initial task is not completed of stoping motor pin for 500ms and starting motor again. Motor stops as IR detects object but it remains off as object is still ahead of IR sensor.

so what will you name the color sensor? ... it seems like you are using confusing names

insert a layer of separation between the sensor and the motor ... use a run flag ... set it at beginning ... sensor clears the flag and starts a timer ... timer expiration sets the flag .... further down in the code, if flag is set, then run motor

@jsotola I'm using total 5 IR sensor and 1 color sensor. as IR_COLOR is the first IR sensor which is close to color sensor so I named it as IR_COLOR. So, that's not a big issue for me. I will name color sensor as something COLOR_Sen.

@jsotola Please, can you provide demo code related to flag for arduino? You may edit mine code too if you wish!

you are already using a flag variable in your code ... it is named state

YES! It's little confusing to me! can you please insert your logic of clearing flag by sensor in my code?

pick a value for set and a value for clear ... true/false ... HIGH/LOW ... 1/-1 ... 10/20 ... "abc"/"xyz" ... etc. etc. ... right now your code uses HIGH and LOW ... true/false is the most convenient because the if statements operate on true/false ... if ( state ) {} and  if ( !state ){}

use pen and paper... write description of the desired behavior in words ... something like if sensor is LOW then clear the flag ... a clear description translates to code almost directly

I have edited my code a bit and here's it! I don't understant arduino flags so I wanted you to edit my basic code with flags!  Here's my edited code link:    https://drive.google.com/file/d/1ulzu5nnARIugKC4R7LD0-OWzkvYRSgdi/view?usp=sharing

there is no such thing as arduino flags ... this is C or C++ programming ... you are already using a flag variable in your code ... the flag name is state ... the value of the flag variable controls the motor if (state == LOW) digitalWrite(Motor, LOW);  ... I don't know if that turns the motor on or off ... I will not download anything from Google drive

@jsotola Indeed! But the problem lies with the timing! As, Object reaches ahead of IR sensor, the ESP32 turns off motor as mentioned in code but I want it to stay off for a few ms like 500ms and after 500ms it ESP32 should start the motor again even though IR sensor is detecting object! How can I translate this in code for arduino?

@jsotola I have edited the code in main post of mine! You may check that for reference!

You have the general idea.
Your code looks a bit cluttered. Comments are not part of the program, keep them away from the code.
The if statements reduce to if (true), that means that == true part is redundant.
All you need is if(state). The if block will execute when state is true.
Conversely if (!state) tests for state being false
When there are only two possible values, then else if(state == true) can be simply else.
Identical code that is in both parts of the if-else block should be moved to outside of the block, rememberTime=millis(); should be moved to after the closing brace } of the if-else block.
Here is some code that does what you want.
This code has not been tested on a hardware device.
https://wokwi.com/projects/364353854313747457
const int     sensor_blocked  = LOW;              // define sensor values
const int     sensor_clear    = HIGH;

const int     motor_on        = HIGH;
const int     motor_off       = LOW;

const int     master_enable   =  2;
const int     motor_pin       =  3;
const int     sensor_pin      = 12;

int           sensor_state;
int           sensor_previous = sensor_clear;
int           motor_state     = motor_on;

unsigned long millis_previous = 0;
unsigned long millis_now;

const long    interval        = 500;

void setup() {

  pinMode(master_enable, INPUT_PULLUP);
  pinMode(sensor_pin,    INPUT_PULLUP);
  pinMode(motor_pin,     OUTPUT);

}

void loop() {

  sensor_state = digitalRead( sensor_pin );

  // ---------------------------------------------------------------------------------------------------

  if ( sensor_state != sensor_previous ) {             // only run this code when sensor state changes
    sensor_previous = sensor_state;                    // remember new sensor state

    if ( sensor_state == sensor_blocked ) {            // sensor became blocked
      motor_state = motor_off;                         // turn off motor
      millis_previous = millis();                      // start of "motor off" interval
    }
    delay(20);                                         // debounce sensor
  }

  // ---------------------------------------------------------------------------------------------------

  if ( motor_state == motor_off ) {                    // timer check is relevant only when motor is off
    millis_now = millis();
    if ( millis_now - millis_previous >= interval ) {  // check if timer expired
      motor_state = motor_on;                          // enable motor
    }
  }

  // ---------------------------------------------------------------------------------------------------

  if ( digitalRead( master_enable ) != LOW ) motor_state = motor_off;     // master switch

  // ---------------------------------------------------------------------------------------------------

  digitalWrite(motor_pin, motor_state);                // translate motor state into action

}


text:
Use server.arg results as a function parameter?
I've got an ESP8266 (NodeMCU) and I am trying to understand the ESP8266WebServer library, as how to use the results across functions.
In my setup function, I have the following:
   server.on("/marquee", []() {
      varOne = server.arg("baseColor");
      varTwo = server.arg("marqueeColor");
      server.send(200, "text/html", webPage);
      Serial.println("Marquee  activated");
      state = true;
      ledMode = "marquee";
    });

In my loop, I detect the ledMode and if it is set to marquee then it runs the following FastLED function, amongst others:
fill_solid(leds, NUM_LEDS, 0xFF0000);

What I am trying to figure out is how I go from taking a hex color code of say FF0000 from the URL parameter, and use that in my fill_solid function.
server.arg stores get the parameter as a string, so I am not sure what needs to be done.  Also, using a variable name in place of the Hex code in the fill_solid function results in an error due to not expecting the variable

What argument types does fill_solid() take, please?

server.arg stores get the parameter as a string, so I am not sure what needs to be done.

The parameter needs to be converted to an uint32_t (and then to a CRGB or CHSV struct). The simplest way is to use the C library function strtoul
uint32_t color = strtoul(arg, NULL, 16);

This can be improved so that it checks that a number was scanned, etc.
Cheers!


text:
MAX31865 & NodeMCU RTD Low Threshold and Exception
I've got a NodeMCU V1 and a MAX31865 with a PT100 attached.  When using the example arduino code, it seems to log out the correct values but with an RTD Low Threshold error like so:
RTD value: 8068
Ratio = 0.24621582
Resistance = 105.87280273
Temperature = 15.09
Fault 0x40
RTD Low Threshold

The loop will continue for a few iterations and then throw an exception, before resuming logging out of the values above
The exception reads:
--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Soft WDT reset

>>>stack>>>

ctx: sys
sp: 3fffed00 end: 3fffffb0 offset: 01a0
3fffeea0:  38fe9521 00000000 3ffe8938 00000030
3fffeeb0:  401015ea 3ffe88f4 004ae1cb 40233b68
etc etc etc

The code is as follows.
#include <Adafruit_MAX31865.h>

// Use software SPI: CS, DI, DO, CLK
Adafruit_MAX31865 thermo = Adafruit_MAX31865(D4,D1,D2,D3);
//Adafruit_MAX31865 thermo = Adafruit_MAX31865(D4);

#define RREF      430.0
#define RNOMINAL  100.0

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

void loop() {
  uint16_t rtd = thermo.readRTD();
  Serial.print("RTD value: "); Serial.println(rtd);
  float ratio = rtd;
  ratio /= 32768;
  Serial.print("Ratio = "); Serial.println(ratio,8);
  Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
  Serial.print("Temperature = "); Serial.println(thermo.temperature(RNOMINAL, RREF));

  // Check and print any faults
  uint8_t fault = thermo.readFault();
  if (fault) {
    Serial.print("Fault 0x"); Serial.println(fault, HEX);
    if (fault & MAX31865_FAULT_HIGHTHRESH) {
      Serial.println("RTD High Threshold");
    }
    if (fault & MAX31865_FAULT_LOWTHRESH) {
      Serial.println("RTD Low Threshold");
    }
    if (fault & MAX31865_FAULT_REFINLOW) {
      Serial.println("REFIN- > 0.85 x Bias");
    }
    if (fault & MAX31865_FAULT_REFINHIGH) {
      Serial.println("REFIN- < 0.85 x Bias - FORCE- open");
    }
    if (fault & MAX31865_FAULT_RTDINLOW) {
      Serial.println("RTDIN- < 0.85 x Bias - FORCE- open");
    }
    if (fault & MAX31865_FAULT_OVUV) {
      Serial.println("Under/Over voltage");
    }
    thermo.clearFault();
  }
  Serial.println();
  delay(10000);
}

simulate this circuit – Schematic created using CircuitLab


text:
Arduino powered with 12v and interrupt noise
Hi i've a big problem with my project.
I realized a simple project with Arduino Uno: i've attached interrupt to pin 2 to read water flow.
If I power on Arduino from 5v usb all works as expected: my water counter (showed on an lcd) increase only if water pass trough the sensor flow.
But if poweron arduino with external 12v, the interrupt start immediately, also in no water passing trough sensor and also if i remove phisically the sensor from the circuit!!
Any suggest?
Flow sensor has 3 pins: vcc, gnd, data.
Data pin goes to pin 2 (interrupt), vcc to arduino 5v, and gnd with arduino gnd.

What flow sensor do you have exactly? And what 12V power supply?

@chrisl the flow meter is a yf-s201. But the sensor is not the problem, because the noise appear also if remove the sensor from my circuit. I use a power supply with output 12v/2.0A

Did you enable the internal pull-up on the Arduino? Are you using an external pull-up instead?

I ask because the sensor might need a pullup or pulldown resistor, which you don't currently use. A floating input pin (like when you disconnect the sensor without enabling the internal pullup) can change its state to whatever noise floats by, for example the noise from the 12V power supply. The example code that I found here enables the internal pullup resistor. Please do this via pinMode(pin, INPUT_PULLUP); , then report back if it worked

@itajackass you said that the interrupts occur when the sensor is not connected, so why are you even talking about the sensor?

@chrisl no luck. Setting it as INPUT_PULLUP instead INPUT, the problem of "noise" as gone.....but also the correct working is gone! The counter not increment, stay at 0, if I flow water inside sensor....

@itajackass Can you upload your code?

correct behavior disappearing from pullup could indicate bad sensor wiring as well.


text:
600VDC measurement with Arduino (voltage divider)
I need to detect quick (~200ms) voltage drop, so I am thinking of making an oscilloscope with Arduino. Problem is - can I reliably read 600V DC voltage and what resistor values should I choose for voltage divider? Can I apply same rules as for lower voltage (150k and 1k ohm)?

I think this would be better suited for electrical stackexchange

I'm probably going to regret asking, but: what is the actual application of this?

Welcome to SE/Arduino! -- Is the ground (reference) of the 600 VDC safe to touch? Like, you are measuring tram (public transport) power?

I think first of all you need a circuit to bring down the voltage to about 5volt otherwise 600volts will blow up your Arduino.

Here is the code
int vin=A2;
int inputstate;
float inputvalue;

void setup()
{
Serial.begin(9600);
pinMode(vin,INPUT);
}

void loop()
{
inputstate=analogRead(vin);
inputvalue=(inputstate*5.5)/(11.7)/0.8;
Serial.println(inputvalue);
}

It might works but it is hard for me to get the actual calculation  but you need to change this for your liking make this calculation,,
inputstate(which is your analogread pin maximum readings (1023)) × 5.0(you need to cange this on your calculation) / 11.7( or any number it can divide to give you 600.0)
So your calculation will be
1023 × 5.0 (or whatever number) / 11.0(or whatever number to get 600.0)
Once you have gotten your right calculation
You input  the numbers you calculated with in place of 5.0 and 11.0
You can remove 0.8 i added it base on my calculation to get 600.0.

I have put 1Mohm and 10Kohm resistors, which seem to work.

This should work but, if the 119 kΩ resistor ever fails short, one may end up with deadly voltage reaching the computer (and the user). It would be wise to split the circuit into a possibly-having-unsafe-voltage part, and a safe part, with some galvanic isolation between them. And have the design checked by someone qualified to handle high voltages.

@EdgarBonet nice idea edgar, 600v dc is deadly and might cause damage to not only the computer but also to the user

Try to design in an opto-coupler instead of using solutions which results in the Arduino sharing a ground and otherwise directly connected with a 600 Volts DC system. This will, however, detect only 600V or zero. For intermediate voltages it is not appropriate. There are, however, methods of using a PWM signal to represent a voltage which can cross an opto-coupler.

If the ground (reference) of the 600 VDC is safe to touch, multiple resistors in series are a good and common solution. Only one of them will break or get short, leaving the others as safety measure.

Be aware that resistors have a maximum voltage rating. It is normal to use a chain of smaller resistors to spread the voltage between them. For instance ten 75V 100kΩ resistors in series would give 1MΩ at 750V rating. Assuming you design your PCB layout with the correct clearances etc. At 600V you need to be very careful with your PCB design.


text:
Arduino Uno stops accepting command from PS3 Wireless controller?? although it remains connected!
so I was trying to control a bot wirelessly with the help of ps3 controller and USB host shield, i am using Arduino UNO as micro-controller. I was able to connect PS3 controller with Arduino and checked all button presses. It works very smoothly for button presses and shows on serial monitor which button was pressed without any lag. But the issue I am facing is that when I try to call any function on button press, the entire function is getting executed and execution comes back to void loop but Arduino stops accepting commands from ps3. But it shows that PS3 is still connected and the connection isn't lost. I went through different blogs and I found out that some say that issue is with new HOST SHIELD library 2.0 and some say that UNO computation takes time.
this is what I have tried.
#define motopinl1 8
#define motopinr1 9
# define motopine1 10

#define motopinl2 11
#define motopinr2 12
#define motopine2 13

#define val 200

void setup() {
Serial.begin(115200);
#if !defined(__MIPSEL__)
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
if (Usb.Init() == -1) {
  Serial.print(F("\r\nOSC did not start"));
  while (1); //halt
}
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
}

void moveforward()
{

// digitalWrite(motopinl1,LOW);
digitalWrite(motopinr1,LOW);
digitalWrite(motopinl2,LOW);
// digitalWrite(motopinr2,LOW);
analogWrite(motopine1,200);
analogWrite(motopine2,200);
// digitalWrite(motopinl1,HIGH);
//digitalWrite(motopinr2,HIGH);

Serial.println("MoveForward called");
Usb.Task();

}

void moveBackward()
{

digitalWrite(motopinl1,LOW);
//  digitalWrite(motopinr1,LOW);
// digitalWrite(motopinl2,LOW);
digitalWrite(motopinr2,LOW);
analogWrite(motopine1,200);
analogWrite(motopine2,200);
// digitalWrite(motopinr1,HIGH);
//digitalWrite(motopinl2,HIGH);

Serial.println("Movebackward called");
Usb.Task();
}

void moveleft()
{

digitalWrite(motopinl1,LOW);
// digitalWrite(motopinr1,LOW);
digitalWrite(motopinl2,LOW);
// digitalWrite(motopinr2,LOW);
analogWrite(motopine1,200);
analogWrite(motopine2,200);
// digitalWrite(motopinr2,HIGH);
//digitalWrite(motopinr1,HIGH);

Usb.Task();
Serial.println("Moveleft called");
}

void moveright()
{

// digitalWrite(motopinl1,LOW);
//digitalWrite(motopinr1,LOW);
digitalWrite(motopinl2,LOW);
digitalWrite(motopinr2,LOW);
analogWrite(motopine1,200);
analogWrite(motopine2,200);
// digitalWrite(motopinl1,HIGH);
//digitalWrite(motopinl2,HIGH);

Serial.println("Moveright called");
Usb.Task();
}

void stopit()
{
digitalWrite(motopinl1,LOW);
digitalWrite(motopinr1,LOW);
digitalWrite(motopinl2,LOW);
digitalWrite(motopinr2,LOW);
analogWrite(motopine1,0);
analogWrite(motopine2,0);
Usb.Task();
}

void loop() {
Usb.Task();

if (PS3.PS3Connected || PS3.PS3NavigationConnected) {
  if (PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
   // Serial.print(F("\r\nLeftHatX: "));
    //Serial.print(PS3.getAnalogHat(LeftHatX));
    //Serial.print(F("\tLeftHatY: "));
    //Serial.print(PS3.getAnalogHat(LeftHatY));
    if (PS3.PS3Connected) { // The Navigation controller only have one joystick
      //Serial.print(F("\tRightHatX: "));
      //Serial.print(PS3.getAnalogHat(RightHatX));
      //Serial.print(F("\tRightHatY: "));
      //Serial.print(PS3.getAnalogHat(RightHatY));
    }
  }

  // Analog button values can be read from almost all buttons
  if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) {
    Serial.print(F("\r\nL2: "));
    Serial.print(PS3.getAnalogButton(L2));
    if (PS3.PS3Connected) {
      Serial.print(F("\tR2: "));
      Serial.print(PS3.getAnalogButton(R2));
    }
  }

  if (PS3.getButtonClick(PS)) {
    Serial.print(F("\r\nPS"));
    PS3.disconnect();
  }
  else {
    if (PS3.getButtonClick(TRIANGLE)) {
      Serial.print(F("\r\nTriangle"));
      moveforward();
      PS3.setRumbleOn(RumbleLow);
    }
    if (PS3.getButtonClick(CIRCLE)) {
      Serial.print(F("\r\nCircle"));
      PS3.setRumbleOn(RumbleHigh);
      moveright();
    }
    if (PS3.getButtonClick(CROSS))
    {
        Serial.print(F("\r\nCross"));
        moveBackward();
    }
    if (PS3.getButtonClick(SQUARE))
    {
      Serial.print(F("\r\nSquare"));
      moveleft();
    }

    if (PS3.getButtonClick(UP)) {
      Serial.print(F("\r\nUp"));
      stopit();
      if (PS3.PS3Connected) {
        PS3.setLedOff();
        PS3.setLedOn(LED4);
      }
    }
    if (PS3.getButtonClick(RIGHT)) {
      Serial.print(F("\r\nRight"));
      if (PS3.PS3Connected) {
        PS3.setLedOff();
        PS3.setLedOn(LED1);
      }
    }
    if (PS3.getButtonClick(DOWN)) {
      Serial.print(F("\r\nDown"));
      if (PS3.PS3Connected) {
        PS3.setLedOff();
        PS3.setLedOn(LED2);
      }
    }
    if (PS3.getButtonClick(LEFT)) {
      Serial.print(F("\r\nLeft"));
      if (PS3.PS3Connected) {
        PS3.setLedOff();
        PS3.setLedOn(LED3);
      }
    }

    if (PS3.getButtonClick(L1))
      Serial.print(F("\r\nL1"));
    if (PS3.getButtonClick(L3))
      Serial.print(F("\r\nL3"));
    if (PS3.getButtonClick(R1))
      Serial.print(F("\r\nR1"));
    if (PS3.getButtonClick(R3))
      Serial.print(F("\r\nR3"));

    if (PS3.getButtonClick(SELECT)) {
      Serial.print(F("\r\nSelect - "));
      PS3.printStatusString();
    }
    if (PS3.getButtonClick(START)) {
      Serial.print(F("\r\nStart"));
      printAngle = !printAngle;
    }
  }
#if 0 // Set this to 1 in order to see the angle of the controller
  if (printAngle) {
    Serial.print(F("\r\nPitch: "));
    Serial.print(PS3.getAngle(Pitch));
    Serial.print(F("\tRoll: "));
    Serial.print(PS3.getAngle(Roll));
  }
#endif
}
#if 0 // Set this to 1 in order to enable support for the Playstation Move controller
else if (PS3.PS3MoveConnected) {
  if (PS3.getAnalogButton(T)) {
    Serial.print(F("\r\nT: "));
    Serial.print(PS3.getAnalogButton(T));
  }
  if (PS3.getButtonClick(PS)) {
    Serial.print(F("\r\nPS"));
    PS3.disconnect();
  }
  else {
    if (PS3.getButtonClick(SELECT)) {
      Serial.print(F("\r\nSelect"));
      printTemperature = !printTemperature;
    }
    if (PS3.getButtonClick(START)) {
      Serial.print(F("\r\nStart"));
      printAngle = !printAngle;
    }
    if (PS3.getButtonClick(TRIANGLE)) {
      Serial.print(F("\r\nTriangle"));
      PS3.moveSetBulb(Red);
    }
    if (PS3.getButtonClick(CIRCLE)) {
      Serial.print(F("\r\nCircle"));
      PS3.moveSetBulb(Green);
    }
    if (PS3.getButtonClick(SQUARE)) {
      Serial.print(F("\r\nSquare"));
      PS3.moveSetBulb(Blue);
    }
    if (PS3.getButtonClick(CROSS)) {
      Serial.print(F("\r\nCross"));
      PS3.moveSetBulb(Yellow);
    }
    if (PS3.getButtonClick(MOVE)) {
      PS3.moveSetBulb(Off);
      Serial.print(F("\r\nMove"));
      Serial.print(F(" - "));
      PS3.printStatusString();
    }
  }
  if (printAngle) {
    Serial.print(F("\r\nPitch: "));
    Serial.print(PS3.getAngle(Pitch));
    Serial.print(F("\tRoll: "));
    Serial.print(PS3.getAngle(Roll));
  }
  else if (printTemperature) {
    Serial.print(F("\r\nTemperature: "));
    Serial.print(PS3.getTemperature());
  }
}
#endif
}```

I haven't connected to bot. I was checking whether function are being executed on button press or not or serial monitor. so there cannot be issue of power supply. problem is PS3 still remains connected, also line of execution returns to void loop, then why it stops further commands. please please do suggest any ideas and methods by which I can solve this problem. thank you.

I found that when you use delay inbuilt function, it completely blocks Arduino from accepting any command, that causes some communication barrier. Although ps3 remains connected, it doesn't accept commands. so all you have to do is to remove all delays from your function and build logic based Millis.