text:
Can I connect 220V AC supply to Node MCU (or any arduino)pin D1 and D3 while node MCDU is power off?
Can I connect 220V AC supply to node MCU pin D1 and D3 while node MCDU is power off?

Are you trying to kill yourself? 220V can be fatal. Go and talk to a qualified electrician before you do anything more.

Short answer: HELL no. You should not connect AC supply lines to any low voltage pins, under any circumstances. The insulation on the wires is not sufficient for that voltage, and it would pose a serious risk of fatal injury. Oh by the way, it would fry your Arduino, but that is not important compared to killing anybody who touched anything connected to the Arudino.

No, never! 220V is way way way too much for a microcontroller. The Uno runs on 5V, the ESP8266 on 3.3V. You should never connect any more voltage than that to the microcontroller. Also you must not connect a negative voltage to the microcontroller pins.
Besides the voltage difference: You should also not connect a voltage to the pins of a microcontroller, while the microcontroller itself is turned off (meaning that it does not have the necessary supply voltage). In that case a parasite current would run through the clamping diodes, which powers the microncontroller, until the diodes get blown.

As an important side note: Don't do anything with mains power (like 220V AC), until you really know, what you are doing!!! One error and it can kill you !!!


text:
Intercepting Keyboard Data on a Micro Controller
Recently I have purchased male and female USB-C breakout boards. I intend to connect the male breakout to a keyboard and the female end to my computer using a USB-C cable and wire the breakouts together using a breadboard. I was wondering if it is possible to read the keystrokes being sent across the D- and D+ lines with a micro-controller.
Here is an image of how I currently have the breakout boards setup

Just a suggestion, you should probably edit your question and replace Micro Controller with Arduino so as not to be off topic.

Welcome to SE/Arduino! Please take the [tour] to learn how this site works, and read "[ask]". -- Would you mind to [edit] your question and extend on the reason, please? -- It is much simpler to capture key presses in the receiving operating system, or in the keyboard before being transmitted. USB is quite complex "on the wire," however, you might try what small logic analyzers are doing. These commonly have special hardware involved, a simple device like the microcontroller of an Arduino cannot do it.

You may want to take a look at this video. The author decodes the USB HID protocol by hand, with pen and paper.

It would be far far easier to interface an Arduino to an old PS2 keyboard.
USB is complex.  You would have to understand USB protocol, then understand the HID (Human Interface Device) protocol inside of the USB protocol.  As HID can interface a number of devices like mice and keyboards, you might have to then understand the keyboard portion of the HID protocol.
As a point of reference, commercial USB analyzers cost hundreds of dollars.  This USB analyzer cost about $500.
As an alternative, have you considered an all software USB monitor? These normally reside on the same computer as the USB Device is attached to. Wireshark should be able to do this.
Also, assuming that is a Pro Micro used on the keyboard, consider adding code to its Atmel processor to send out keyboard activity on an unused pin. This approach might proved much easier then monitoring the keyboard after its data has been incorporated into the USB protocol.

I don't want to discourage you.  I just what to point out the difficulties of creating a USB interface.  Especially one that is not a USB Device or USB Host (i.e. one that can monitor but will not enumerate or try to take control of the USB).

This is a really old thread that discusses a USB Sniffer. Even back then (likely only USB 3.0 existed at the time) it was thought to be a really difficult task.

OP doesn't want a general USB sniffer. only keyboard

Btw you can use Wireshark to catch USB communication directly on the system. His question looks more like XY problem. If he has everything on the photo, he could just program it directly into that on-keyboard MCU (looks like Pro Micro with usb-c?)

@Juraj, I think once you start using USB to communicate you are going to have to buy into the entire USB protocol.  But please follow up w/links to project that monitor only a USB/HID/Keyboard.  I would be fun to figure out how they did it!

Good points @KIIV.  I forgot about Wireshark.  And you are correct, That Pro Micro should be able to monitor and spit out the keyboard activity way easier than picking apart the USB signal.

so my though is that there are Arduino projects with keyboard as input and there are projects where the Arduino is the keyboard. so it should be enough to copy keys from input to output. but of course with the keyboard on the photo the keyboard is already an Arduino.

I see, I was hoping for a simple way to have a microcontroller (like another Pro-Micro for example) to read in key inputs sent over USB. Creating a USB interface seems like it is currently out of my scope.

You can try @Juraj 's idea.  But you can't have 2 keyboards.  Well, you might be able to ... but you don't want 2 keyboards.  You want 1 keyboard and something that will listen.  So you need to keep the new keyboard from getting enumerated by the USB host.  But you still need it to listen.  This is where I'm in unknown waters.  It's almost like you need the listener to act like the 1st keyboard except it can not talk back.  This isn't just out of your scope, it's out of most of our scopes!

Micro can't be an USB host. USB host shield would have to be used to read an USB keyboard. but again. here the keyboard is already an Arduino.

source: Stack Exchange

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

sort: votes


text:
How does actually arduino measure voltage?
I am not interested into the AnalogRead() part, but rather on how he converts 5 or 2 V into a number between 0 and 1023. How does it practically do it to convert the voltage level into a number or into bits to then send to the processor? Thanks in advance

https://en.wikipedia.org/wiki/Analog-to-digital_converter

The ATmega328P features a 10-bit successive approximation ADC. The ADC is connected to an 8-channel Analog Multiplexer.

First, an input is selected from the multiplexer on the left. This allows any of 8 input channels to be active at one time (but only one). These are: A0 to A5 on the Uno (some boards also have A6 and A7). There are also additional input channels (not shown) which also allows the selection of:

The internal temperature sensor
Ground
Bandgap reference voltage

The input channel (multiplexer output) is connected to a "sample and hold" capacitor, as shown. Once an analog conversion starts the switch is opened after 1.5 ADC cycles (12 µs with the default prescaler of 128) so that the capacitor retains its current reading (ie. it holds it) so that the input voltage can now change without affecting the result. This would be useful for fast-changing signals, as the whole conversion can take 104 µs (depending on the prescaler).
To work out the voltage the logic applies the analog reference voltage (ARef) divided down by a DAC (digital-to-analog converter) under the control of the ADC logic. The output of the DAC is sent to the comparator which determines if the input voltage is higher or lower than the reference voltage, at its current divided state. For example, the high-order bit would be set or cleared by setting the DAC to divide the reference voltage by 2 (ie. 2.5V if ARef is 5V). If the input is higher than 2.5V then the high-order bit in the result is set. This takes one ADC cycle (8 µs at the default prescaler of 128 with a 16 MHz processor clock).
To get the next result bit the DAC would be set to the next step (ie. 0.25 of ARef or 0.75 of ARef depending on whether the first bit was set or not) and another comparison done. This process is repeated for all 10 bits.

The Arduino Uno is powered by an ATmega328P microcontroller. According
to the datasheet:

The ATmega48A/PA/88A/PA/168A/PA/328/P features a 10-bit successive
approximation ADC.

On the next page, you can see the following schematic, where I have
highlighted the most essential parts of the converter. You can see the
DAC, the comparator, and the SAR data register.

If you want to get into the details of how this works, see the Wikipedia
article on Successive-approximation ADC. You may notice the
schematic at the top of that Wikipedia page is somewhat similar to the
one above.

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


text:
Using SPI on Pi Pico, Arduino IDE
Beginner with the Pi Pico here, but I studied electronics engineering and am reasonably hardware literate. I've used mbed online for a project prior to covid.
I want to use SPI to connect to a display using the ILI9488, (480 x 320 TFT panel), however, I cannot see how or where I would define SPI pins, and my understanding is that using SPI.h would default to Arduino pinouts - the uno etc being pin incompatible with the pi pico.
Do I need to trudge through the SPI.h file to try to work out how I set the pins manually? Or am I barking up the wrong tree?
I am using macOS, Arduino IDE 2.1.1 and have no issues connecting to the pico W. Please ask for any other clarification, I can provide a schematic of my design if it makes things easier. Love the pico but am finding it hard to use with C/C++.
Thanks,
KL

the pins are defined in the variants file for the selected board so the SPI library has the pins specific for the board

Depend on which Arduino Core you installed. The variants definition of Arduino Core describe the pin assignments for each board. There are two Arduino Core for Pico, the board variants definitions for the one by Earle Philhower can be found here, another one based on mbed by Arduino is here.

You can read the actual SPI pins with the following sketch
    void setup() {
      Serial.begin(115200);
    }

    void loop() {
      Serial.print("MOSI: ");
      Serial.println(MOSI);
      Serial.print("MISO: ");
      Serial.println(MISO);
      Serial.print(" SCK: ");
      Serial.println(SCK);
      Serial.print("  SS: ");
      Serial.println(SS);
      Serial.println();
      delay(5000);
    }

As Juraj wrote, they are defined in the board files.
I have no experience with your ILI9488 display and the corresponding library. Many libraries allow you to use software defined pins. I would not recommend that, especially for a display with 480 x 320 pixels. You really need the speed of the hardware SPI.


text:
ESP-IDF logging library slows down ISR processing
I'm hacking a project with ESP32-WROOM module. I'm running some timers with alarms along with some peripherals triggering ISRs. In the ISR routine I'm sending events to a queue, and receiving them in a task. Normally I'm seeing ~50 micros delay between ISR routine and the task.
I added the esp_log component for logging to UART. If I call some ESP_LOGx in the task after receiving the queue event, the aforementioned delay grows to 25 millis in some cases (depending on the amount of logging).
What's the reason? Does esp_log have longish noInterrupt sections internally? Is there any way to avoid them? Any other remedies?
Those delays are quire troublesome because on one hand I need logging to get things working. On other hand those delays turn all the timings upside down...
I actually switched to esp_log form hand-rolled logger. In my logger I had a 5k fifo queue for log data. The logging calls would format strings and push them into the queue. A low priority task would pop the data and print it to the UART. It was much better in terms of performance. I switched to esp_log for richer functionality, but ... Going back unless there is a fix.

Since your logger uses the UART, you need to take the transmission time into account.
Supposing that you use a 9600 baud line and send about 25 bytes.
A single byte has 10 bits on the wire, start bit, data bits, and at least one stop bit. There are more options to the protocol, but this is it basically.
Each bit takes 1/9600 seconds, this is the definition of 9600 baud. (Actually, this is oversimplified, but nevertheless a correct number here.) 10 bits of one byte take t_Byte = 10 / 9600 s = 1.042 ms.
To send 25 bytes, this sums up to about 25 ms.
Lesson learned: do not log directly to UART in a time critical task. You found the common solution by queuing the bytes to send. Just make sure that the queue will not fill up in the long term.

that makes sense, I realized I can redefine vprintf function esp_log_set_vprintf and implement buffering and flushing the buffer asynchronously


text:
I would like to know why my four gear motors are rotating at different speeds when connected to 2 L293D motor drivers, controlled by the arduino
Ignore direction of the motors(for now).
This is my connection diagram. Any and all improvements to this are welcome.
Bottom left motor seems to run at 210-224 rpm
Bottom right motor runs at 160-180 rpm
Top right motor runs at 210-224 rpm
Top left motor runs at 160-180 rpm

Code for running the below setup:

// Motor A connections

int enA = 7;

int in1 = 4;

int in2 = 5;

// Motor B connections

int enB = 6;

int in3 = 3;

int in4 = 2;

//Motor c

int enC = 9;

int in5 = 12;

int in6 = 13;

// Motor d connections

int enD = 8;

int in7 = 10;

int in8 = 11;

void setup() {

// Set all the motor control pins to outputs
pinMode(enA, OUTPUT);
pinMode(enB, OUTPUT);
pinMode(in1, OUTPUT);
pinMode(in2, OUTPUT);
pinMode(in3, OUTPUT);
pinMode(in4, OUTPUT);
pinMode(enC, OUTPUT);
pinMode(enD, OUTPUT);
pinMode(in5, OUTPUT);
pinMode(in6, OUTPUT);
pinMode(in7, OUTPUT);
pinMode(in8, OUTPUT);

  // Turn off motors - Initial state
digitalWrite(in1, LOW);
digitalWrite(in2, LOW);
digitalWrite(in3, LOW);
digitalWrite(in4, LOW);
digitalWrite(in5, LOW);
digitalWrite(in6, LOW);
digitalWrite(in7, LOW);
digitalWrite(in8, LOW);
}

void loop() {
  moveForward();
  delay(3000);
  motorOff();
  delay(1000);
}

void moveForward(){

  analogWrite(enA, 200);
  analogWrite(enB, 200);
  analogWrite(enC, 200);
  analogWrite(enD, 200);

  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
  digitalWrite(in5, HIGH);
  digitalWrite(in6, LOW);
  digitalWrite(in7, HIGH);
  digitalWrite(in8, LOW);
}

void motorOff(){
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
  digitalWrite(in5, LOW);
  digitalWrite(in6, LOW);
  digitalWrite(in7, LOW);
  digitalWrite(in8, LOW);
}

Any change to the code is also welcome.

Pins 7 and 8 aren't PWM pins on the UNO.  So when you call analogWrite on them with a value greater than 127 it defaults to digitalWrite and just writes those pins HIGH.  Pins 6 and 9 are PWM pins, so they are responding as expected to the analogWrite.  Since they are outputting PWM and the signal to the other motors is constantly high, they run slower.
You should change your wiring so that all of the enable pins are connected to PWM capable pins.  On the Arduino UNO those are pins 3, 5, 6, 9, 10, and 11.


text:
Upgrade ESP-01 firmware on MacOS
I recently bought an ESP-01 as well as an FTDI programmer (3.3v-5v) and after typing AT+GMR I noticed it said:

AT version:0.40.0.0(Aug  8 2015 14:45:58)
SDK version:1.3.0
Ai-Thinker Technology Co.,Ltd.
Build:1.3.0.2 Sep 11 2015 11:48:04

I have looked and looked on a way to upgrade its firmware (on MacOS) to no avail. How can I upgrade it? I want to be able to change the baud rate to 9600. A lot of examples to do it are in windows requiring another application or something like that but how can I do it in a Macbook? Thanks.

use esptool. the firmware binaries are on Espressifs site. the latest versions don't fit into esp-01's flash memory

"I want to be able to change the baud rate to 9600", what do you mean by that? Is that the reason you want to upgrade firmware? The firmware came as binary file, you won't be able to change that. Default baud rate of esp-01 is 115200 bps. You can change it via AT command, run a bare minimum sketch and type in AT+UART_DEF=9600,8,1,0,0 to make the change, the command _DEF will make the setting persistent.

Sorry im really new to Arduino and ESP in general, I read that you need to have both the Arduino and ESP in the same baud rate and to do that I need to upgrade my firmware (please correct me if im wrong).

Here is the step-by-step on upgrade the ESP-01 AT Command firmware (for running on macOS).
Wiring
For flashing the ESP-01 firmware, you need to have a USB-TTL adaptor as a programmer.
+---------------------+---------+
|                     | RxD Vcc |
|       Top View      | IO2 RST |
|                     | IO0 CPD |
|                     | GND TxD |
+---------------------+---------+

ESP-01          USB-TTL Adaptor
 VCC   ---------- 3V3
 GND   ---------- GND
 TxD   ---------- RxD
 RxD   ---------- TxD
 CH_PD ---------- see note* below
 GPIO0 ---------- Connect to a push switch (Flash button) to GND
 RST   ---------- a push switch (Reset button) to GND

Note: depend on whether you have ESP-01 or ESP-01S, for ESP-01, you will need to connect CH_PD either directly to 3v3 or via a 3k-10k resistor to 3v3. However, you don't need an extra pull-up resistor for ESP-01S as CH_PD already has on-board pull-up resistor. This picture shows the different between ESP-01 and ESP-01S, visually ESP-01 has 2 LEDs on board near the antenna, while ESP-01S have two extra resistor between header pins and ESP8266EX chip, and with only one LED.

Download and install esptool
Download and install esptool from https://github.com/espressif/esptool. esptool is a python application. You need to have python installed as well.
Download firmware 2.1
Download ESP8266 nonOS SDK - Release 2.1.x, noticed that this is not the latest version as the latest version doesn't works for ESP-01 based on my experience.
Upgrade the firmware
You will actually only need 4 files for the upgrade, I would suggest that you copy and paste those files into your esptool directory from the downloaded bin/ directory. cd into your esptool directory and run the following commands to upgrade the firmware.
To put ESP-01 into programming mode:

Press and hold Flash(GPIO0) button;
Press Reset button once, this will put ESP-01 in programming mode;
Press Reset to start the newly uploaded program when upload is completed.

./esptool.py --port /dev/cu.SLAB_USBtoUART write_flash 0x00000 boot_v1.7.bin
./esptool.py --port /dev/cu.SLAB_USBtoUART write_flash 0x01000 user1.1024.new.2.bin
./esptool.py --port /dev/cu.SLAB_USBtoUART write_flash 0x7c000 esp_init_data_default.bin
./esptool.py --port /dev/cu.SLAB_USBtoUART write_flash 0x3e000 blank.bin
./esptool.py --port /dev/cu.SLAB_USBtoUART write_flash 0x7e000 blank.bin

Please noted that /dev/cu.SLAB_USBtoUART is the USB port for my USB-TTL interface, yours might be different, run ls /dev/tty.* to find out your USB port

the AT binaries are published separately from SDK too. https://www.espressif.com/en/support/download/at?keys=&field_type_tid%5B%5D=14

usual is to run esptool as one command started in the at firmware's folder esptool.py write_flash --flash_size 2MB-c1 0x0 boot_v1.7.bin 0x01000 at/1024+1024/user1.2048.new.5.bin 0x1fb000 blank.bin 0x1fc000 esp_init_data_default_v08.bin 0xfe000 blank.bin 0x1fe000 blank.bin (this command is for AT 1.7 and 2 MB or more flash)

@Juraj  You have ESP-01 with 2MB? I never saw any ESP-01 came with 2MB flash unless I buy chip and replace it. Usually I saw  it either come with 512kB or 1MB.

I didn't say that it is for esp-01. I have a command for a 2 MB module so I pasted it as example.

I see. Thanks for the one liner.

I think you might mention that esp-01 need a decent power supply with s good amount of current to prevent any problems while flashing... Definitely I wouldn't suggest connecing Esp's vcc to the USB-TTL but to an external power supply..... If I am wrong please tell me I am a student and I am learning so I can be wrong

@ShamsEl-Deen  Yes, esp-01 could take as much as 170mA during communication, and the short burst of increase of current could cause the drop of voltage down to 3v, and that will cause esp-01 to crash. A good power source of 250mA with a large cap will be sufficient. In my case, my USB-TTL happened to be able to power that while all my Arduino boards (Uno, Leonardo, Nano) failed to power ESP-01.

You use esptool.py available from github.
It's exactly the same usage regardless of which operating system you are using (apart from the serial port device name of course), so instructions for Linux (for example) are the same as instructions for Mac OS X.

The OP doesn't need to upgrade the ESP's firmware, despite that that's what the question said. They apparently want to change its baud rate. That is doable with an AT command in the existing firmware, as described @hcheung described in a comment.
See my answer to a similar question here, noting especially, the last few lines of that post which is essentially a script for manually making the change. Note also, that this is not at all host operating system specific; everything is done with a sketch like the one in that question, and the Arduino IDE Serial Monitor.


text:
How to move a servo with a function
Im currently moving a servo from one side to another by using the typical for loop like this:
int lightON = 180;
int lightOFF = 90;

if (buttonState == HIGH) {

  digitalWrite(LED, HIGH);
  for (pos1 = lightOFF; pos1 <= lightON; pos1 += 1) {
    servo1.write(pos1);
    delay(15);
  }
  digitalWrite(LED, LOW);

}

That would be moving the servo one way and if I push the button again the servo would move another way.
if (buttonState == LOW) {

  digitalWrite(LED, HIGH);
  for (pos1 = lightON; pos1 >= lightOFF; pos1 -= 1) {
    servo1.write(pos1);
    delay(15);
  }
  digitalWrite(LED, LOW);

}

The thing is, I have this very same code in 3 other servos and I don't want to be repeating the same code with 2 different variables (pos and servo) over and over again, so I tried
void runServoLight(int pos, int light1, int light2, Servo servo, int state) {

  if (state == 1) {

  digitalWrite(LED, HIGH);

  for (pos = light1; pos <= light2; pos += 1) {
     servo.write(pos);
     delay(15);
  }

  digitalWrite(LED, LOW);

  } else if (state == 0) {

  digitalWrite(LED, HIGH);

  for (pos = light2; pos >= light1; pos -= 1) {
    servo.write(pos);
    delay(15);
  }

  digitalWrite(LED, LOW);

  }

}

Now instead of running the whole for loop code I only run:
runServoLight(pos1, lightON, lightOFF, servo1, 1);

The problem is that it doesn't seem to work and I can understand why, I may be writing the function wrong but im nor really sure. I would really appreciate some help. Thank you!

In your function, light1 needs to be lower than light2. Looks like you got those mixed up in the call.

You wrote:

void runServoLight(
        int pos, int light1, int light2, Servo servo, int state)

Here you are giving the list of parameters used by the function. In C++,
parameters are by default passed by value. This means that, when the
function is called, the arguments passed in the call are copied into
the parameters listed here, which are local variables of the function.
Changes to those parameters will not propagate to the arguments provided
by the caller.
This can be an issue for the Servo object. This object keeps some
internal state, which has the memory of the current configuration of the
timers. Since you are working on a copy of the provided object, the
original object is not updated when you act on the copy. I do not know
whether this is making your program misbehave, but it would be safer to
pass the Servo object by reference:
void runServoLight(
        int pos, int light1, int light2, Servo &servo, int state)

This way the object will not be copied: the function will instead work
on the original object provided by the caller.
The same may apply to the pos parameter. The very first thing the
function does with this parameter is to overwrite it. Then there is no
point in receiving that value from the caller. You can instead remove
the parameter and create a local variable with the same name:
void runServoLight(int light1, int light2, Servo &servo, int state) {
    int pos;  // local variable
    ...
}

If you want the caller's version of this variable to be updated, you
could pass it by reference, just like the Servo object. It is,
however, more efficient to keep the variable local and have the function
return the final position. The call would then look like:
pos1 = runServoLight(lightON, lightOFF, servo1, 1);

One final point that is not visible in the snippets you showed: are you
doing edge detection on the buttons? Edge detection means that you act
on the changes of state of the buttons, not on the states themselves.
For example, you move from lightOFF  to lightON not when the button
state is HIGH but rather when it turns HIGH.

This is not a solution, however, by rafactoring it makes your sketch more maintainable as duplicated code is removed:
void runServoLight(int pos, int light1, int light2, Servo servo, int state)
{
  if (state == 1) {
    process(light1, light2, +1, servo);
  }
  else if (state == 0) {
    process(light2, light1, -1, servo);
  }
}

def process(int this_light, int other_light, int delta, Servo servo)
{
  digitalWrite(LED, HIGH);
  for (pos = this_light; pos >= other_light; pos += delta) {
    servo.write(pos);
    delay(15);
  }
  digitalWrite(LED, LOW);
}

Instead of the state integer, it's more clear to use an enumeration and use a switch statement.
#include "Servo.h"

const int LED = 13;

enum EServoState { LEFT, RIGHT };

void runServoLight(int light1, int light2, Servo servo, EServoState state);

void setup()
{
}

void loop()
{
  int light1 = 1;
  int light2 = 2;
  EServoState state;
  Servo servo;
  runServoLight(light1, light2, servo, state);
}

void runServoLight(int light1, int light2, Servo servo, EServoState state)
{
  switch (state)
  {
  case LEFT:
    process(light1, light2, +1, servo);
    break;

  case RIGHT:
    process(light2, light1, -1, servo);
    break;

  //default:
   // Handle program error
  }
}

void process(int this_light, int other_light, int delta, Servo servo)
{
  digitalWrite(LED, HIGH);
  for (int pos = this_light; pos >= other_light; pos += delta)
  {
    servo.write(pos);
    delay(15);
  }
  digitalWrite(LED, LOW);
}


text:
Is it possible to have long wire connections from an NodeMCU to a servo motor or button?
For my proyect, I need to conect my NodeMCU to a servo motor as well as a push button, the thing is, the distance from the NodeMCU and both components has to have a distance of around 6.10 meters (or 20.0131 feet), I dont know if it is possible to do this connection, I worry if the pwm signal or the voltage would drop by the time it reached either component. I havent been able to try this because I dont have long enough cables to do the connections. In the case that it would be possible, what type of cable should I use and should I add something extra to the circuit to make it work better? Thanks.

use the long wire for the pushbutton part of the circuit ... use it to activate the LED of an opto-isolator .... basically, pressing the button lights an LED at the arduino ... you can use a battery to run the opto-isolator or use power from the arduino ... adjust the LED series resistor to obtain a good signal

you could use additional nodeMCUs, they are cheap and wireless.

I would suggest a pull up resistor forcing at least 1 mA or more of current through the switch contact. This helps keep the switch contact clean if it is not rated for dry switching. Then from the junction of the pull up resistor put a 20 - 100K resistor in series with your input pin. You can also add a 100nF cap between the input and ground to kill noise. This forms a low pass filter and denounces some of the switch noise. The other wire to the switch will be ground.  I did this a lot with 12/24VDC control systems. If you do several inputs check your currents and be sure you do not over power the Arduino. This will forward bias the top input protection diode pushing current into the Arduino VCC. The inputs are typically rated at 20mA but check to be sure yours is rated properly.

A push button won't be a problem. That is a very simple change in resistance from open circuit to a few ohms. You just need a low enough resistance to force the voltage coming through weak internal pullup resistor down to ground. It looks like 22 gauge wire has about 52.7 ohms / 1000 meters.
I don't think 6 meters of 22 gauge wire will be a problem for a 5V PWM signal either. If it's a very electrically noisy environment you might want to use shielded or twisted pair cable, but it seems unlikely that would be needed.


text:
How can I power off a servo the best way? Problems with MG90S servo
I have a NodeMCU and im trying to control a servo to move from angle A to B and viceversa. The thing is I want to be able to power off the servo after moving so it could stop getting voltage and current. I decided to use an NPN transistor (2N2222A to be more precise) and the servo red cable is connected from one end of the transistor and the other end is connected to the red line in my breadboard while the middle pin is connected to a pin in the NodeMCU. The thing is, it seems to work with a SG90 perfectly but when an MG90S is connected it doesn't move and you can hear a faint clicking from the servo. When the MG90S is instead connected directly to voltage line it works. I don't understand what the problem is. I also implemented the servo.detach(); function and it works but I don't know if it truly shuts off power to the servo like using a transistor would.
if (buttonState2 == HIGH) {
  digitalWrite(LED2, HIGH);
  digitalWrite(transistor2, HIGH);

  for (pos2 = 90; pos2 < 180; pos2 = pos2 + 1) {
    servo2.write(pos2);
    delay(15);
  }
  digitalWrite(transistor2, LOW);
  digitalWrite(LED2, LOW);
}

This is the code that I have, I would really appreciate some help, Thanks!

run your code, then turn off the servo power manually at the appropriate time ... doing that shows you the servo behavior if the power was turned off electronically  ... does the servo behave as desired when you do that?

You need a PNP or P-channel FET to switch the + (red) connection. An NPN or N-channel FET won't work right.


text:
ESP32 Low Power Reconnect Latency Question
I am trying to develop a small 9-button BLE keyboard on the ESP32 with a rotary encoder as a volume knob. My question involves the low power modes and the time it takes for them to wake up.
My system enters sleep mode after 5 seconds of inactivity from the user.
The issue is when the ESP wakes up from light sleep - it takes around 1 to 2 seconds for bluetooth to reconnect, and the keystroke or action that woke it up isn't processed.
How can I address the issue of a faster reconnect? I want the system to save power when it is not in use, but I also wish for it to be responsive when coming out of this low-power state to process user requests.
Here is the processing block:
while (true) {
    //Begin sleep if user has not interacted for >= 5 seconds
    current_sys_time = millis();
    if (current_sys_time - last_sys_event_time > MAX_ALLOWED_IDLE_TIME)
        light_sleep_begin();

    //Play/pause media when rotary encoder switch is pressed
    if (digitalRead(PIN_SW) == LOW && play_pause_btn == NOT_PRESSED) {
        delay(25);
        if (digitalRead(PIN_SW) == LOW)
            play_pause_btn = WAS_PRESSED;
        last_sys_event_time = millis();
    }
    else if (digitalRead(PIN_SW) == HIGH && play_pause_btn == WAS_PRESSED) {
        last_sys_event_time = millis();
        play_pause_btn = NOT_PRESSED;
        bleKeyboard.write(KEY_MEDIA_PLAY_PAUSE);
    }

    //Turn volume up or down when encoder is turned clockwise or ocunter-clockwise, respectively
    if (encoder_read()) {
        if (encoder_4bit_sample == CLOCKWISE)
            bleKeyboard.write(KEY_MEDIA_VOLUME_UP);
        else if (encoder_4bit_sample == COUNTER_CLOCKWISE)
            bleKeyboard.write(KEY_MEDIA_VOLUME_DOWN);
    }
}

And here is my sleep function:
void light_sleep_begin()
{
    gpio_wakeup_enable(GPIO_NUM_33, GPIO_INTR_LOW_LEVEL); //Encoder SW pin
    gpio_wakeup_enable(GPIO_NUM_35, GPIO_INTR_LOW_LEVEL); //Encoder CLK pin
    gpio_wakeup_enable(GPIO_NUM_32, GPIO_INTR_LOW_LEVEL); //Encoder DT pin
    esp_sleep_enable_gpio_wakeup();

    esp_light_sleep_start();
}

Board: ESP32 DevkitC \
IDE: PlatformIO \
Module: ESP32 WROOM

I don't think the failure to process the input is due to any bluetooth reconnection issue. Have you tried placing a print within your IF block so that you know as soon as the ESP observes a button press?

@TisteAndii Yeah, the thing is that when light sleep is called, I see the ESP disconnect from the slave device, and when it wakes up it takes ~2 seconds to re-establish the connection. There has to be a quicker wake-up time :/

Waking up likely isn't what is taking 2 seconds. That's why I'm saying you should time it, to narrow down exactly what's going on. Place a print(millis()) immediately before and after light_sleep_begin() so you know how long that's taking. Place another inside the IF block so you know when the button press gets noticed, BLE connection or not. Then post what you find.

Hey, sorry I was being ambiguous with my use of the phrase "wake up". I was talking about the time it takes for BLE to re-connect the ESP to the computer after sleeping. Anyways, I took your advice and placed a Serial.println(millis()); before and after light_sleep_begin(); The difference between the first and second print is how long it was sleeping before being waken up. It changes each time depending on how long I let it sleep. The button press gets noticed instantly.

Okay, that's good news. The button events are instantly noticed, problem is sending them ASAP after waking up. When you enter light sleep, the radios are turned off so upon waking up, I expect it'll take a while for the radio to resume advertising and for your PC (or whatever your client is) to connect to the ESP32. All these small delays add up and represent the cost of going to sleep in the first place. You can try saving the button press event(s) in some array until the connection is up (isConnnected()) and then send them. Or raise an issue on the library's Github, seems responsive.

@TisteAndii Ok. That makes sense. I appreciate your help.


text:
ESP8266 & 2x VL53L0X Sensors cause WDT resets
I have a system that utilises 2 VL53L0X sensors. This works fine for the majority of time, but after around 20 hours till 2 days (varying), the ESP resets due to Software a WDT, I've managed to do a stack trace, and this is the result:
PC: 0x40100529: Twi::busywait(unsigned char) at /Users/martin/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/core_esp8266_si2c.cpp line 271
EXCVADDR: 0x00000000

Decoding stack results
0x40218f25: Twi::readFrom(unsigned char, unsigned char*, unsigned int, unsigned char) at /Users/martin/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/core_esp8266_si2c.cpp line 405
0x4010083e: millis() at /Users/martin/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/core_esp8266_wiring.cpp line 188
0x4021913c: twi_readFrom(unsigned char, unsigned char*, unsigned int, unsigned char) at /Users/martin/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/core_esp8266_si2c.cpp line 1042
0x402090b0: TwoWire::requestFrom(unsigned char, unsigned int, bool) at /Users/martin/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/libraries/Wire/Wire.cpp line 129
0x402090dc: TwoWire::requestFrom(unsigned char, unsigned char) at /Users/martin/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/libraries/Wire/Wire.cpp line 143
0x402140eb: VL53L0X::readReg(unsigned char) at /Users/martin/Documents/Arduino/libraries/vl53l0x-arduino-1.02/VL53L0X.cpp line 322
0x40214442: VL53L0X::readRangeContinuousMillimeters() at /Users/martin/Documents/Arduino/libraries/vl53l0x-arduino-1.02/VL53L0X.cpp line 816
0x40201f00: readVLXSensors() at /Users/martin/Documents/Arduino/TEST_WS2812/TEST_WS2812.ino line 674
0x402083c7: loop() at /Users/martin/Documents/Arduino/TEST_WS2812/TEST_WS2812.ino line 596
0x40218404: loop_wrapper() at /Users/martin/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/core_esp8266_main.cpp line 172

This is the function that reads the sensors (initiated from the main loop):
void readVLXSensors() {

  if (readTop) {
    distSensorTop_distance = distSensorTop.readRangeContinuousMillimeters();
    if (distSensorTop.timeoutOccurred()) {
      distSensorTop_distance = 99999;
    }
    readTop = !readTop;

  } else {
    distSensorBottom_distance = distSensorBottom.readRangeContinuousMillimeters();

    if (distSensorBottom.timeoutOccurred()) {
      distSensorBottom_distance = 99999;
    }
    readTop = !readTop;
  }

}

As you can see as last desperate measure, I alternate the reading of the sensors, where as before I just read both sensors after each other. But even this approach still gives the WDT resets.
I don't believe it is (my)code nor the VL53L0X Library.. Any one an approach on this one?

It looks like the twi library goes into a tight loop waiting for a response from the sensor, and there's no yield in there.

Thats part of the esp core isn't?

Yep. Make sure you're on the latest version of the core.

Yes I am on 2.6.3

I can see that busywait() doesn't yield, and it doesn't really want to either. Maybe you could add a yield() call just before you query each sensor.

I've changed some things, will have to wait a few days to see the result.


text:
Atmega Millis with Quartz crystal
I followed https://www.arduino.cc/en/Tutorial/ArduinoToBreadboard this tutorial to program my Atmega 328p to run on a breadboard with a 16 MHZ Quarz crystal and two 22pF capacitor.
I want to program a digital clock without a RTC (code below). So I wrote my code by using millis(), and set the time exactly to the time of my mobile. After two minutes the Atmega was about a quarter minute early, but it seems to stay there. Why is that? Doesen't it use the crystal? Do I have to program it differently? Or will it stay at this time difference and run more or less accurate now?
My code:
#define ZERO 0b01110111
#define ONE 0b00000110
#define TWO 0b10110011
#define THREE 0b10010111
#define FOUR 0b11000110
#define FIVE 0b11010101
#define SIX  0b11110101
#define SEVEN 0b00000111
#define EIGHT 0b11110111
#define NINE 0b11010111
#define SECOND 1000
static int changed = 0;

static int led01 = 1;
static int led02 = 3;

static int led11 = 4;
static int led12 = 5;

static int state = 0;
static int selP = 0;

static int blink = 0;
static int btn_1 = 0, btn_2 = 0;

static long last = millis();
static long tm = 0;

static int seconds = 0, minutes = 45, hours = 13;

static const int DATAH1 = 2, ST_CPH1 = 3, SH_CPH1 =4;
static const int DATAH2 = 5, ST_CPH2 = 6, SH_CPH2 =7;

static const int DATAM1 = 11, ST_CPM1 = 12, SH_CPM1 =13;
static const int DATAM2 = A0, ST_CPM2 = A1, SH_CPM2 =A2;

static const char numbers[10] = {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE};
void setup()
{
  pinMode(DATAH1, OUTPUT);
  pinMode(ST_CPH1, OUTPUT);
  pinMode(SH_CPH1, OUTPUT);

  pinMode(DATAH2, OUTPUT);
  pinMode(ST_CPH2, OUTPUT);
  pinMode(SH_CPH2, OUTPUT);

  pinMode(DATAM1, OUTPUT);
  pinMode(ST_CPM1, OUTPUT);
  pinMode(SH_CPM1, OUTPUT);

  pinMode(DATAM2, OUTPUT);
  pinMode(ST_CPM2, OUTPUT);
  pinMode(SH_CPM2, OUTPUT);

  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
}

// main loop
void loop()
{
  long curr = millis();
  tm += curr-last;
  if(tm < 0 || tm > 900000){
    tm = 0;
  }
  last = curr;
  if(digitalRead(9) == LOW){
    if(!btn_1){
      if(state == 0){
        state = 1;
        selP = 0;
      }else{
        if(selP >= 3) state = 0;
        else selP++;
      }
      tm = 0;
      blink = 0;
    }
    btn_1 = 1;
  }else btn_1 = 0;

  if(state == 0){ //ZEIT LAEUFT
    if(tm >= SECOND){
      seconds+=tm/SECOND;
      tm = tm%SECOND;
      changed = 1;
    }
    if(seconds >= 60){
      minutes += seconds/60;
      seconds = seconds%60;
    }
    if(minutes >= 60){
      hours += minutes/60;
      minutes = minutes%60;
    }
    if(hours >= 24){
      hours = 0;
    }
  }else{ //UHR STELLEN
    if(tm>=500){
        blink = blink?0:1;
        tm = 0;
        changed = 1;
      }
    if(digitalRead(10) == LOW){
      if(!btn_2){
        changed = 1;
        switch(selP){
          case 0:
            hours+=10;
            if(hours >= 24) hours -= 20;
            break;
          case 1:
            if(hours/10 < 2){ //in else case zaehlt man die 2. Ziffer nur noch bis 3, da 24 kein Bestandteil mehr ist
              if(hours%10 == 9){
                hours-= 9;
              }else hours++;
            }else{
              if(hours%10 == 3){
                hours-= 3;
              }else hours++;
            }
          break;
          case 2:
            minutes+=10;
            if(minutes >=60) minutes = 0;
          break;
          case 3:
             if(minutes%10 == 9){
              minutes-= 9;
            }else minutes++;
        }
      }
      btn_2 = 1;
    }else btn_2 = 0;
  }
  if(changed){
    led01 = hours/10;
    led02 = hours%10;
    led11 = minutes/10;
    led12 = minutes%10;
    byte str[4];
    str[0] = numbers[led01];
    str[1] = numbers[led02];
    str[2] = numbers[led11];
    str[3] = numbers[led12];
    if(blink){
      str[selP]=str[selP]|(1<<3);
    }
    digitalWrite(ST_CPH1, LOW);
    shiftOut(DATAH1, SH_CPH1,MSBFIRST, str[0]);
    digitalWrite(ST_CPH1, HIGH);

    digitalWrite(ST_CPH2, LOW);
    shiftOut(DATAH2, SH_CPH2,MSBFIRST, str[1]);
    digitalWrite(ST_CPH2, HIGH);

    digitalWrite(ST_CPM1, LOW);
    shiftOut(DATAM1, SH_CPM1,MSBFIRST, str[2]);
    digitalWrite(ST_CPM1, HIGH);

    digitalWrite(ST_CPM2, LOW);
    shiftOut(DATAM2, SH_CPM2,MSBFIRST, str[3]);
    digitalWrite(ST_CPM2, HIGH);
  }
}

I measured the time with a timer and the time between two minutes seems to be exactly a minute. So why the initial difference.

Maybe you could simplify your code by using RTC_Millis(), which already implements the logic of a millis()-based clock.

I don’t see anything in this code that allows you to set the time.  You set it by hard coding the numbers.  That’s fine but it takes some time to compile and load to the board and the board is going to start at that time you hard coded.  If the board doesn’t get to start running the program for a few seconds while you upload then it’s obviously going to be a few seconds off.
It’s going to be nearly impossible to guess exactly what time the program starts running.  Maybe you could set the time for several minutes into the future, upload, and then unplug and wait until exactly that time to plug the board in and start it.  Remember there’s a couple seconds for the boot loader before the program starts to run.  It may take some trial and error.
Or you can write code there that allows you to set the time through the serial monitor or something.

Seems to me like the switch/case construct is about setting the time with push buttons.

Oh ok. I see that part now.  I got confused there.  Delete the answer I guess.

Sorry, I am a IT student and used to write code, not build things - so yeah, thats why my code is that messy :) . So you are saying the global static long last = millis() makes the difference because of the startup time? could I prevent this by putting it at the end of setup()? I could also set it in the first iteration of loop

No that's not what I was saying.  First, if it is global then it doesn't need to be static unless there's a whole lot to this project that you're not showing us.  I was talking about the line where you give seconds, minutes, and hours their initial value.  I thought that was to set the time.  Imagine you gave hours an initial value of 13 and then you don't start the board until 15:00, it would be off by two hours.


text:
How to use USB-in on an arduino?
I'm trying to use an arduino as a controller adapter. How would I get USB-in to get the signal from a usb video game controller?

Google for arduino USB host shield

Depends on which Arduino you have.  You’ll probably need a USB host shield to read from the controller and you’ll want one of the 32u4 based boards if you want the PC to recognize your Arduino as a joystick.

@Delta_G The project is to convert a usb controller into a gamecube controller signal. Would a 32u4 based board still be optimal for that?

You’ll have to explain to me what that means.  This is intended to plug into a GameCube and control that?  That may be a tougher but to crack.

Yes, that is my intention. I know it will be tough to crack, but I'm sure it's possible, as I've seen people make GameCube controllers out of Arduinos.

why 32u4? it can emulate a HID device, not read it.

Maybe better to use a Leonardo as it has a "real USB". So you can "fool" the video game controler and let it belive it's connected to a PC.

It makes actually no sense to plug an USB-Controller via an Arduino to a PC. The direct way and using an autofire/macro /custom key programmer app is more efficient.

The Arduino UNO (with 32u4) can either replace an USB controller as demostrated in NicoHood HID library or
additionally act as an interface for controller with strange vendor specific plugs demostrated in UNOJOY and you can build your own Controller/interface out of nearly every old non usb controller by cutting the hardware specific plug (e.g. old Xbox) and attach to an UNO who acts as "interface" to the PC. Another example is a C64-Joystick to the PC
The other option for using an Arduino is interfacing with "old video game systems" . For some there are already more or less succesfull projects. When connecting the USB controller via an USB shield you have normally a high lag time due to the USB shield library, so the better approach is to cut the USB plug and directly interface with the Arduino.

Project with USB Host-shield:

C64 - with USB Joysticks

Project old Joystick to USB-PC:

NES controller to PC USB

Project Arduino as controller for NES/SNES:

UNO to NES/SNES

Info on the pinout/protocol cn be found in this page

Pretty much anything is more efficient on a PC, compared to arduino. There can still be many valid reasons for using/building arduino projects.


text:
RFID RC522 Serial Communication converting problem
I am new to the RFID Scene and Serial communication as well.
So I am trying to use the RC522 RFID module and I wrote in block 22 - 0x36 which is 6. I want to write a code where I take whatever is in block 22 - 0x36, convert it into a float - 6.00 and then do some addition or deduction for example 6.00-2.5 = 3.5 and then I want to rewrite the value of 3.5 into that same sector but of course, convert it back to HEX ASCII - 33 2e 35. I've tried quite hard to find the solution online but couldn't.
  So is this possible to do?
Thanks.

yes, it is possible to do ... do you have any real questions?

why do you need to convert to hex?  ... 0x36, 54, '6', 0b00110110 are all the same data ... the only difference is the human readable form ... it is like uno, one, ichi, eins all being the same thing

can you provide a simple code then? I am having a problem with substracting the byte buffer with some number.

It is unclear to me, what exactly you have and what you want to do with it. Do you have a character buffer with hex in ASCII format? And then you wanto to make some float calculation to it? Please provide the code, that you already have. That would greatly help, since here the types of the variables are really important

@tsotniuspious, no ... you provide the code that you are having problems with and someone will check it over and provide advice

To be clear, what you want stored is ascii codes right?  So it's not hex or bin or dec, everything in computers is stored as binary.  If you store 0x12 in one slot and store 18 in another slot and compare then they are the same and in both cases 0b00010010 is what actually got stored.


text:
Bluetooth: read a user provided value and then obtain time from an Android phone
I'm new to Arduino and try to accomplish following 2 things (via Bluetooth module connected to an Android phone):

read an integer value provided by user.
obtain current time from the phone (the Arduino board itself has no clock module).

As for #1 - I'm able to print to the Bluetooth terminal as follows: Serial.println("Enter time to wait(in miliseconds): ");. I see this string on my phone. However I can't manage to read the value from the terminal using timeToWait = Serial.read();. I tried many possible combinations, but in the best case I get it in form of chars' ASCII values. So how can I properly read an integer value from the Bluetooth terminal?
As for #2 - is it possible at all, and if yes - how? If it is not possible to obtain current time via BT from Android phone - is it possible to obtain it via BT from a Linux laptop? How?

Over a serial port, you are transmitting data byte by byte. If you want to interpret them as numbers, you have to parse the data and assemble the numbers yourself.
You could resort to BLE instead, there you may transmit strings and numbers.

could you, please, create a link with "BLE" pointing on what it is? (Docs maybe)... For me and future readers. Thank you!

BLE stands for Bluetooth Low Energy, also known as Bluetooth 4.0.
Official tutorials to be found at e.g. [link] (https://devzone.nordicsemi.com/nordic/short-range-guides/b/bluetooth-low-energy/posts/ble-characteristics-a-beginners-tutorial).
An easy/easier approach would be studying the examples for ESP32 in the Arduino IDE.

I have found this: https://www.arduino.cc/en/Tutorial/ReadASCIIString which looks promising.

and also https://www.arduino.cc/en/Tutorial.StringToIntExample


text:
cannot find esp8266 via boardmanager
i'm using arduino ide 1.8.12 opened preferences window and did enter
http://arduino.esp8266.com/stable/package_esp8266com_index.json, https://arduino.esp8266.com/stable/package_esp8266com_index.json
(all comma separated) into the Additional Board Manager URLs field. then i opened the boardmanager (Strg+Shift+I) and enter 'esp' in the search field. BUT I CAN'T FIND "esp8266 by ESP8266 Community". it's not listed. WHAT CAN I DO NOW ?
additive : is there a way to include a locally available json file in the arduino as a library?
the file
    package_esp8266com_index.json
is in the directory
    C: \ Users \ [user] \ AppData \ Local \ Arduino15
thanks in advance

did you restart the IDE?


text:
RGB LEd and a push button in TinkerCAD
I'm working on TinkerCAD, I want to design and simulate a circuit in which there are following components. 1. 1 RGB LED 2. 1 Push button 3. 3 Photo-resistors. 4. 1 Arduino board. So the light should be off at the starting. When the push button is pressed for the first ever time, the LED should light up as red, and then the brightness of the red color should be able to controlled by one of the three photo-resistors used, the second time when the push-button is pressed the LED should light up as green and green color this time should be controlled by another photo-resistor..when the button is pressed for the third time , the LED should now change to blue color and the third photo-resistor should be able to control the brightness of the blue color. And this cycle should go on, upon pressing the Push button.
please tell me what's wrong.
Code looks like this
int button_state = 0;//declaring a variable
int counter;//declaring another variable,will keep count of which color to be lighted
const int pRed = A2; //assigning pin A2 as pRed
const int pBlue = A1; //.............A1....pBlue
const int pGreen = A0; //............A0.....pGreen
int inputRed;//adjusted value of led brightness will be stored
int inputGreen;
int inputBlue;
const int ledRed = 9;
const int ledGreen = 11;
const int ledBlue = 10;

void setup()
{
  pinMode(2,INPUT);
  pinMode(ledRed,OUTPUT);
  pinMode(ledGreen,OUTPUT);
  pinMode(ledBlue,OUTPUT);
  pinMode(pRed,INPUT);
  pinMode(pGreen,INPUT);
  pinMode(pBlue,INPUT);
}

void loop()
{
  button_state = digitalRead(2);// reading the button state
  inputRed = analogRead(pRed);// Reading the value from A2 pin
  inputRed = map(inputRed,0,1023,0,255);//value from A2 pin adjusted for led's brightness
  if (button_state == HIGH) {
    counter = 0; // Declaring counter as 0 again
    analogWrite(ledRed,inputRed);
    analogWrite(ledGreen, 0);
    analogWrite(ledBlue, 0);
    delay(10);// Wait for 10 millisecond(s)
    green();// Jumping to green
  }
}
void green()
{
  while (counter == 0){//counter was declared 0 in loop function,so the code won't go ahead till it's 0 only
  button_state = digitalRead(2);//for reading the button state once again
  inputGreen = analogRead(pGreen);//reading the signal from A0 as it is the inputpin for photoresistor for green light
  inputGreen = map(inputGreen,0,1023,0,255);  //value from A0 pin mapped
  if (button_state == HIGH) {
    counter++; // Increasing counter by 1 so that it becomes 1 now.
    analogWrite(ledRed,0);
    analogWrite(ledGreen,inputGreen);
    analogWrite(ledBlue,0);
    delay(10);//wait for 10 millisecond(s)
    blue(); //jumping to function for blue led now
  }
}
}
void blue()
{
  while (counter == 1)//using while, so that the code won't go ahead if counter=1,as made in function for green light
  {
  button_state = digitalRead(2);
  inputBlue = analogRead(pBlue);//reading value from A1 pin
  inputBlue = map(inputBlue,0,1023,0,255);//value from A1 pin mapped
  if (button_state == HIGH) {//
    counter++;
    analogWrite(ledRed,0);
    analogWrite(ledGreen,0);
    analogWrite(ledBlue,inputBlue);
    delay(10);//wait for 10 millisecond(s)
  }
  }
}

please tell me what's wrong.

I'm sorry to say, but pretty much everything. You need to rethink your program flow from the ground up.
Separate out the button from the LED actions. The button should only control the counter. The counter then makes the decision what to do with the LEDs.
Also you have to learn about the concept of change with the button. You don't want to be doing something if the button is high, since that will be being done all the time the button is pressed. Instead you need to learn how to do something only at the moment the button changes from low to high.
As a rough outline to how your program could look, here's a pseudo-listing:

Set the counter to 0
If the button changes from LOW to HIGH

Increment the counter

If the counter is greater than 3

Set the counter to 1

That would give you a sequence of 0-1-2-3-1-2-3-1-2-3 for the counter as you press the button.
Next you have a separate section in your loop to deal with what the counter is.

If the counter is 0

Turn off all LEDs

If the counter is 1

Control the red LED and turn off the others

If the counter is 2

Control the green LED and turn off the others

If the counter is 3

Control the blue LED and turn off the others

If you implement that properly you will have created a finite state machine.

Okay can you give me a rough outline of the commands that can be used when the button is changed from LOW to HIGH, I've really tried everything I know. An example of something similar would also suffice.

digitalRead(), if() and remembering what the button state was.

Plus you'll need to debounce the button presses. (When you detect the button change from low to high, record the value of millis, and ignore further changes for 20-100 mS.)

@DuncanC Depends how many delays you end up littering around the place...  But yes, decent debouncing is always good.

How about NO delays?

@DuncanC Then add an RC network to the button :P Or use one of the myriad of debouncing libraries.

It's not very hard to write debounced button code. See my answer for an outline of how to do it.

@DuncanC I know, but it's not something you want to do every time. That's why I wrote my own library to do it. Write once, use many. Why write the same code every time?

Your code might look something like this
#define debounceTime 50   //Tweak this value to adjust amount of debouncing
unsigned long lastButtonMillis = 0;
uInt8 switchState = 0;
uInt8 oldButtonState = LOW;

void setup() {
   //Your setup code
}

void handleSwitchChange(uInt8 switchState) {
   switch switchState {
      case 0:
         //code for red
         break;

      case 1:
         //code for green
         break;

      case 1:
         //code for blue
         break;

   }
}

void loop() {
    //If enough time has elapsed, check for button presses
    if (millis() - lastButtonMillis >= debounceTime) {
        lastButtonMillis = millis();
        if (oldButtonState == LOW && digitalRead(switchPin) == HIGH) {
            oldButtonState = HIGH;
            switchState = (switchState + 1) % 3; //value will cycle 0,1,2,0,1,2
            handleSwitchChange(switchState);
        }
    } else {
        oldButtonState = digitalRead(switchPin);
    }
}


text:
Why this simple serial monitor code not working?
The follwoing code echoes whatever arduino recieves through reciever pin. The idea is that arduino will echo whole data in the buffer on the same line and starting from the new line while echoing the next data recieved in the buffer.
void setup()
{
    Serial.begin(9600);
}

void loop()
{
  if(Serial.available())
    {
        int count = Serial.available();
        for(int i = 0; i < count; i++)
        {
            char character = Serial.read();
            Serial.print(character);
        }
        Serial.print("\n");
    }
}

When I run the code it prints the characters line by line. for example if I enter the word "QUICK" it echoes the following
Q
U
I
C
K

Whereas I think it should be echoing
QUICK

Please help me out.

You seem to have the assumption, that the string "QUICK" is send as one package of characters, because you send it with one keypress from the Serial Monitor. But Serial (UART) is a "serial" protocol, meaning, that each byte (aka character for ASCII encoding) is send sequentially.
At 9600 baud each byte will take about 1ms to transmit. Also: small random delays can be introduced by the PC or in the USB communication (if you are communication through a USB to Serial chip, like when you connect the Uno via USB).
Your code runs faster than the data arrives at the Unos microcontroller. The first if clause is entered as soon, as there is one byte in your Serial buffer. Then you start reading the data from the buffer, but at that time no further bytes did arrive. So the loop is exited after one iteration.
If you want to process the Serial data line by line, you should send a line ending from the Serial Monitor (or whichever program you are using) via the Line ending option. The common way is to use \n aka the newline character as line ending. Then in your code you should read the data until you receive the newline character.
That can be done in multiple ways. One way is to read each arriving character into your own buffer, which is big enough to hold the maximum number of characters, that can occur in your messages. Then, when receiving the newline character you can process the data in the buffer. A variables holds the current position in the buffer:
unsigned int pos = 0;
char buffer[20] = ""; // enough space for 19 characters + the null character for terminating the string correctly

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

void loop(){
  if(Serial.available()){
    char c = Serial.read();
    if(c != '\n'){
      buffer[pos] = c; // Adding the received character to the buffer
      if(pos < sizeof(buffer) - 1){
        // incrementing the position variable to point to the next position in the buffer
        // but only, if there is enough space in the buffer left
        // otherwise this code will overwrite the last character
        pos++;
      }
    } else {
      buffer[pos] = 0; // Terminating the string correctly
      // Process the message here
      Serial.println(buffer);
      // Reset buffer by setting the position back to zero
      pos = 0;
    }
  }
}

Note: This code needs your loop() function to iterate fast enough, so that you won't miss more data, than the internal buffer of Serial can hold (I think 32 characters). So you probably don't want to use long delays (which is nearly always a bad idea anyways, see non-blocking coding and the millis() function).


text:
Compile-time 'Undefined reference' error for functions defined in a .cpp source file that are called in my main project file
I'm currently working with the NodeMCU ESP12E and MPU6050 IMU using the Arduino IDE and wanted to create a project that has a .h file that declares the variables and functions. In the .cpp file, I have various function definitions. The main.ino file just calls some of these functions. Please find some excerpts of code from each file and the errors I encountered. The errors say the three functions called in the .ino file are undefined even though they are defined in the .cpp file
Algo.h file:
extern int activity_state; // activity_state=1 for RUN and activity_state=0 for WALK
extern float * speedarray; // Dynamic array for storing speed
extern int speedindex;
extern float * timearray; // Dynamic array for storing time
extern int timeindex;

extern unsigned int localPort;

Algo.cpp:

static void pedometerInit() // Initialising all pedometer algorithm variables
{
      int i = 0;
  //pedometerAlgo varibles
  pedi_window_high = 2000;
  pedi_window_low = 200;

  pedi_sampling_counter = 0;
  pedi_refresh_frequency = 50;
  validZone = 1;
  jatin_index_1 = 0;
  jatin_mag = 0;
  pedi_max = 0;
.
.

All the functions work on the variables declared in the header file.
Ped_algo.ino:
void setup() {

  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(STASSID, STAPSK); // Setting up WiFi station
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print('.');
    delay(500);
  }

  Udp.begin(localPort); // Setting up UDP connection

  MPU6050_Init(); // Initial configuration of the MPU6050
  pedometerInit();
}

void loop() {

  pedometerAlgo();
}

Error messages:
Ped_Algo.ino.cpp.o:(.text.loop+0x0): undefined reference to pedometerAlgo()'
in functionloop':
 undefined reference to pedometerInit()'
 undefined reference toMPU6050_Init()'
 undefined reference to `pedometerInit()'
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

Well, for example in the static void pedometerInit() that static means linker is not allowed to use it outside its own compilation unit Algo.cpp (Algo.o)

Also, it seems you don't have the constructor pedometerAlgo::pedometerAlgo() implemented.

did you include Algo.h in .ino?

I have included Algo.h in the .ino file. Also, I'm not using classes here. And removing the static, gives me the undefined reference error to all the variables used in the functions.

As well as extern in the header for your variables you have to actually create those variables somewhere. extern just t tells the compiler that they exist somewhere else. You have to ensure that they actually do exist somewhere.

Firstly, static keeps a function from ever being exported globally:
static void pedometerInit() // Initialising all pedometer algorithm variables

should not be static.
Secondly, extern does not define a variable, it merely tells the compiler that "this variable exists somewhere. Find it at link time." - however you're not actually defining those variables anywhere.  In addition to the extern hints in the .h file you need to have the variables in the .cpp file for the compiler to be able to find them.
int activity_state; // activity_state=1 for RUN and activity_state=0 for WALK
float * speedarray; // Dynamic array for storing speed
int speedindex;
float * timearray; // Dynamic array for storing time
int timeindex;

unsigned int localPort;

void pedometerInit() // Initialising all pedometer algorithm variables
{
 ... your code ...
}


text:
Connecting the MKR GPS shield by cable or as a shield
I have an MKR WiFi 1010 and an MKR GPS Shield. When I connect my GPS Shield using the I2C cable, it works fine.
This works perfectly (the bottom is the MKR Motor Carrier):

However, when I use it as a shield (hat?) using the pins, it doesn't.
This doesn't work. The code blocks somewhere (I suspect GPS.available()):

My question, should it work the same whether it is cabled or put on with the pins? Or should I change my code somehow?

From the shop page:

It interfaces with Arduino boards either through a serial interface, when used with headers and put on top of a MKR board, or through an I2C interface and a dedicated ESLOV cable supplied as bundle.

From Arduino_MKRGPS library reference:
begin() Parameters:

GPS_MODE_I2C to use the MKR GPS with the I2C cable (default setting),
GPS_MODE_SHIELD if using the MKR GPS as a shield.


text:
How to write to the second line of a display?
I got this 4 line display from Mouser: https://www.gravitech.us/20chbllcd.html, and I get it to work fine for lines 1 and 3 (as line 3 is just the 21st character of line 1). But I am struggling to get lines 2 and 4 working. If I understand correctly, these are "line 2" for the HD44780 controller, and I should set the DDRAM address to 0x40 before I write there.
But, when I try that, nothing happens.
I tried writing 0x04 to the DDRAM address counter, and I can see the cursor jumping there, but when I write to that address, no text shows up. If I omit the command, text pops up correctly.
Also, when changing the contrast of the display (using the potentiometer on the Vdd and Vo pins), only lines 1 and 3 change contrast.
My code:
This method I use for convenience:
void set(int _rs, int _rw, int _d7, int _d6, int _d5, int _d4, int _d3, int _d2, int _d1, int _d0) { ... }

To set the DDRAM address to 0x40:
set(0,0,1,1,0,0,0,0,0,0);

The general timing and control is correct, as I can get text on the display, and also a function like "shift" works fine.

You're not using the standard LiquidCrystal.h library?

@Majenko no, not yet. If I cannot get this to work myself, I'll try and see if that can work. I looked at the LiquidCrystal source code though, and I didn't see anything I could use.

Personally I would start with the known working, well tested, and properly supported LiquidCrystal.h library, and then pare it down to just the code I needed (if code size were an issue). As it is we can't really help you since we don't know your code or setup.

Line 1 starts at address 0x00 | 0x80 0b10000000 and ends at 0x13 | 0x80 0b10010011
Line 2 starts at address 0x40 | 0x80 0b11000000 and ends at 0x53 | 0x80 0b11010011
Line 3 starts at address 0x14 | 0x80 0b10010100 and ends at 0x27 | 0x80 0b10100111
Line 4 starts at address 0x54 | 0x80 0b11010100 and ends at 0x67 | 0x80 0b11100111

That 0x80 0b10000000  is the HD44780 command for set DDRAM address. The other bits 0b1xxxxxx define the address.

You'll find more details at Arduino with HD44780 based Character LCDs

Yes. That's what I said.

You need to setup the HD44780 in 2-line mode. The command is | 0 | 0 | 1 | DL | N | F | X | X | with:

DL: 0 = 4-bit / 1 = 8-bit interface
N: 0 = 1 line / 1 = 2 lines (this is the bit to set)
F: 0 = 5x7 / 1 = 5x10 font size

Most probably you have that command already in your program to set the width of the interface, but with N = 0.
Note: The common algorithm is to send the command 0x33 three times to make sure to be in 8-bit mode. The first can be the second part of a half-done 4-bit command, possibly not changing the interface width. Then the second and third will switch into 8-bit mode. If the device is already in 8-bit mode, or gets into it in the course, it makes no harm to repeat.
Since in 4-bit mode only D7 to D4 are used, you can change 0x33 into 0x38 to enable the 2-lines mode.


text:
IDE compiles incorrect file after renaming them
I am using the stand alone Arduino IDE to build some projects, and I have a few .cpp files now, but during work I renamed them .c and back. When compiling the project now (with Ctrl-R), it is still trying to compile the .c files. But, I don't even see them on disk!
Changing the .cpp makes no difference. I am used to IDEs having some kind of project file, or a "clean project" option, but I cannot find those here.

are the files open in tabs in IDE? IDE takes source code from the editors. a 'sketch' is a folder with source files. all are compiled

The Arduino IDE copies all files to a tmp folder. Try restarting the IDE.

A restart did it.

The Arduino IDE does not monitor changes to open files. So if you rename or change a file externally (i.e. in another editor), the IDE won't update the file contents. Therefore, after such a change, a restart might be necessary.
Note: If you use another editor to change a file but only compile (and upload) in the IDE, this will work, because the compiler correctly reads the updated file. But editing the source in the IDE and an external editor at the same time might overwrite either change!


text:
Power MPU 6050 module through pin AD0
TL;DR: is it safe to power a MPU 6050 module through its AD0 pin instead of VCC?
We managed to have two MPU 6050 modules on the same I2C buffer by changing the address of one of them by connecting its AD0 pin to the same current origin used for VCC.
We found out that we can get the same result if we just switch the power cable which goes to the VCC pin to the AD0 pin: the module changes its address and we are able to read its data normally.
This would be a better configuration for us because, if the AD0 cable ever got disconnected, we wouldn't get anything from the second module but we would still get uncorrupted data from the first one. In the other case (cable to both VCC and AD0), if the AD0 cable got disconnected, we would get corrupted data.
So the final configuration would be: GND, SCL, SDA pins connected normally, power to AD0, pin VCC left unconnected.
The question is: is this a safe configuration or is it better to just leave the VCC pin connected normally and get another cable to the AD0?
From empirical tests it looks like it works fine, but we couldn't find any confirmation and are not experts on the matter.

Theoretically that should be OK.
According to the datasheet the MPU6050 consumes no more than 3.9mA with all the internal options turned on. That is below the limit of 25mA sustained current from a single IO pin for the ATMega chips. Just be aware of the total limit of the ATMega's power pins of 200mA, but it would take a lot of modules to reach that limit.
Since the MPU6050 is a 3.3V device your modules most likely have a voltage regulator on them to allow powering from 5V. That should mitigate any voltage droop caused by the higher impedance of using an IO pin as a voltage source.


text:
Same LED but different brightness on same PIN
I connected a led to pin 7 (with a small resistance to avoid burning it) and tried the code below, with and without pinMode as output
void setup() {
  pinMode(7, OUTPUT);
  Serial.begin(9600);
}

void loop() {

  digitalWrite(7, HIGH);
  delay(5000);
  digitalWrite(7, LOW);
  delay(200);

  Serial.println("hello world");
}

Why does commenting the line pinMode(7, OUTPUT); make the led dimmer ?

try pinMode(7, INPUT); and pinMode(7, INPUT_PULLUP);

not sure what i'm supposed to understand @jsotola
it seems pull up is default but what is it?

All the pins are configured as INPUT by default on startup. So if you leave out the pinMode(7, OUTPUT);, pin 7 will still be configured as input. An Input doesn't provide any current (or only a very very low leak current), so the LED will be off in this time.
When you write HIGH to a pin, while it is configured as INPUT, you are activating the internal pullup resistor. This is a resistor (typically about 10kOhm) from the pin to Vcc (HIGH level) inside the microcontroller itself. Now a small current - set by the total resistance (your resistor + internal pullup) - can flow through the diode, making it light up very dim.
Configuring a pin as INPUT with the internal pullup resistor activated can be done in one command: pinMode(7, INPUT_PULLUP);, which makes the intent more clear, but does exactly the same under the hood as setting to INPUT and writing HIGH to the pin.


text:
Create a system of hot swap firmware update on Arduino Nano?
Is it allowed by Arduino Nano architecture, to develop a Sketch, divided into two segments:

The one, that accepts through a CAN-bus a the new version of the firmware itself and writes it into the second segment. The purpose of the first segment is to be only triggered, when data is being transmitted.
The firmware itself.

I imagine it looking like this:
void loop(){

  if (CAN.onReceive(...)){
    // first segment
  }
  else{
    // second segment
  }

}

After the transmition is complete, the sketch just runs forth with updated code. Is it possible?

The InternalStorageAVR in my ArduinoOTA library can write a binary into the upper half of a classic AVR MCU flash. The library doesn't allow to use it with Nano because of the small flash size, but it is easy to remove the check.
See the advanced OTASketchDownload example on how to use InternalStorage with your own way of downloading the update binary.
InternalStorageAVR requires a modified Optiboot bootloader with the copy_flash_pages function. A hex file with the modified bootloader is available in my_boards GitHub repository.
use of InternalStorage
  if (!InternalStorage.open(length)) {
    client.stop();
    Serial.println("There is not enough space to store the update. Can't continue with update.");
    return;
  }
  byte b;
  while (length > 0) {
    if (!client.readBytes(&b, 1)) // reading a byte with timeout
      break;
    InternalStorage.write(b);
    length--;
  }
  InternalStorage.close();

  if (length > 0) {
    Serial.print("Timeout downloading update file at ");
    Serial.print(length);
    Serial.println(" bytes. Can't continue with update.");
    return;
  }

  Serial.println("Sketch update apply and reset.");
  Serial.flush();
  InternalStorage.apply(); // this doesn't return

yes, it is mentioned in the Answer. in ArduinoOTA.h and in InternalStorageAVR.cpp there is a #if FLASHEND >= 0xFFFF

Juraj, when I'm trying to run your OTASketchDownload example, the output is "error: 'InternalStorage' was not declared in this scope. note: suggested alternative: 'ExternalOTAStorage'" Could you suggest, how I can fix it?

Juraj, can you please specify, where InternalStorage puts the saved bytes and how can I read them back? I went through what documentation I've found, but still don't grasp it.

just use apply() and it will with the help of the bootloader copy it to address 0 and reset the MCU. you can't do anything else with it.

let's say I want to test it locally - in what format should I feed it the new version of the sketch?

bin format. copy platform.local.txt from library's extras/avr folder, next to platform.txt in the boards package. restart the IDE. use Export binary from Sketch menu. it will put a .bin file next to .ino

It did really create the new_version.bin.ino file for me, but how can I send it to the board and get InternalStorage to read it?

the standard way for the library is to upload from IDE over a WiFi or Ethernet shield. other options are a download over a network, read from SD card, read from Serial, I2C or any other way of transport you can do in your sketch

Juraj, I understand, that it goes far away from the topic of this question, so I asked another one: https://arduino.stackexchange.com/questions/95996/how-to-send-a-binary-file-to-a-nano-board-through-an-isp-connection-using-arduin. Would be happy, if you'd answer it.

That sounds similar in principle to some of the SD card bootloaders that I recall reading about a few years ago. These bootloaders would look for a file on SD card when triggered and then write that to flash memory.
I understand that receiving a file via CAN is different, but I expect most of the main ideas are the same. One advantage of an SD card is that the full file can be verified before writing to flash. The Nano does not have enough RAM to store the entire 32kB, so I expect you would have to do it 'in realtime' over CAN.
https://github.com/zevero/avr_boot is one example that supports the ATmega328P (so should be compatible with the Nano).
But in essence, what you are looking for is a customised bootloader.


text:
Exit from for function after detecting obstacles
#include <HCSR04.h>

int red = 13;
int green = 12;
int blue = 11;
int trigger = 9;
int echo = 8;
int halt;

void setup(){
  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(blue, OUTPUT);
  pinMode(trigger, OUTPUT);
  pinMode(echo, INPUT);
  Serial.begin(9600);
}

void redLed(){
  rgb(255,0,0);
  delay(200);
}

void rgb(int r, int g, int b){
  analogWrite(red, r);
  analogWrite(green, g);
  analogWrite(blue, b);
}

void fadeBlu(){

    for (int i=0; i<=255; i+=5){
    rgb(0,0,i);
    delay(40);

    Serial.print("halt in IF is ");
    Serial.println(halt);
    }

    for(int i=255; i>=0; i-=5) {
      rgb(0,0,i);
      delay(40);

      Serial.print("halt ELSE is ");
      Serial.println(halt);
    }
}

void human() {

  UltraSonicDistanceSensor distanceSensor(trigger, echo);
  double distance = distanceSensor.measureDistanceCm();
  halt = 0;

  // cover sensor
  if (distance<=30) {
    halt=0;
    redLed();
  }
  // no cover
    halt=-1;
    fadeBlu();
}

void loop(){
  human();
}

I'm looking for a way to exit from "for" loop of fadeBlue() function if the hand is detected in front of sensor. I would like that in any case of fading and if there is hand in front of sensor the led became red. In my code the led doesn't stay red if I had hand in front of the sensor and also the value of "halt" doesn't change. I put some serial.println to make debugging.

Did you try to break out of the loop?

No, i don't know how to use break here.. i have to break in for?

if( [some-condition] ) return;

Alternatively, calculate the brightness the blue led should be, based on time (millis()). E.g. rgb(0,0,(millis()/40)%256);

I don't understand how to use millis there..

First, try to avoid duplication of code, so make a sub function (I slightly changed the print statement, but I assume it's only for debugging):
void fadeBlu()
{
    fadeBlueCycle(0, 255, 5);
    fadeBlueCycle(255, 0, -5);
}

void fadeBlueCycle(uint8_t start, uint8_t end, int8_t step)
{
    for (int i = start; i != end; i += step)
    {
        rgb(0, 0, i);
        delay(40);

        Serial.print("halt in step ");
        Serial.print(step);
        Serial.println(halt);
    }
}

Now to break from the for, you can use break, or simply return. It's not a good practice to have multiple return statements in one function, thus put it at the end, and use a break. Also, some people don't like a break and prefer using a `while. This would look like:
void fadeBlueCycle(uint8_t start, uint8_t end, int8_t step)
{
    uint8_t i = start;
    bool condition = true;

    while ((i != end) && condition) // or !condition, depending on what you prefer
    {
        rgb(0, 0, i);
        delay(40);

        Serial.print("halt in step ");
        Serial.print(step);
        Serial.println(halt);

        condition = `some condition`;
        i += step;
    }
}

Good answer as usual. Note that the for loop in C/C++ allows you to add additional checks, so you could also write the for loop as for (int i = start; i < end && condition; i += step) and get the same effect as the while loop, while also having the for loop manage the counter.

@DuncanC True ... and personally I don't like this concept, as it's like a while loop, written as a for loop. But it's personal. I have seen many professional projects using it this way (with the for). Personally I consider a for loop like an unconditional loop where beforehand the number of iterations is known, and a while loop as a conditional loop, where the number of iterations is not known beforehand. The break statement is kind of discussable in this sense. (But everything is better than a goto).

The condition of the while in my case should be if there is obstacles in front of sensor?

That depends on what your requirements are. If you want to break the loop based on some condition, use the condition you need. The while loop will stop when  condition is true, or you can use the not (!) operator (thus !condition) to stop the while` loop when the condition is false.

I noticed that the break happens ONLY after the end of the while loop and not at any time when there is obstacle in front of sensor, why this happens?

Assign the  condition you implemented to the variable condition and print it... It should change according to what you implemented.

No, i can't understand what kind of condition i need there. The only condition that stop the while loop should be something related to the distance from the sensor, (distance<=30) but i have used that on human() function...

Let us continue this discussion in chat.


text:
NodeMCU wiring for Serial1?
I'm trying to get telemetry data to be sent out Serial1 on the NodeMCU board.  I read that TX is (by default) mapped to pin D4.
Ultimately, there will be a Raspberry that will be listening for these messages, but I don't have it yet.  So to quickly test this, I connected an oscilloscope with Serial decoding to D4 and the GND of the probe to GND on the NodeMCU.  The problem is I'm not getting any indication of activity out D4 when I run the following code:
Serial1.begin(9600);
Serial1.printf("some text");

Am I wiring the probe correctly?  Am I missing another serial command in the sketch?
When I move to the rPI, do I GND both boards together, then write TX (D4) to RX on the rPI?

https://community.blynk.cc/t/how-to-use-2-serial-ports-or-more-in-nodemcu/20282/2. one of the answers insists that the nodeMCU shouldn't be connected to computer to be able to use serial1

You can do Serial.swap() in setup() to swap Serial away from RX/TX pin. Serial is then on D7 as RX and D8 as TX (and you can wire some serial module there).
Bridge with jumper wire D4 pin with TX pin. the Serial1 output will go over the USB chip to Serial Monitor and you will see the prints to Serial1.
This will not disturb the flashing mode, because bootloader will still listen on standard Serial pins.

This code worked for me as Modbus slave
Required this library <ModbusRtu.h>
#include <ModbusRtu.h>
unsigned long TIME = 0;
unsigned long LASTTIME = 0;
unsigned long INTERVAL = 5000;

int i = 0;
// data array for modbus network sharing
uint16_t au16data[16] = {
  3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, 11 };

/**
 *  Modbus object declaration
 *  u8id : node id = 0 for master, = 1..247 for slave
 *  port : serial port
 *  u8txenpin : 0 for RS-232 and USB-FTDI
 *               or any pin number > 1 for RS-485
 */
Modbus slave(1,Serial,0); // this is slave @1 and RS-232 or USB-FTDI

void setup() {
  Serial.swap();
  Serial.begin( 19200 ); // baud-rate at 19200
  Serial1.begin( 19200 );
  slave.start();
}

void loop() {

  if ((millis() - TIME) > INTERVAL) {
    i++;

    if(i == 16){
      i = 0;

      for (int ii = 0; ii < 16; ii++)
      {
        au16data[ii] = 0;
      }
    }

    au16data[i] = 1;

    TIME = millis();
  }

  slave.poll( au16data, 16 );
}

I'm not sure how this answers the question.

Because above mentioned type of wiring, I have done but I can't find the correct code library, after some research, I found a suitable library. So I share this platform to help others. Thank you!


text:
Pulling the enable pin on Adafruit PowerBoost to low (It's connected to VBatt!)
I am working on an Tonuino (tonuino.voss.earth), and I am using a PowerBoost-module from Adafruit (https://www.adafruit.com/product/1944) for it. The powerboost-module needs the enable pin driven to LOW(GND) to turn the output 5V off. Currently I have a rocker switch which allows me to permananently connect EN to GND.
I would like to implement a auto-off functionality for this combination, i.e. the arduino can drive the enable pin LOW and in this manner kill its own power. In addition to the auto-off, I want the user to be able to turn on the device via a button press. I come from a software background and my last connection to electronics is from a time long, long ago, which is why I am struggeling.
This shows my initial thoughts:

The user presses the button to start the Tonuino. The switch disconnects EN from GND, EN goes to UBATT(HIGH) and 5V to the arduino is enabled. By enabling the arduino, a GPIO is set to high and thus EN is maintained high
To turn off, the arduino sets the GPIO to LOW, thus setting EN to LOW, 5V are disabled and so forth...

My problem: 5V from the Arduino GPIO will always be at 5V and thus higher than the reference voltage of EN (UBATT 3V - 3.7V). I really am afraid that this will damage my lipo. For me this means, I ideally should switch UBATT for EN (safely) and am failing to come up with a solution.
Any pointers are greatly welcome

The datasheet states that the EN pin can be up to 7V. But you could also, instead of setting the Arduino pin to OUTPUT HIGH, set the Arduino pin to INPUT. The pull-up (R13) on the PowerBoost will then provide Vbat to the EN pin. So it would never see 5V.

PS note that as soon and the Boost converter turn off, the power to the Arduino goes off, and the pin will no longer be LOW, turning the boost converter back on. Majenko's solution already fixes that.

Your biggest problem is that the module defaults to on. There is a 340kΩ resistor pulling the EN pin up to VBAT all the time, so to turn it off you have to actively override that pullup.
Ideally you would modify the module by removing that resistor (R13) and adding your own resistor between the ENABLE and GND pins. You can the override that with both a button and a P-channel FET in parallel to turn the module on.
For example:

simulate this circuit – Schematic created using CircuitLab
Now normally R1 pulls ENABLE to ground turning the module off.  You press SW1 and it pulls ENABLE up to VBAT and turns it on.  5V then gets supplied to the Arduino, at which point you need to set the GPIO to output and pull it HIGH.
This causes the gate of M2 to be pulled above its threshold voltage (make sure it has a threshold voltage between 0V and 3V) and it starts to conduct pulling the gate of M1 below its threshold voltage (must be between 0V and -2V) bypassing switch SW1 keeping the system enabled.
You can now let go of SW1 and it will all stay powered on until you either set the GPIO LOW or set it to an INPUT.
Note that resetting the Arduino (for programming, for example) would cause the boost module to shut down and require re-powering with SW1 (or through the GPIO if you have the Arduino powered through USB for programming of course).
However if you don't want to or can't modify the module then things get a little nastier.
To make it default to OFF R1 in the above schematic will have to be low enough value that the voltage presented at the ENABLE pin is below 20% of the battery voltage.  R1 and the existing 340kΩ pullup resistor form a voltage divider, so you need to calculate the size of resistor that will allow it to be below 20% VBAT.
Since a voltage divider just gives you a proportion of the input voltage whose ratio is the ratio of the "top" resistance in the divider to the total resistance we don't care what the voltage is, only the ratio.  And we don't really care about the exact value, only that the result is below 20%.  So we can pick a good common value.
However we don't want a value that is too low, because the voltage divider will be draining power from the battery all the time, so the higher the resistances the less the power drain will be.
For example if we pick the common value 47kΩ we see that:
    R2           47000
 ------- = --------------- = 0.11 (11%)
 R1 + R2    340000 + 47000

Which is below the 0.2 (20%) that we want, which is good.  Calculating the current at a typical battery voltage of 3.7V we get
     V          3.7
I = --- = -------------- = 0.000010 (10µA)
     R    340000 + 47000

10µA is not much, on the scale of things, but it's good to know about it when you're working from a battery since it will form part of your power budget calculations.

This is a fantastic answer! Thank you for enlightening me and the time to answer my question. I will see what  parts i can get quickly to realize this

Hi Majenko, so after a test build on the breadboard, I have to rescind my acceptance of the answer. Here is why: The arduino does turn the powerboost module off - BUT - the gate voltage remains at 2,25V. So a trickle current is running somwhere...

Which variant of the circuit are you using? Did you remove R13 or are you trying to work around it?

I removed R13 from the circuit

There may be some back flow through the Arduino gpio. Isolating it with an n channel MOSFET would cure that. I'll update the schematic shortly.

@JoeD Ok, I have modified the schematic to include a N-channel MOSFET used to isolate the GPIO. It has the effect of reversing the GPIO logic, so now HIGH is on and LOW or INPUT is off.


text:
Which Bluetooth Module can I use with Arduino Micro?
I am building a HID (mouse) using Arduino Micro. I want the mouse to communicate with the PC wirelessly. I am wondering which Bluetooth module works for me either HC-05,06 or any other?

the question is not opinion based. please share as an answer your experience with a module for BLE HID with an AVR based MCU.

It would be difficult to beat the price of a COTS Bluetooth mouse. If that's not your goal, then, perhaps, your next step might be to search if an HC-05 can support the HID protocol. Or, if that's not possible, if the Atmel Mega can. I might be wrong, but I think that would be the tricky bit in your project.

The HC-05 should certainly allow you to communicate with an Arduino Micro via the provided hardware serial port (Tx/Rx pins).  Here's a link to my blog post about doing this with an Arduino Uno (should be the same except possibly pin # differences).

Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.

Isn't that what links are for - to lessen the requirement to repeat stuff, or summarize it in a way that leaves out important details?

I think the linked post answers that


text:
Can anyone find out why when I run this code for a GPS and BME680 sensor I have no errors but nothing happens
Here is the code
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <SoftwareSerial.h>

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);

SoftwareSerial gpsSerial(5, 11); // RX, TX (TX not used)
const int sentenceSize = 80;
char sentence[sentenceSize];

void setup() {
  Serial.begin(9600);
  while (!Serial);
  Serial.println(F("BME680 test"));
  gpsSerial.begin(9600);

  if (!bme.begin()) {
    Serial.println("Could not find a valid BME680 sensor, check wiring!");
    while (1);
  }

  // Set up oversampling and filter initialization
  bme.setTemperatureOversampling(BME680_OS_8X);
  bme.setHumidityOversampling(BME680_OS_2X);
  bme.setPressureOversampling(BME680_OS_4X);
  bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
  bme.setGasHeater(320, 150); // 320*C for 150 ms
}

void loop() {

 static int i = 0;
  if (gpsSerial.available())
  {
    char ch = gpsSerial.read();
    if (ch != '\n' && i < sentenceSize)
    {
      sentence[i] = ch;
      i++;
    }
    else
    {
     sentence[i] = '\0';
     i = 0;
     displayGPS();
    }
  }
}

void displayGPS()
{
  char field[20];
  getField(field, 0);
  if (strcmp(field, "$GPRMC") == 0)
  {
    Serial.print("Lat: ");
    getField(field, 3);  // number
    Serial.print(field);
    getField(field, 4); // N/S
    Serial.print(field);

    Serial.print(" Long: ");
    getField(field, 5);  // number
    Serial.print(field);
    getField(field, 6);  // E/W
    Serial.println(field);
  }
}

void getField(char* buffer, int index)
{
  int sentencePos = 0;
  int fieldPos = 0;
  int commaCount = 0;
  while (sentencePos < sentenceSize)
  {
    if (sentence[sentencePos] == ',')
    {
      commaCount ++;
      sentencePos ++;
    }
    if (commaCount == index)
    {
      buffer[fieldPos] = sentence[sentencePos];
      fieldPos ++;
    }
    sentencePos ++;
  }
  buffer[fieldPos] = '\0';

  if (! bme.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }
  Serial.print("Temperature = ");
  Serial.print(bme.temperature);
  Serial.println(" *C");

  Serial.print("Pressure = ");
  Serial.print(bme.pressure / 100.0);
  Serial.println(" hPa");

  Serial.print("Humidity = ");
  Serial.print(bme.humidity);
  Serial.println(" %");

  Serial.print("Gas = ");
  Serial.print(bme.gas_resistance / 1000.0);
  Serial.println(" KOhms");

  Serial.print("Approx. Altitude = ");
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");

  Serial.println();
  delay(2000);
}

What exactly does "nothing happens" mean? You have print statements in setup. Are these showing up in your Serial Monitor?

All that will show up on the serial monitor is "BME680 test" Then it will just do nothing.

put in more serial.print statements ... figure out where it stops

You have the BME pins defined for an SPI connection, but your created an instance for I2C connection with Adafruit_BME680 bme;, so how exactly you wire your BME sensor with the Arduino?


text:
How to use capactive touch on Adafruit board in Arduino mode?
I have a Trinket M0 which has three pins capable of capacitive touch, A0, A3, and A4. When using CircuitPython on these boards you can use the CapTouch Library. But as far as I can tell this does not exist for use in Arduino mode. Does anyone know how to get these pins to pick up capacitive touch? I've tried the Adafruit_FreeTouch library, but with zero documentation, it's not very user friendly. I thought I had it working with two pins, but whenever both pins detect capacity, the capacity is divided between them, so both pins report about the same capacity.
Any help would be greatly appreciated.
This question does seem like a duplicated of Built-in capacitive touch detection with SAMD21 development board (Arduino Zero Compatible) but there was never a solution.
Thanks!

have you tried the example code that is included with the Adafruit_FreeTouch library?

look at page 861 of the datasheet ... http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D21_DA1_Family_DataSheet_DS40001882F.pdf  ... the touch pins can be used discretely or in a matrix configuration

Example code for capacitive touch on Trinket M0.  Note: make sure to install the Adafruit FreeTouch library.
// touch - Capacitive touch demo using FreeTouch. Trinket M0 version.
// Note: the pin silkscreened 1 is Analog Pin 0.

#include "Adafruit_FreeTouch.h"

Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(A0, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);

void setup()
{
  // Initialize A0 as a touch sensor
  if (! qt_1.begin())
    Serial.println("Failed to begin qt on pin A0");
}

void loop()
{
  int counter, result = 0;
  counter = millis();
  result = qt_1.measure();
  Serial.print("QT 1: "); Serial.print(result);
  Serial.print(" (");  Serial.print(millis() - counter); Serial.println(" ms)");
  Serial.println("\n*************************************");
  delay(200);
}

Information about the parameters for the constructor can be found at: https://forums.adafruit.com/viewtopic.php?f=8&p=610501  and are paraphrased below incase the link goes dead.
The parameters for the constructor are:
p - The input pin connected to the sensor.
t - How much to oversample the input.  One of the following:
OVERSAMPLE_1
OVERSAMPLE_2
OVERSAMPLE_4
OVERSAMPLE_8
OVERSAMPLE_16
OVERSAMPLE_32
OVERSAMPLE_64

Oversampling is a process of taking several measurements, finding the average, and reporting that instead of the actual readings. It's way of reducing noise, but also improves the accuracy of the measurement. The average value of noise is zero (if it wasn't, it would be a source of free energy), so the more readings you add together, the closer the noise error in the measurements approaches zero.
There's another side-effect of adding noise to measurements though: it dithers the sensor output around the real input value. If I have a window comparator that only measures "below 1v" and "above 2v", and feed it a signal at 1.1v plus a couple of volts of noise, I can expect to see about ten "below 1v" outputs for every one "above 2v" output. The noise pushes the signals above and below the thresholds, but vanishes if I take the average of a large enough sample. Statistically, getting a 10:1 improvement in resolution like that would take about 64 readings to make the noise error small enough to ignore.
Oversampling takes longer though, so there's always a tradeoff between how much you can do and how long the signal will remain stable.
r - The value of the resistor that will discharge the touch pad.  One of the following:
RESISTOR_0
RESISTOR_20K
RESISTOR_50K
RESISTOR_100K

f - Frequency mode.  One of the following:
FREQ_MODE_NONE
FREQ_MODE_HOP
FREQ_MODE_SPREAD
FREQ_MODE_SPREAD_MEDIAN

For systems that take repeated measurements, there's one kind of noise that doesn't average to zero: noise that occurs at the same frequency as the sampling rate. There are all sorts of videos that show the effect of a camera being in sync with the thing it's recording.. this one is especially nice:   https://www.youtube.com/watch?v=uENITui5_jU
For capacitive sensors, things like induced signal from fluorescent lights can create noise, and if the lamp frequency is just slightly off of your sampling frequency, the touch system will think it looks like a series of touches.
(If you have an oscilloscope, hold the tip of a probe between your fingers and put your hand within a foot or so of a fluorescent light.)
One way to prevent that is to change the sampling frequency. You can shift it up and down in a predictable pattern, hop from one frequency to another, or add some random jitter. Atmel's QTouch library supports all those options, but 'NONE' (fixed frequency readings) is the simplest.

Yes, FreeTouch is the answer.