text:
Serial.flush() in arduino
I am new to Arduino and I have the following:
int     delaynum;
char    cval[12];

void setup()
{
 Serial.begin(9600);
 Serial.print("Enter Number");
 Serial.flush();

 int i=0;
 while(i<12)
 {
  if(Serial.available()>0)
  {
    char ch=Serial.read();
    if(ch>='0'&&ch<='9')
    {
      cval[i]=ch;
      i++;
    }
    else
    {
      cval[i]=0;
      delaynum=atoi(cval);
      break;
    }
  }
 }
}
void loop()
{
   Serial.println(delaynum);
   exit(0);
}

The code output in virtual bread board:(i Entered 100)

But when i remove Serial.flush() The output like (i Entered 100)

I am Expecting the output:
Enter Number (I want to enter number 100 after the output)
100
Why the code not working ?
I am using Arduino IDE with virtual bread board(ATMega328p)

it is an error of the emulation. Serial.flush() only waits until the data are sent completely.

Not knowing what virtual breadboard does on a normal Arduino it would do the following:
Serial.flush() clears the buffer  and this needs some time normaly you wait minimum for around 100 ms to write/read to that buffer again. As your code runs in setup (so just once) the serial is not available as its still flushing and so your result.
As the name setup says this should only be used to setup HW/SW but not to run routines as you may get all sorts of weird results. If you use "\n" aka newline terminators in your communication you can go for them and flushing would be only necessary if the connection is interrupted and you have to resend data.
EDIT

Waits for the transmission of outgoing serial data to complete.

If you send a character, it is placed in a buffer for transmission. It takes time for each character to be sent because serial is slow. Once it is in the buffer, it will be sent automatically in the background while the program immediately moves on to the next statement. This is done so the program won't waste time waiting for characters to be sent.
flush() is a way to wait for it to be sent, instead of immediately moving on in the user program.
So after calling flush() you can be sure that all data has been sent, and the buffer is empty. So in your case where you placed it it makes no sense.

Can you explain in more detail and Arduino use same buffer for both input and output or serial.flush() flush both input and output buffers?

See my edit above. Please mark as accepted if its ok

So in your case where you placed it it makes no sense, why? Arduino does not wait in setup function and what is solution for this can you explain please i am new to this.

Please read on Arduino.cc the basic101 I am not gonna teach here we solve one problem at a time

somehow this answer doesn't say anything to answer the problem

I don't understand "As your code runs in setup (so just once) the serial is not available as its still flushing and so your result.". Why would Serial not be available?

I hate people just writing comments without enlighten us all with their wisdom His problem is when calling serial.flush before id serial.available in a setup routine it does not show any output in Android and he asked why? Serial flush takes time to complete and so the next step (if) is not processed what would be the case if it where in the loop (cause its comming back to the routine) every x ms. The answer is run code in loopor dont flush without delay in setup.

the if after flush is in a while loop which doesn't finish until 12 digits or a nondigit character is received. in very old Arduino core flush would be used to empty the receive buffer.


text:
how to get esp32 ip address ,which is being connected to local network
I need to know the IP address of ESP32 on the local network(without printing ip on serial monitor ). The idea is to do mDNS or UDP broadcast to send the IP to the android application. The app will then use that IP to do the communication. Is there someone who has already done it?

You have already answered it yourself.  The idea is to do mDNS... - that is exactly what mDNS is for. You don't know the IP address, so you look it up with mDNS.

You don't. You configure mDNS (as you already suggested in your question...!) and the client device then queries mDNS to find the device by the name you allocated it.
Look at the ESPmDNS library examples for how to use mDNS.
Edit: if you really want the IP, you can do WiFi.localIP() (station mode) or WiFi.softAPIP() (access point mode).

source: Stack Exchange

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

sort: votes


text:
Adafruit Metro Mini FTDI chip overheating
I have an Adafruit Metro Mini board that I am using. After soldering the board and accessories to a perfboard the FTDI chip is overheating, the COM port will not show up on the PC, and the 3V pin does not produce any power while the board is plugged in.
Is there a way to fix this? Have I nuked my board?

Maybe short or you reversed something

The 3.3V output of the FTDI chip might be shorted to Gnd, or overloaded by your circuit. Start by checking that.

Is there a way to fix this?

Yes. Undo whatever short circuit you have created with your soldering.

Have I nuked my board?

Possibly, possibly not. Most likely the short is making the regulator go into thermal shutdown and no lasting damage has been caused. But you can't be sure.

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


text:
Problems running Arduino project off a 9V battery
I have been working on an Arduin Uno Rev2 project for a while now. I have been developing using my MacBook, downloading code through the USB jack running it, monitoring the serial output on my MacBook, etc.
The Arduino is being powered from my MacBook through the USB jack which is also carrying the serial output back to the MacBook.
But now I want to make this project portable. IE: instead of powering it off a wire from my Macbook, I want to power it off a battery. So I followed these instructions #4 and connected up a 9V battery to the VIN pin.
At first it seemed to work. But very soon started noticing great instability. There are many serious problems I need to solve working off this battery:

As soon as I connect up the battery, I loose the Serial Monitor connection (even though the USB cable is still connected). So I can no longer see what's going on inside the Arduino for debugging purposes. Why? How can I continue to see the Serial Monitor? Is there a way to see the serial output from somewhere other than the USB jack?
I can tell by the lights on the board and by the behavior of the outputs that the software is malfunctioning. But I can't tell exactly why (because of #1). Why would changing the power source cause this?
I know that the VIN pin needs 7-12 volts. The battery I plugged in is a new 9V battery. But what happens as it wears down? Does it still push 9 volts? Or does the voltage drop? Can I tell my Arduino to stop functioning if the voltage drops below acceptable levels? Because ceasing altogether is better than malfunctioning.
I have read that I need to ensure that the current from the battery remains around 500mA. But how can I measure that in hardware/software? This ties back into question #3.

the Uno WiFi Rev 2 has too high current draw for a 9 V battery and it will empty any battery very  fast. I would try an USB power bank maybe.

A 9v battery is useless. Use a better battery.

@Majenko what battery should I use? A bank of 6 AA 1.5 V batteries?

Use a USB power bank.

I want to power it off disposable, non-rechargable batteries that can be purchased at regular groceries stores. So I think that rules out USB power-banks.

Than make sure to buy large quntities of batteries and change often - vote to close

Why vote to close when nobody has answered questions #1, #3 or #4?

Q3 ("Or does the voltage drop?" Yes it does; and it does it even when the battery is new. All batteries have some internal resistance, so the more current you draw, the lower the battery voltage. 9v batteries are especially poor in this respect - they really are meant for very low current / long run-time devices like smoke detectors and do a very poor job of supplying larger currents. You'll do much better with 6 Alkaline cells. Choose the size battery that gives enough run-time between replacements.

As soon as I connect up the battery, I loose the Serial Monitor connection (even though the USB cable is still connected). So I can no longer see what's going on inside the Arduino for debugging purposes. Why? How can I continue to see the Serial Monitor? Is there a way to see the serial output from somewhere other than the USB jack?

Probably because although the voltage is high enough to cut off the power from the USB port it's not got enough current to run the main MCU properly.

I can tell by the lights on the board and by the behavior of the outputs that the software is malfunctioning. But I can't tell exactly why (because of #1). Why would changing the power source cause this?

Because 9V batteries can't provide enough current.

I know that the VIN pin needs 7-12 volts. The battery I plugged in is a new 9V battery. But what happens as it wears down? Does it still push 9 volts? Or does the voltage drop? Can I tell my Arduino to stop functioning if the voltage drops below acceptable levels? Because ceasing altogether is better than malfunctioning.

No. The voltage drops rapidly to about 8V then down and down and down until it's below what the regulator can regulate. You can see this curve in any battery datasheet.

I have read that I need to ensure that the current from the battery remains around 500mA. But how can I measure that in hardware/software? This ties back into question #3.

That's nonsense. The current demands will be whatever the circuit needs at any moment in time. There will be an upper limit to that demand (defined by your circuit and what you are doing at any one time - the peak current draw) and your power source has to be able to provide at least that amount of current.  If you try to draw more current than the battery can handle then the output voltage will drop to a level where it can no longer power the circuit properly. It is at this point you get "brownouts" and the board resets randomly and strange unpredictable things happen.
In short: never use a 9V battery for an Arduino project. It's fine for vert low power operations, which take careful design, but for general use stay away from them. Also the Arduino's built-in regulator is a very inefficient and will waste about 25%-40% of a 9V batteries power before you even begin. Instead you should use a more efficient switching regulator to provide 5V directly to the 5V pin (or USB port) from suitable higher capacity batteries (such as AA cells).

As a comparison here's some typical battery discharge graphs comparing alkeline AA to PP3 (9V). These are both Duracell Ultra.

As you can see the PP3 drops its voltage very rapidly even under a light load. Under a "heavy" load (what would be considered a very light load to an AA) it tumbles away to next to nothing in no time at all.

Thank you for this explanation. I'm a software guy.
New to the world of hardware engineering and electricity.

@SaqibAli Then to give you a context you will understand: Device datasheets are the API of the hardware world. When programming you need to know the API. With electronics you have to understand the power and timing. Reading the datasheet is just the same as reading a library's API document.

If I get this working with AA batteries, then how can I get the serial output while running on battery power?

It should "just work".

When I get this working with AA batteries, can I get the Arduino to simply shutdown if the voltage is too low rather than have brown-outs, malfunctions and other unpredictable behavior?

If you build a circuit to do that, sure. It's not something the Arduino can do alone - the Arduino has no concept of "shut down" other than holding RESET low, which has to be done externally.

Actually I thought, that brown out detection is meant to hold the Arduino in reset, until it has sufficient voltage, to prevent it from malfunctioning. Then you would just need to configure it correctly


text:
Pulse generator with varying width
I am trying to generate a square pulse with a fixed delay of 5 second between pulses and varying width of the pulse. The code I wrote so far generates a sequence of pulses every 5 seconds. Is it possible to generate one pulse (with varying width) every 5 seconds instead? Could you please help me with it?
const int pin =  11;

int i  = 0;

void setup() {
    Serial.begin(9600);
    pinMode(pin, OUTPUT);
}

void loop() {
    i = random(0 , 255);
    analogWrite(pin, i); // turn on LED
    delay(5000);
}

use digitalWrite and set the pin HIGH for desired duration

AnalogWrite generates a series of pulses with a varying duty cycle. If you only want a single pulse, you should probably write the code manually.
What range of pulse widths do you want, and with what precision and accuracy?

As others have said, you could use digitalWrite() and the millis() function to get decent precision and accuracy. If you need higher precision and accuracy though you may want to switch to using port registers to manipulate the pin directly. That is significantly faster to respond than the digitalWrite() function, so you can make your timing more exact. And if you need sub-millisecond precision you could use the micros() function for your timing.

Thank you for your replies and suggestions. I am trying to synchronize two neural recording systems. Therefore I am trying to generate those pulses with varying width and fixed time so I can align them later on offline, to set a proper off set time in data analysis. I was thinking of pulse widths (5-500)ms.

Simple but not fully accurate:

Turn on LED
Delay for the amount of pulse width (e.g. 20)
Turn off LED
Delay 5000 ms - pulse width (20) thus 4980 in this example

However, since turn on/off a LED will also take some time, this will take slightly more than 20 + 4980 = 5000 ms.
Thus better is:

Set time to a variable (use millis function).
Turn on LED
Wait until time >= pulse width
Turn off LED
Wait until time >= 5000

I wonder why OP used analogWrite.

@Juraj I assume he wants a 'random'  pulse width (PWM) generated. so the pulse width I use in my example is some random time the OP should use.


text:
Individually addressing LEDs in a multiplexed matrix
I have created my first LED project with a hand made 4X4 LED matrix. The cathodes are joined horizontally to make the rows and the anodes are joined vertically to make the columns the columns. It is controlled by a shift register with the cathodes (rows) connected to pins 0-3 and the anodes (columns) connected to pins 4-7 of the register controlled from an Arduino Nano.
It all works but I have hit upon a limitation that I have not seen in the various videos and tutorials about making LED matrices so I suspect I am missing something.
This code will light up the bottom left LED which I will call position (0,0).
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, B00011110 );
digitalWrite(latchPin, HIGH);

This code will light up the LED at position (1,1), so one up and one to the right.
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, B00101101 );
digitalWrite(latchPin, HIGH);

If I then combine the two as below:
digitalWrite(latchPin, LOW);
shiftOut(dataPin, clockPin, MSBFIRST, B00111100 );
digitalWrite(latchPin, HIGH);

it of course lights up 4 LEDs: (0,0),(0,1),(1,0) and (1,1).
This feels like a limitation of wiring the LEDs in this way because once you power a row in a given column, you cannot unpower it in subsequent columns or vice versa. i.e. lighting (X,Y) and (A,B) means that you cannot have (X,B) and (A,Y) unlit.
However, in the videos I have seen that accompany tutorials on how to make similarly constructed matrices, I can see them lighting up in ways I can't replicate.
How can I light up an LED at positions (0,0) and (1,1) without also lighting up (0,1) and (1,0)?
Is this possible with this configuration?

You are looking for "switching between 0,0 and 1,1 fast enough, that eye can't see it's not lit at the same time, but slow enough it's visible" - Multipexing

You need in principle at least 50 Hz to trick your eyes (or actually brains).

@KIIV Thanks that seems to work well.

Thanks to KIIV in the comments I figured it out. Apparently the trick is to rapidly switch between columns or rows without ever having two on at the same time.
With the below code running in the main loop it appears that (0,0) and (1,1) are lit at the same time even though they are actually switching rapidly.
void loop()
{
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B00011110 );
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, B00101101 );
  digitalWrite(latchPin, HIGH);
}

Yup. That is a common issue with matrixed displays. Note that it's possible to light your LEDs one row or one column at a time. You shift in the states of all the LEDs in 1 row, then turn those off and turn on the LEDs in the next row, etc.


text:
Securing ESP8266 connections
In my setup, I've got a number of ESP8266 devices around my home controlling various devices like my boiler and some lights.
They're all controlled by a central smart hub on a Raspberry Pi with a static's IP address.
This works great, but I'm increasingly concerned of the security implications of this. Communication between the Pi and the various ESP8266s is currently done over HTTP, with all the commands simply in the URL the Pi requests from the web servers.
As such, anyone on my network could theoretically control these smart devices using a simple curl request.
Whilst I have a strong Wi-Fi password, and am using WPA2 encryption, I would feel much more comfortable if communication with the ESP8266s was controlled in some way. E.g. in the same sort of way you can only connect to an SSH server using public key encryption if you have the right private key.
Is something like this possible to implement on an ESP8266? I've done some searching and only found articles about HTTPS which doesn't seem like it would solve my problem.
Thanks in advance,
Rocco

You could have a shared password. Then have the sender hash that password concatenated with the time and data, and perhaps some random nonce. Send the time, nonce, data and hash to the ESP. The ESP can then do the same at it's end and validate that the hashes are the same. The ESP can validate the sender has the same password, and that the message hasn't been altered. Data however is still send in the clear, but in this case, I don't think it matters. The time is there to prevent replay attacks. Either have the ESP know the time through NTP, or have it store the timestamp of the last message.

@Gerben Thanks, that's a great idea! I feel your solution may be more relevant as it takes far less compute time on the ESP. I'm not quite sure how properly solve the problem of the ESP getting the time. Getting from the NTP would be off by a few milliseconds or seconds, and I'm not quite sure what you mean about the time stamping.

you don't need accurate time. The time is just there to prevent replay attacks. You store the last time stamp of the last message, and then only accept messages with newer timestamps. To prevent replay attacks after the ESP is reset, you could use NTP and make sure the message isn't older than a few seconds or so. PS just to reiterate; the sender sends the timestamp, along with the data, to the ESP.

The simplest method is to encrypt your communication channel using some secret key.  You could use the built-in AES encryption functionality, which would mean that only people that know the key could encrypt a request in such a way that the device at the other end could decrypt it.
You would think that SSL (HTTPS) would do the job, but that only provides interception security, not authentication. Of course for even more security you can combine both HTTPS and AES encryption.  One for overall encryption, and the other for encryption-based authentication.

Thanks for your answer. So you suggest encrypting the instruction on the hub, sending it to the ESP8266, then decrypting it with some key and executing it on the ESP8266? Wouldn't it also be wise to implement HTTPS in this case to prevent replay attacks?

Sure, you can also use HTTPS. More is always better :)


text:
Attiny85 SoftwareSerial not working on battery power
I have a very small test project running on an Attiny85 (set to internal 8MHz).
Everything works when powering the circuit from an Arduino (3.3 or 5.0 volt). But when changing the  power to a 18650 battery with a voltage of around 4.0v the Attiny85 still works, because the LED blinks, but nothing is coming through via the UART. What could be the reason for this?
#include <SendOnlySoftwareSerial.h>
#define PHOTO_RESISTOR_PIN A1
#define UART_TX_PIN 0
#define LED_PIN 1

SendOnlySoftwareSerial esp(UART_TX_PIN);

void setup() {
  esp.begin(9600);
  pinMode(PHOTO_RESISTOR_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(UART_TX_PIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_PIN, HIGH);
  int light = analogRead(PHOTO_RESISTOR_PIN);
  esp.println(light);
  delay(1000);
  digitalWrite(LED_PIN, LOW);
  delay(1000);
}

Do yoou not have the ground of the ATTiny circuit connected to the ground of the UART board???

That was it! So the reason why that works when running off the Arduino power is that they share the same ground in the computer (that powers them both)?

Yep. You might like to read this:https://majenko.co.uk/blog/importance-sharing-grounds

Absolutely, thank you!

Unless you connect the ground of your ATTiny to the ground of your USB UART interface there is no circuit for the electrons to flow around.
It works when powered from the computer because everything shared the same ground connection.


text:
MEGA 2560: Simple program - One analogWrite turns off the other
I'm using Windows 10, Arduino 1.8.12 (Windows Store 1.8.33.0)
I have an Arduino MEGA 2560 and a red LED connected to pin 4.
#define RED 4
#define GREEN 2

void setup() {
  analogWrite(GREEN,  0);
  analogWrite(RED,  100);
}

void loop() {

}

This code lights up the red LED.

However, when I write 1 to the GREEN pin analogWrite(GREEN,  1), the red LED goes off. I'm expecting the red LED to stay on.

#define RED 4
#define GREEN 2

void setup() {
  analogWrite(GREEN,  1);
  analogWrite(RED,  100);
}

void loop() {

}

The red LED stays on when both written values are the same, e.g.
  analogWrite(GREEN,  25);
  analogWrite(RED,  25);

I also found that adding some "garbage" code at the beginning fixes the issue. I wasn't able to get the garbage into a simpler form without both pins shutting off.

#define RED 4
#define GREEN 2

void setup() {
  // GARBAGE BEGIN ===
  unsigned long t = millis();
  const unsigned long period = 10;
  float progress = float(t % period)/period;
  float r = progress * 0;
  // GARBAGE END ===

  analogWrite(GREEN,  100 + r);
  analogWrite(RED,  50 + r);
}

void loop() {

}

Update: Thanks all for your comments. Setting the pinMode to output did not fix the issue. However, changing the function declaration to __attribute__((optimize("-O0"))) void setup() { fixed the issue. -O1 also works, but -O2 fails.

Do both LEDs have suitable current-limiting resistors?

Actually there is only one LED attached, and it's connected through a 220 Ohm Resistor.

Please, show your circuit schematic.

Wait, what? There's only one LED attached, but when you turn on one of your LEDs the other one turns off? That makes no sense.

@DuncanC it's not that I turn on another LED, it's that I analogWrite to an additional pin and it turns off the LED pin.

do both pins exhibit the same behavior?

@jstola Yes, it seems that doing simultaneous writes will disable both of them.

looks like a bug in the library ... do you have the correct board selected in the arduino IDE? ... does the behavior remain if you insert a command line between the two ... something as simple as a++;

Try before the write pinMode(GREEN, OUTPUT); pinMode(RED, OUTPUT); and give feedback if it worked

@Codebreaker007 I started to post that the OP was missing the calls setting the pins to outputs, but if you look up the docs on analogWrite() it says specifically that you don't have to set the pin to output before using it, which surprised me. It's probably still worth trying a try though.

You should post an answer to your own question. with the solution you found. I would suggest trying calls to pinMode(GREEN, OUTPUT); pinMode(RED, OUTPUT) as Codebreaker suggests, as well as adding a short delay in your setup in place of the "garbage code" you posted.

If you use ArfuinoIDE < 1.6 you have to define pin mode, since then its done in analogWrite.c.If using IDE >=1.8.10 its an optimization problem by the compiler for the Mega try to replace the line void setup() with void setup() attribute((optimize("-O0")));  // also -O1 works the default -Os and -O3,-O4 not

If you look in the source code for analogWrite, one of the first things it does is set the pinMode.

Yes since around 1.6 on as I wrote as we do not know OPs version we have to exclude basic things not everybody is always on the latest version

@Codebreaker007 Setting the optimization level to 0 or 1 fixes the issue (see my update in my post). I'm wondering if you can direct me to an explanation of why this occurs.

However, would you mind to answer your own question, and mark it (later, if you're forced to wait), please? This will help others investigating the same problem, because they can upfront see that your problem is solved.

As you are using using ArduinoIDE >=1.8.10 its an "optimization" problem by the compiler for the Mega try to replace the line
 void setup()

with
 void setup() __attribute__((optimize("-O0")));

// also -O1 works the default -Os and -O3,-O4 not
Actually the problem is not the IDE version but the included AVR boards package version.  You can install any AVR boards package in any IDE with Boards Manager. Last good AVR boards package is 1.6.21. If your compiler (tool chain) shows 7.03 in the output window you  are affected. I have examples where the compiler even optimizies the loop away, which ends in funny results - I dont know wether other boards are also affected but the MEGA is for sure.

Is there a bug report issue opened with Arduino for this? This definitely needs to be fixed!

Yeah more than one the last one https://github.com/arduino/Arduino/issues/9659

This one looks relevant as well https://github.com/arduino/Arduino/issues/9653


text:
Web page using bluetooth?
I have a project where I read 2 sensors using an esp32 and also have an web server. I can connect using mobile phone and display the page where I see info about the sensors (using web sockets to update the info on the page very quickly ) and also send some commands back to esp32. Is working fine, just the issue that when I am connected to esp I don t have internet on my phone anymore (which is a normal thing:) ).
My question is if I can achieve same but using bluetooth instead wifi ? Is there any way to have a "web page" using bluetooth ?
Thank you

why not connect the esp32 to the same WiFi network you connect your phone?

Of course you can use bluetooth to comunicate with a webpage
here is an example
https://github.com/hewittwill/WebBluetooth-Terminal

No. There is no such facility in Bluetooth to provide such a feature.  That's not to say that technically it can't be done, there just isn't any software (a web browser) that would support it.
Instead you would need to use a Bluetooth-enabled app on the smartphone to communicate with the ESP32 over Bluetooth and display the data / provide control natively.  Such an app would probably have to be written by you since it would be specific to the way you are working, unless you can find a generic app that lets you design an interface for your project and then communicate using a documented protocol that you would then have to implement on the ESP32.

An alternative is to just reverse everything. Instead of having your phone connect to the ESP32 then connect to a webserver on it just have the ESp32 connect to your phone when your phone is set to WiFi Hotspot mode. You can still then get your phone to connect to the webserver on the ESP32, and your phone also has mobile internet. If course, if you are wanting internet through a WiFi connection for your phone then you can't do that. However, your ESP32 can then just also connect to your WiFi router so there is nothing to change on your phone. You just browse to the webserver on the ESP32 through your local WiFi network.

There is an experimental feature called the Web Bluetooth API. You could host a single file on a Webserver which then interacts via Bluetooth with your ESP. Keep in mind that aside from localhost you have to use https as protocol. Here is a Tutorial that shows how you can read and write to Bluetooth caracteristics using JavaScript.

Program your ESP32 to connect to your wifi - it then gets its own IP address on your LAN (e.g. 192.168.1.123 ) - then connect to your ESP from your phone (or anything else on your LAN).
Have you tried micropython? Works amazing on esp32 - makes everything super easy


text:
Modbus programming
I have a Controllino Mega running a code that rotates a stepper one revolution CW, and one revoluction CCW.
I need the program to run, just when a signal is received from an HMI that I have connected to the Controllino via ethernet.
This is my first time using modbus. I have seen some examples using the modbus library, and I know I have to declare the variables in void setup, but don't know how many variables I need and if they  have to be analog or digital. I don't know either how to read those variable within void loop.
    #include <SPI.h>
    #include <Controllino.h>
    #include <Ethernet.h>
    #include "MgsModbus.h"

    MgsModbus Mb;

    const int pul = 46;  // pin 46 to PUL -
    const int dir = 47;  // pin 47 to DIR -

    void setup ()
     {

        byte mac[] = {0x90, 0xA2, 0xDA, 0x0E, 0x94, 0xB5};
        IPAddress ip(10, 7, 4, 17);
        IPAddress gateway(10, 7, 4, 17);
        IPAddress subnet(255, 255, 255, 0);
        Ethernet.begin(mac, ip, gateway, subnet);
        delay(5000); // Time to open the terminal
        Serial.begin(9600);

        pinMode (pul, OUTPUT);
        pinMode (dir, OUTPUT);
     }

     void loop()
     {

 Mb.MbsRun();

   digitalWrite(dir, HIGH);
  /*Turns the motor 400 steps*/
  for (int i = 0; i < 400; i++)
  {
    digitalWrite(pul, HIGH);
    delayMicroseconds(1000);
    digitalWrite(pul, LOW);
    delayMicroseconds(1000);
  }

 delay(1000);

  digitalWrite(dir, LOW);
/*Turns the motor 400 steps*/
  for (int i = 0; i < 400; i++)
  {
    digitalWrite(pul, HIGH);
    delayMicroseconds(1000);
    digitalWrite(pul, LOW);
    delayMicroseconds(1000);
  }

delay(1000);

 }

is Arduino slave or master?

Arduino is the slave.

then setup the registers. the library has examples


text:
An array of existing arrays
I have a bunch of 3D arrays in the following form:
byte lines[][4][2] {
                     { {B00000000, B11110000 },
                       {B00000000, B11110000 },
                       {B00000000, B11110000 },
                       {B00000000, B11110000 } },
                     { {B11110000, B00000111 },
                       {B00000000, B11111000 },
                       {B00000000, B11111000 },
                       {B00000000, B11111000 } },
// continues for numerous elements
                    }

They are a bunch of values to push out to a pair of shift registers controlling an LED matrix. Each array is essentially an animation that plays across the LED matrix.
I would like to put my collection of arrays into an array so I can iterate through them. I know I can just combine them into one big array but the code is already opaque and I would at least like to keep separate named arrays so I can sequence and rearrange a series of animations by rearranging a series of named arrays in another array rather than one massive array of opaque binary values.
I want to do something like this
sometype* sequence[] = { lines, circles, squares } ;

or if that's not possible then:
sometype* sequence[3];
sometype[0] = lines;
sometype[1] = circles;
sometype[2] = squares;

Can I do this or some approximation thereof? If so what is "sometype"? I can't figure out how to say "an array of pointers to 3d byte arrays" or whatever it is I am trying to do. What is the syntax for deeclaring the array and dereferencing the pointers?

Try this:
byte (*sequence[])[4][2] = { lines, circles, squares } ;

Explanation: The identifiers lines, circles and squares decay
to pointers to the first element of each array. Their decayed types are
then “pointer to array of length 4 of array of length 2 of byte”. This
type could be declared as
typedef byte (*pointer_to_2d_array)[4][2];

The sequence is then an array of this type, which can be declared as
pointer_to_2d_array sequence[] = { ... };

or, if you appreciate the obscure elegance of the C syntax, as in the
beginning of this answer.

Yes, you can ( both ways )
You need
typedef byte sometype[4][2];

However, you'll probably need the size of lines, circles, etc. , which is lost by a pointer.
One way might be an end marker (A special element, indicating there are no more)
Another might be a
struct sometype {
  size_t n;
  byte [][4][2] data;
} lines ;

IMO, even 2D arrays are reaching the limits of human intelligence, and I'd prefer even more user defined types:
typedef byte Pattern[4][2]; // or a more appropriate name

Pattern lineArray[] {
             { {B00000000, B11110000 },
               {B00000000, B11110000 },
               {B00000000, B11110000 },
               {B00000000, B11110000 } }
          , { {B11110000, B00000111 },
               {B00000000, B11111000 },
               {B00000000, B11111000 },
               {B00000000, B11111000 } }
};

typedef struct {
  size_t count;
  Pattern* data;
} PatternCollection;

PatternCollection lines = {sizeof(lineArray)/sizeof(Pattern), lineArray };

PatternCollection sequence[] = {lines /* , circles, squares */ }; // if you ever need to iterate them


text:
strcat gives error when I try to add a char to a char array
I have
char c;

where
int bt_available = Serial2.available();
if (bt_available) {
  c = Serial2.read();
}

and later in the code I try to
strcat(some_char_array, c);

and it gives me this error

initializing argument 2 of 'char* strcat(char*, const char*)' [-fpermissive]
  error: invalid conversion from 'char' to 'const char*' [-fpermissive]

My best guess why the error appears would be that strcat can only accept strings and char arrays, but not single characters, so a solution I can think of would be to create a char array like char test[1] where test[1] = '\0' and then test[0] = c but I'm not sure if that's the best way to go about the problem and if that's a solution. Does 'const char*' mean 'char[]'?
P.S I read Majenko's blog thingy and I'm turning all Strings to char arrays and it's a bit of suffering :P

A char is a single character. A char * and a char[] are both arrays of characters (more correctly char * is a pointer to an array of characters).
strcat expects two arrays or pointers to arrays of characters. If you want to add a single character you can either fool the compiler into thinking that the character is an array of characters of size 1 (but it lacks the required NULL termination) or manually manipulate the target array.
For the former you could use strncat and casting:
strcat(some_char_array, &c, 1);

That gives you a pointer to the character, which is as far as the compiler is concerned, indistinguishable to a pointer to an array of characters. You use the "n" variant of strcat  to limit it  to just one character (plus an added NULL character) so it doesn't rely on the missing NULL termination.
For the second you could do:
int n = strlen(some_char_array);
some_char_array[n] = c;
some_char_array[n+1] = 0;

That just sets the Nth character in the target array to whatever is in c, then adds a new NULL termination character to the end.


text:
Serial communication arduino mega and D1 Wemos Mini
Can anyone help me connecting arduino mega to D1 Wemos Mini serially? Please let me know most efficient and easy steps to setup a communication.
Using that following tutorial:
https://engineeringprojectshub.com/serial-communication-between-nodemcu-and-arduino/amp/
Following is the circuit diagram:
https://i.stack.imgur.com/oOKwL.png

Rx to Tx3 and Tx to RX3, gnd and 3.3 V. ready. in Mega in code use Serial3 to communicate with esp8266.

@Juraj Is the Wemos Mini 5V tolerant? Otherwise a voltage divider would be needed between Mega TX and Wemos RX

@AliHassanRaza What exactly is your problem with setting up the connection? Serial (aka UART) has only 2 lines plus ground connection. There are many tutorials on the web. Did they not help you? What exactly couldn't you understand there?

@chrisl, voltage divider would limit the speed and complicate troubleshooting.. the esp8266 can handle 5 V logic pull-up current for a test. in long term setup I recommend a level shifter, not voltage divider

I am not getting anything when I try to serially communicate them.

Then you need to show us your code and wiring. Please edit your question and add the information there, not in the comments, as the comments are only temporary

if (esp.available()>0)
{
Serial.println("Inside");
int data = esp.read();
Serial.println(data);
}
It is not going inside this condition, neither at arduino side nor at esp side

Using that following tutorial:
https://engineeringprojectshub.com/serial-communication-between-nodemcu-and-arduino/amp/

what is esp? SoftwareSerial? use hardware Serial3 (or 1 or 2). SoftwareSerial doesn't work on all pins of Mega

Apart from ensuring you're wiring TX -> RX and connecting all grounds, you can use SerialTransfer.h to automatically packetize and parse your data for inter-Arduino communication without the headace. The library is installable through the Arduino IDE and includes many examples.
Here are the library's features:

This library:

can be downloaded via the Arduino IDE's Libraries Manager (search "SerialTransfer.h")
works with "software-serial" libraries
is non blocking
uses packet delimiters
uses consistent overhead byte stuffing
uses CRC-8 (Polynomial 0x9B with lookup table)
allows the use of dynamically sized packets (packets can have payload lengths anywhere from 1 to 254 bytes)
can transfer bytes, ints, floats, and even structs!!

Example TX Arduino Sketch:
#include "SerialTransfer.h"

SerialTransfer myTransfer;

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

void loop()
{
  char buff[] = "hi";

  myTransfer.txObj(buff, sizeof(buff));
  myTransfer.sendData(sizeof(buff));
  delay(100);
}

Example RX Arduino Sketch:
#include "SerialTransfer.h"

SerialTransfer myTransfer;

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

void loop()
{
  if(myTransfer.available())
  {
    char buff[40];

    myTransfer.rxObj(buff, sizeof(buff));

    Serial.println("New Data: ");
    Serial.write(buff, sizeof(buff));
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");

    if(myTransfer.status == -1)
      Serial.println(F("CRC_ERROR"));
    else if(myTransfer.status == -2)
      Serial.println(F("PAYLOAD_ERROR"));
    else if(myTransfer.status == -3)
      Serial.println(F("STOP_BYTE_ERROR"));
  }
}


text:
How to create and edit fonts for the Adafruit GFX library?
I noticed that the TomThumb.h font included in the Adafruit GFX library has characters that have different widths, which is a problem for me because I'm doing text processing that requires characters to have the same dimensions (width and height).
I also noticed that the TomThumb.h font misses some characters (such as '). I need a way to create/edit fonts for the Adafruit GFX (where I'm using the Adafruit_ST7735 on a 1.8" TFT display). I've looked around the internet but I couldn't find anything decent.

The library comes with a number of fonts. The ones named *Mono* are monospaced, which means that all the characters are the same size.

@Majenko Interesting. I thought that by default all characters are required to take equal dimensions.

Nope. Each character in the font ("glyph") specifies the dimensions and offset of the character, and also the "advance" - how far to move the cursor after printing the character.

@Majenko I'm surprised there isn't an easy way to create fonts for the Adafruit GFX. It's a relatively supported and used library.

I have various utilities for DisplayCore, but DisplayCore doesn't run on an Arduino.

@Majenko My main goal here is to display text of a book. Is there any way I can do that without using a monospaced font? Because I'm preprocessing the text on a phone and I'm doing the whole thing by counting how many characters a line can fit and so on so when a word doesn't fit, it goes to the next line... you get the idea. Is it possible to make the whole when-word-doesn't-fit-goes-on-next-line and with page switching functionality using a non-monospaced font? I suppose I'll have to know how many pixels each character takes so I do calculations...

Split your text into words and use the getTextBounds function to find out how wide it is. Add the width of a space. If it fits on the current line then print it. Otherwise start a new line and print it. You'll have to maintain your own cursor coordinates of course.

@Majenko Sound great! What do you mean about the cursor coordinates?

So that you know where to print your next word.

@Majenko Oh got it. The getTextBounds() requires the starting x and y of the word. Ahh, it's gonna be rather painful but I have no other option. Thank you for helping me out! :-)

@Majenko About the page functionality, do you have an idea of how it can be done? I'm reading the book content from an SD. The issue I have with the paging functionality is that if I'm on page 82, I have to process all pages until 82 and it's starting to lag as I get further into the book. I'm ready to drop the pages as a whole but I need some way to return the person to the place in the book from where he/she left, so he/she can continue reading. What would be the best way to go about this?

@Majenko After researching a bit, I think I can do it with fseek and remembering the last character of the last word... Thank you so much for helping me and suggesting the method above. You're the best!

@Majenko One thing that's unclear is, how would I go about going to previous pages? If I'm on some page and I've processed it and displayed it, how do I go to the previous page not knowing from which character to seek and so on...?

That is a tough one to suggest a solution to. Maybe plain text isn't the best format to store the data in.

@Majenko Hmm, I'm converting PDF to text and sending that from a phone to the Arduino via BT and then I'm displaying the text on a 1.8" TFT display. What else could I store it as when my goal is to make something like an e-reader?

Maybe render the pages on the phone as bitmap images and display those on the screen instead?

@Majenko Good suggestion but the text might not be visible or readable because the TFT display is rather small (1.8") and is 128x160 pixels and I don't think the content of the PDF page would be visible :P

I'm not thinking pages as they are on a PDF, but pre-rendered in your own chosen font.

@Majenko Yes but the issue of characters of fonts having different widths persists. As far as understood, on the phone, I create a bitmap image 128x160 where I overlay the text with the chosen font but I'll still have to do the same text processing as if it was being processed on the Arduino as text. It gets really complicated so I think I'll process the txt on the Arduino with the method you suggested above with getTextBounds...

@Majenko The idea of doing it with bitmap images is good but comparing pros and cos with the on-the-go processing with getTextBounds(), the latter is better because it allows for dynamic font changing, is less complicated and less heavy (because text files are lighter than bitmap images of pages). And also uploading speeds would be much much faster. Tell me what you think :-)

I found an online editor that can parse Adafruit GFX font headers, modify, and export the result to create a new font header.  It works very well.  May be a bit late to help OP, but for anyone else looking...
It uses regexes to extract info from the header files, so it's pretty strict on following the layout of GFX font headers provided by Adafruit.
webpage: https://tchapi.github.io/Adafruit-GFX-Font-Customiser/
github: https://github.com/tchapi/Adafruit-GFX-Font-Customiser

That works nicely, once you figure it out.

One possible solution you might already have: There’s a small utility called fontconvert that’s part of the Adafruit GFX library. The source code is installed by default together with the Adafruit GFX library in Arduino/libraries/Adafruit_GFX_Library/fontconvert You need Linux to compile it from the provided source code. It also compiles and runs on a Raspberry Pi.
It takes care of converting TrueType fonts (completely or partially) to Adafruit GFX format. There’s some documentation on compiling and using it in the fontconvert directory.

Thanks, I found it. Unfortunately, I don't have a Linux nor a Raspberry Pi. I could install a Linux VM. Isn't there an easier way? Like, some tool where you put the individual pixels for each character.

Well, there’s This. I don’t know how useful this is for you, but you could take a look at it.

Thanks, I'll take a look. I hope it'll do the job

I have used this website to generate various fonts, sizes, etc. with success.
http://oleddisplay.squix.ch/#/home

I have used truetype2gfx - Converting fonts from TrueType to Adafruit GFX.
It can make various sizes to a complete standard font.

@ocrdu - did you visit the website and try out the "tool"? How did it work for you?


text:
External vs arduino power supply for servo motors?
I recently created a project that involves the control of three SG90 servo motors. I started off by controlling this through the 5V output pin of the Arduino Uno, with the Arduino powered through the barrel plug with a 9V mains power supply.
However, the servos couldn't perform the full 180° sweep, it would appear to be due to the high torque at the end of the motion for my application.
I then switched to powering the servos separately to the Arduino using four AA batteries in series. I now had no issues with the servos stalling and could perform the full sweep.
I am not sure why this is though?
Four AAs in series will result in 6V, which is not that different to the 5V Arduino output pin? And it seems the current is the issue with servo stalling? and surely the number of batteries makes no difference to this as connected in series it stays the same? Is the current of the AA battery just higher than the 5V Arduino output pin?
Any help would be greatly appreciated, I'd really like to have a better understanding of this.

How much current does each SG90 servo draw? How much current can the Uno 5V regulator provide?

@VE7JRO I'm unable to measure the current directly but from some measurements I found online it appears the typical current during operation of the servo is 100-250mA with a stall current of 360mA. It appears the voltage regulator can get up to 800mA if pushed to the limit. Please note all the sources I got these values from may be inaccurate.

Here's some info on the SG90: https://arduino.stackexchange.com/a/49755/37523  I'm not sure what type of voltage regulator on your particular Uno, but heres some info on that: https://arduino.stackexchange.com/a/43894/37523

For controlling more than one/two max servo you should use a motor shield (h-bridge) or something like a PCA9865 board with external power supply. You get funny effects with three servos attached to the UNO when trying to do syncronized sweeps or high torque at the same moment in all three servos. Invest in that hardware, if there is enough Amp (1.5A and up depending on the num of servos) you could use a single PSU for both.


text:
Large number into variable
Probably something easy but I’ve not resolved it.
I’m extracting data from a JSON string and all the values are correct accept for two.
They are referring to two date time values and are in milliseconds.
One is the date refreshed and the other is date updated.
Problem is they are both very large and I’m having difficulty assigning them in the IDE.
One is 1588447162117 which is showing as 020-05-02 20:19:53.948  on the dashboard using the JSON.
Here is the code I have thus far to get the data from JSON:
#include <ArduinoJson.h>

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

  const char* input = "{TotalCases:3308678,TotalCasesToday:4458,TotalDeaths:234123,TotalDeathsToday:293,TotalRecovered:1042991,TotalTerritories:124,CurrentUpdatedMS:1588312648603,CurrentChangedMS:1588312648603}";

  StaticJsonDocument<512> doc;

  DeserializationError err = deserializeJson(doc, input);

  if (err) {
    Serial.print("Error: ");
    Serial.println(err.c_str());
    return;
  }

  unsigned long TotalCases = doc["TotalCases"];
  unsigned long TotalCasesToday = doc["TotalCasesToday"];
  unsigned long TotalDeaths = doc["TotalDeaths"];
  unsigned long TotalDeathsToday = doc["TotalDeathsToday"];
  unsigned long TotalRecovered = doc["TotalRecovered"];
  unsigned long TotalTerritories = doc["TotalTerritories"];
  unsigned long CurrentUpdatedMS = doc["CurrentUpdatedMS"];
  unsigned long CurrentChangedMS = doc["CurrentChangedMS"];

  Serial.print("Total Cases: ");
  Serial.println(TotalCases);
  Serial.print("Total Cases Today: ");
  Serial.println(TotalCasesToday);
  Serial.print("Total Deaths: ");
  Serial.println(TotalDeaths);
  Serial.print("Total Deaths Today: ");
  Serial.println(TotalDeathsToday);
  Serial.print("Total Recovered: ");
  Serial.println(TotalRecovered);
  Serial.print("Total Territories: ");
  Serial.println(TotalTerritories);
  Serial.print("Update time in ms:");
  Serial.println(CurrentUpdatedMS);
  Serial.print("Change time in ms:");
  Serial.print(CurrentChangedMS);
}

void loop()
{

}

**Serial monitor output**

Total Cases: 3308678
Total Cases Today: 4458
Total Deaths: 234123
Total Deaths Today: 293
Total Recovered: 1042991
Total Territories: 124
Update time in ms:0
Change time in ms:0

Should be good to manipulate it once I can work with it in a variable.
Thanks for any input,
Shane

what exactly is your question?

I guess you want to use uint64_t but depending on your hardware that might not be possible

What JSON library are you using? How did you code the reading of the value? Note that that number is about 2^40.53, so it won't fit in 32 bits. But it will if you drop the last 3 digits, which reduces the resolution to one second.

Please show your code

that number is hexadecimal 171D6D42F05 ... it fits into 64 bits

Isn't a long 32 bits on most Arduinos? Which Arduino boards support 64 bit integers?

Any. It's not down to the board. It's down to the compiler. The board defines how efficiently it handles them. Any board can use uint64_t

Fair point. I used to write 6502 code, where anything beyond 8 bits required manual carrying and such. A modern compiler will take care of that for you, at the cost of reduced performance.

JSON is overcomplicated for embedded purposes compared the the much more useful C++ struct. Why are you using JSON instead of something like a struct?

I didn't try myself, but just by looking at the docs I suggest you try:

Adding

#define ARDUINOJSON_USE_LONG_LONG 1

at the top of the sketch, before including ArduinoJson.h.

Declare CurrentUpdatedMS and CurrentUpdatedMS as either
unsigned long long or uint64_t.

Edit: To answer the question in the comment:

When you said you looked at the docs where did you check?

I had to follow a (not so simple) path: Deserialization tutorial →
JsonDocument::operator[] → JsonVariant →
JsonVariant::as<T>(). This last page states that the method
as<unsigned long long>() “may require ARDUINOJSON_USE_LONG_LONG”.
Unfortunately, the macro is not linked, so I have to search for it and
found ARDUINOJSON_USE_LONG_LONG.

Thanks I have it working now and will process it like that. When you said you looked at the docs where did you check? Just so I can know where to look in future.

Hi.
That’s worked well as I could assign the value though it is a UNIX timestamp and not appearing correctly when I print or display on a OLED. Tried a couple of things to remedy this including casting to long, u_int 64 etc but it still returns the incorrect time. My data has dateupdated in MS as 13 digits when I should be able to process 10. Would appreciate any thoughts I’ve tried various options. Is there a way to convert that object in the JSON to a string?


text:
Start / Stop Motor Run with Button State Change
I'm trying to understand Arduino with push buttons. But I can't get the test project I'm working on to work as how I want it to do.
Basically what I'm trying to do with the codes below is to make the push button either start or stop the servo motor. But so far, I couldn't get it to work. I'm also wondering why the servo motor won't run on loop? I tried several approach, but I couldn't get it working.
What am I missing here? Thanks.
By the way, I'm a beginner.
#include <Servo.h> //Servo Library.

int servoPin = 3; //Servo to Pin 2.
int led = 4; // LED to Pin 4.
int buttonState = 0;
int lastButtonState = 0;

Servo ServoOne; //Servo object created.

void setup() {
  Serial.begin(9600);
  ServoOne.attach(servoPin);
  pinMode(led, OUTPUT);
  pinMode(2, INPUT);
}

void loop() {
  buttonState = digitalRead(2);
  if (buttonState != lastButtonState) {
    servoRun();
  }
  lastButtonState = buttonState;
}

void servoRun() {
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      Serial.println("Running.");
      ServoOne.write(0); //Servo resets to 0 degrees.
      digitalWrite(led, LOW); //LED turns on.
      delay (1000);
      ServoOne.write(90); //Servo turns to 90 degrees.
      digitalWrite(led, HIGH); //LED turns on.
      delay (1000);
      ServoOne.write(180); //Servo turns to 180 degrees.
      digitalWrite(led, LOW); //LED turns on.
      delay (1000);
      ServoOne.write(90); //Servo turns to 90 degrees.
      digitalWrite(led, HIGH); //LED turns on.
      delay (1000);
      ServoOne.write(0); //Servo resets to 0 degrees.
      digitalWrite(led, LOW); //LED turns on.
    } else {
      Serial.println("Off.");
      ServoOne.write(0);
      digitalWrite(led, LOW);
    }
  }
}

Edit:
I tried this new approach, but I can't get the button state change saved.
#include <Servo.h> //Servo Library.

//Constant.
const int pswitch = 2; //Switch to Pin 2.

//Variables.
int servoPin = 3; //Servo to Pin 3.
int led = 4; //LED to Pin 4.
int newState; //Current switch state.
int oldState = LOW; //Previous switch state.

Servo ServoOne; //Servo object created.

void setup() {
  Serial.begin(9600);
  ServoOne.attach(servoPin);
  pinMode(led, OUTPUT);
  pinMode(pswitch, INPUT_PULLUP);
}

void loop() {
  newState = digitalRead(pswitch);

  if (oldState == LOW && newState == HIGH) {
    Serial.println("ON and running.");
    ServoOne.write(90);
    digitalWrite(led, HIGH);
    delay(1000);
    ServoOne.write(0);
    digitalWrite(led, LOW);
    delay(1000);
    ServoOne.write(90);
    digitalWrite(led, HIGH);
    delay(1000);
    ServoOne.write(180);
    digitalWrite(led, LOW);
    delay(1000);
    ServoOne.write(90);
    digitalWrite(led, HIGH);
    delay(1000);
  } else {
    Serial.println("OFF.");
    delay(1000);
  }
  oldState = newState;
}

write a simple sketch that turn the motor on ... does the motor run?

what is the purpose of the first if statement in servoRun()?

So what I want it to do is to keep the servo running  from 0, 90, 180, 90 and back to 0 on loop. The first if checks the state of the button. If it's pressed, it should supposed to 0 degrees and turn the LED off.

Basically I wanted to create a toggle switch button using one button. Is it possible? To toggle the servo to turn on and turn off? If it's toggled on, it will continue doing the 0, 90, 180, 90, 0 on loop, and if it's toggled off, it will stop. And if it's toggled on again, it will continue doing its job from where it stopped?

So, you want one button press to start the motor and keep it turning until the next button press? As far as I can see, one button press will now start the motor, will do a full revolution and then stop. Pressing the button again will start the motor again due to the button bouncing (or it may do nothing if the button is debounced externally). Correct?

@StarCat -- Yes that's correct. Actually I want the motor to perform a different job (in this sample, I just want it to stop rotating for the sake of simplicity) when the button is pressed. But I can't get the button state change saved.

@StarCat, I edited the post to show you my current codes. I can't get the state change saved to "newState". How do I do that? Is it even possible?
Like for a simple example, on press, it will serial print "ON", and when pressed again it will print "OFF".

What do you mean you can't get the old state saved?  That's what the last line of loop does.  Or do you mean that there is some behavior that makes you think that's what's happening?

The way you have it written right now, it will detect a button is pressed, that satisfies the if statement.  Then it will follow the lines in that if block one after the other.  So first it prints, lights the led, moves to 90 degrees, sticks it's head in the sand for one second then goes to 0 degrees turn off the led stick head in sand for another full second, and on and on.  Finally when it gets to the end of all of that the loop repeats and it finally gets to check the button again.  So there's no way the button can stop it mid way because the button can't be checked in there.

@Delta_G -- Sorry for the confusion. Basically what I want the button to do is to make it perform another job. But I think my code is wrong, because it doesn't transfer the state change from newState to oldState so it can compare. So to explain it simpler, how can I make it (let's say) print ON on the first press of a button, and then print OFF on the second press? Like a toggle on and off switch?

@Delta_G or rather with a press of a button, it will rotate the servo to 180 or 0. Like on first press, it will rotate to 180 and hold its angle until pressed again -- which will rotate it back to 0 degrees.

Yeah.  I understood what you wanted.  I was explaining why it works now the way it does.   You’re wrong in thinking that you’re not assigning the value of the old state.  That’s what the last line in loop does.   That’s happening.  Get it out of your mind that this is the problem. It’s not.  The problem is that once the button is pressed your code does the entire movement before it checks the button again.  You have blocking code.  You need a non-blocking state machine.  Google that.

@Delta_G took me a while to figure out what's causing the problem. Turns out it was the delay. I didn't know it stops everything. Finally got it working using millis and adding another variable to check the value of the button. Button works instantaneously as I want it to be. Thanks!

Execution always runs one line at a time.  No line of code can ever run until the line before it gets executed.  Well that’s not entirely true but for our purposes it’s close enough.  It’s not just delay.  Any command that takes a long time to run is an issue.


text:
How long does my digital pulse need to be for it to be read?
I have the following really simple code. On every iteration it'll read the first pin, and if it's high - do some serial IO. Then do the same with the second pin. Nice and simple, works during my tests.
My concern is that (in production), the digital pulse I'm receiving (and trying to mimic during testing) would be too quick for the arduino to read. So, for example, the race condition could be:

First pin is low Read first pin - result is low.
First pin is now high Read second pin - result is low.
Fist pin now low again Read first pin - result is low again (missed the 'high')

How much of an 'edge case' is this? Am I worrying about something that's likely to be a non-issue here? In production, each single pulse would represent a significant amount of product (I multiply it elsewhere) - so even skipping one could throw my data off.
boolean count1High = false;
boolean count2High = false;
int count1 = 7;
int count2 = 8;
int a = 1;
void setup() {
  pinMode(count1, INPUT);
  pinMode(count2, INPUT);
  Serial.begin(9600);
}

void loop()
{
  if (digitalRead(count1) == HIGH)
  {
    if (!count1High)
    {
      count1High = true;
      a++;
      Serial.println(a);
    }
  }
  else
  {
    count1High = false;
  }

  if (digitalRead(count2) == HIGH)
  {
    if (!count2High)
    {
      count2High = true;
      a++;
      Serial.println(a);
    }
  }
  else
  {
    count2High = false;
  }
}

EDIT:
I know best approach here might be to attach an interrupt but I've been advised to avoid serial IO from within interrupts, I don't see an alternative here.

This is exactly the reason interrupts were invented. They can respond a lot faster than a simple digital read. By "a lot" I mean orders of magnitude.
When an interrupt is triggered your interrupt handler for that interrupt executes. If another interrupt occurs whilst your interrupt handler is running the interrupt controller remembers it and the interrupt handler for that interrupt will execute as soon as the previous one is finished.
So you won't miss that pulse while the other pulse is processing.
However note that you shouldn't use Serial in interrupts, since Serial itself uses an interrupt internally to control the transmission, so transmission can't happen properly if your interrupt is already running. So instead your interrupt routine should just set a flag which you then check for in your main loop. You then benefit from the ability to notice a pulse while processing another pulse and still be able to use Serial. In fact, if you arrange it right, you can recognise and remember a pulse on the same input as the one you're currently processing.

As explained by Majenko's answer, you should detect the pulses from an
interrupt and print the result from the regular code. However, instead
of just setting a flag in the interrupt handler, I suggest you instead
count the pulses within the handler. This will make the handler a tiny
bit slower, which is often something you want to avoid. However, the
extra overhead is really tiny, and you gain the ability to count
not only pulses that are short but also pulses that are closely spaced.
There is, however, something to be aware of when sharing a variable
between interrupt code and regular code. If the variable cannot be read
in a single CPU instruction (which is the case of an int on an
AVR-based board), there is some risk that the value gets changed in the
middle of you reading it. To void this problem, you have to disable
interrupts when reading the variable from regular code.
Here is an implementation of this strategy highlighting this point:
const uint8_t intPin1 = 2;
const uint8_t intPin2 = 3;

// This is volatile because it is shared between interrupt context
// and regular code.
volatile unsigned int sharedCount = 0;

// Interrupt handler.
void countPulse() { sharedCount++; }

// A variable shared with interrupt context should be accessed from
// regular code with interrupts disabled, in order to avoid race
// conditions.
unsigned int getCount() {
    noInterrupts();
    unsigned int countCopy = sharedCount;
    interrupts();
    return countCopy;
}

void setup() {
    pinMode(intPin1, INPUT);
    pinMode(intPin2, INPUT);
    attachInterrupt(digitalPinToInterrupt(intPin1), countPulse, RISING);
    attachInterrupt(digitalPinToInterrupt(intPin2), countPulse, RISING);
    Serial.begin(9600);
}

void loop() {
    static unsigned int previousCount = 0;
    unsigned int count = getCount();
    if (count != previousCount) {
        Serial.println(count);
        previousCount = count;
    }
}

Note that if the pulses come very fast, you may miss printing the
value, but you will not miss counting it (up to some limit, of
course). Thus you may see non-consecutive numbers being printed.

It depends where the signal comes from and on other code in your sketch.
Typically, a sketch is rather way too fast for a mechanical switch, and you have to debounce it.
If your fear to lose events is realistic, interrupts are the way to go. But an ISR is some very special code: You won't do more than collect the information that there was an event. And you have to assert your main sketch won't interfere with the ISR.


text:
NodeMCU V3 and MPU6050 strange values
I am new to this platform, so please if I do something against the regular rules please let me know so I can learn.
Now my problem: I have a nodeMCU V3 connected to a MPU6050. Using my Arduino Uno I do get sensible values in the order of 0 degrees when the device is flat. Using the same code and the same setup I get very strange values in the order of 45 degrees when the device is flat. I have tried the following:

Using the I2C scanner I do get a valid address.
Testing with the Arduino Uno the values are correct.
The GY 521 breakout uses 3V3 datalines with 2k2 pull ups. Datalines are short. Eg on the same breadboard.
The GY 521 has a voltage regulator on board for 5V, so I feed the device with 5V in order to overcome a voltage drop problem.
I have tried to stretch the stretchClock function but no luck.

I have read about people with a similar kind of issue, but I could not find a solution. Anyone that can help me?
Apoligies. It would be more handy to attach my code:
''
/*
 * I2C example sketch for ESP8266
 */
#include <Wire.h>

const int DevID = 0x68;
const int PWR_MGT1_REG = 0x6B;

const int DataReg_AX = 0x3B;
const int DataReg_AY = 0x3D;
const int DataReg_AZ = 0x3F;
const int AccConfigReg = 0x1C;
const int GyrConfigReg = 0x1B;
const int SelfTestReg = 0x0D;

const int TempReg = 0x41;

const int DataReg_GX = 0x43;
const int DataReg_GY = 0x45;
const int DataReg_GZ = 0x47;

const int CalibrationConfigAcc = 0xF0;//set this value for calibration
const int CalibrationConfigGyr = 0xE0;//set this value for calibration
const int NormalConfigAcc = 0x00;//set this value for calibration 2G
const int NormalConfigGyr = 0x00;//set this value for calibration 250dps

/*
  int16_t Acc_X;
  int16_t Acc_Y;
  int16_t Acc_Z;
*/
float Acc_X, accAngleX, accAngleY, Yaw_Angle;
float Acc_Y;
float Acc_Z;

//double Acc_X, accAngleX, accAngleY, Yaw_Angle;
//double Acc_Y;
//double Acc_Z;

int8_t X_selfTest;
int8_t Y_selfTest;
int8_t Z_selfTest;
int8_t Acc_X_Y_Z_selfTest;

int16_t Temp;
/*
  int16_t Gyro_X;
  int16_t Gyro_Y;
  int16_t Gyro_Z;
*/
float Gyro_X;
float Gyro_Y;
float Gyro_Z;

int16_t Gyro_X_selfTest;
int16_t Gyro_Y_selfTest;
int16_t Gyro_Z_selfTest;

//int SDApin = 3;//create I2C pinouts for ESP8266;
//int SCLpin = 4;

unsigned long elapsedTime, previousTime, currentTime;

void setup() {// put your setup code here, to run once:
  Serial.begin(115200);
  Wire.begin ();
 // Wire.setClock(400000);
//  Wire.setClockStretchLimit(40000);
  Wire.beginTransmission(DevID);
  Wire.write(PWR_MGT1_REG);
  Wire.write(0x0);// wake up the sensor
  Wire.endTransmission();
  CalibrationProcedure();// enter calibration procedure
}

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

previousTime = currentTime;
currentTime = millis();
 elapsedTime = (currentTime - previousTime) / 1000;

  Wire.beginTransmission(DevID);
  Wire.write(DataReg_AX);
  Wire.endTransmission();

  Wire.requestFrom(DevID, 14);
  if (Wire.available() == 14) {
    Acc_X = ((Wire.read() << 8) | (Wire.read())) / 16384.0;// divide by 16384 for 2G setting according to datasheet
    Acc_Y = ((Wire.read() << 8) | (Wire.read())) / 16384.0;
    Acc_Z = ((Wire.read() << 8) | (Wire.read())) / 16384.0;
    Temp = (Wire.read() << 8) | (Wire.read());
    Gyro_X = ((Wire.read() << 8) | (Wire.read()))  / 131.0; // divide by 131.0 according to datasheet for setting 250 dps
    Gyro_Y = ((Wire.read() << 8) | (Wire.read())) / 131.0;
    Gyro_Z = ((Wire.read() << 8) | (Wire.read())) / 131.0;
    delay(500);
  }

  //The formulas below have been extracted from another program and uses mathematical
  //values for calulation of pitch roll and yaw. For the moment only pitch is calibrated
  //The next purpose of this program is follow a calibration procedure to take approx 200 samples
  //and average the total value to correct the pitch roll and yaw value
  accAngleX = (atan(Acc_Y / sqrt(pow(Acc_X, 2) + pow(Acc_Z, 2))) * 180 / PI);
  accAngleY = (atan(-1 * Acc_X / sqrt(pow(Acc_Y, 2) + pow(Acc_Z, 2))) * 180 / PI);
  Yaw_Angle = Yaw_Angle + Gyro_Z * elapsedTime;

  float Gyro_X_axis = (float)Gyro_X / 131.0;
  float Gyro_Y_axis = (float)Gyro_Y / 131.0;
  float Gyro_Z_axis = (float)Gyro_Z / 131.0;
  float Temperature = (Temp / (340.0)) + 36.53;
  //Serial.print(" Accelero X \t" );
  //Serial.print(Acc_X);
  //Serial.print(" Accelero Y \t" );
  //Serial.print(Acc_Y);
  //Serial.print(" Accelero Z \t");
  //Serial.print(Acc_Z);
  //Serial.println("");
  //Serial.print(" Gyro X \t" );
  //Serial.print(Gyro_X);
  //Serial.print(" Gyro Y \t" );
  //Serial.print(Gyro_Y);
  //Serial.print(" Gyro Z \t");
  //Serial.print(Gyro_Z);
  //Serial.print(" Temperature \t");
  //Serial.println(Temperature);
  //Serial.println(Temp);
  Serial.println ("Angle X");
  Serial.println(accAngleX);
  Serial.println ("Angle Y");
  Serial.println (accAngleY);
  Serial.println("Yaw Angle");
  Serial.println(Yaw_Angle);
  delay(500);
}

void CalibrationProcedure() {
  Serial.println("Keep sensor steady until calibration process is complete!");
  Wire.beginTransmission(DevID);
  Wire.write(AccConfigReg);//8 g
  Wire.write(CalibrationConfigAcc);
  Wire.endTransmission();
  delay(250);
  Wire.beginTransmission(DevID);
  Wire.write(GyrConfigReg);
  Wire.write(CalibrationConfigGyr);//250 deg/s
  Wire.endTransmission();
  delay(500);
  Serial.println("Selftest enabled, reading data...");

  Wire.beginTransmission(DevID);
  Wire.write(SelfTestReg);
  Wire.endTransmission();

  Wire.requestFrom(DevID, 4);
  if (Wire.available() <= 4) {
    X_selfTest = Wire.read();
    Y_selfTest = Wire.read();
    Z_selfTest =  Wire.read();
    Acc_X_Y_Z_selfTest = Wire.read();
    delay(500);
  }

  //extracting factory trim values after self test
  //unsigned integers for accelero variables
  uint8_t XA_selfTest;
  uint8_t YA_selfTest;
  uint8_t ZA_selfTest;
  //unsigned integers for gyro variables
  uint8_t GX_selfTest;
  uint8_t GY_selfTest;
  uint8_t GZ_selfTest;
  //Factory Trim variables
  float FTGX;
  float FTGY;
  float FTGZ;
  float FTAX;
  float FTAY;
  float FTAZ;

  float SelfTestPercentage_GX;
  float SelfTestPercentage_GY;
  float SelfTestPercentage_GZ;
  float SelfTestPercentage_AX;
  float SelfTestPercentage_AY;
  float SelfTestPercentage_AZ;

  GX_selfTest = X_selfTest & 0x1F; // 0x1F is a bit mask to extract the first 5 bits. unsigned format
  GY_selfTest = Y_selfTest & 0x1F;
  GZ_selfTest = Z_selfTest & 0x1F;
  XA_selfTest = (X_selfTest >> 3) | (Acc_X_Y_Z_selfTest & 0x30) >> 4; //shift the first 3 bits and extract bits with a mask depending on the LSB postion in the last received mixed byte
  YA_selfTest = (Y_selfTest >> 3) | (Acc_X_Y_Z_selfTest & 0x0C) >> 2;
  ZA_selfTest = (Z_selfTest >> 3) | (Acc_X_Y_Z_selfTest & 0x03);

  Serial.println ("XA_selfTest");
  Serial.println (X_selfTest, HEX);
  Serial.println("YA_selfTest");
  Serial.println(Y_selfTest, HEX);
  Serial.println("ZA_selfTest");
  Serial.println(Z_selfTest, HEX);
  Serial.println("Acc_X_Y_Z_selfTest");
  Serial.println(Acc_X_Y_Z_selfTest, HEX);

  //calculate the factory trim settings
  FTGX = (25.0 * 131.0) * (pow(1.046, ((float)GX_selfTest - 1.0)));// Factortrim Gyro X
  FTGY = (-25.0 * 131.0) * (pow(1.046, ((float)GY_selfTest - 1.0)));// Factortrim Gyro Y
  FTGZ = (25.0 * 131.0) * (pow(1.046, ((float)GZ_selfTest - 1.0)));// Factortrim Gyro Z
  FTAX = (4096.0 * 0.34) * (pow((0.92 / 0.34), (((float)XA_selfTest - 1.0) / 30.0)));
  FTAY = (4096.0 * 0.34) * (pow((0.92 / 0.34), (((float)YA_selfTest - 1.0) / 30.0)));
  FTAZ = (4096.0 * 0.34) * (pow((0.92 / 0.34), (((float)ZA_selfTest - 1.0) / 30.0)));
  Serial.println("Selftest ended...please copy data");
  Serial.println(" GX trim value\t" );
  Serial.println(FTGX);
  Serial.println(" GY trim value\t" );
  Serial.println(FTGY);
  Serial.println(" GZ trim value\t");
  Serial.println(FTGZ);
  Serial.println(" AX trim value\t" );
  Serial.println(FTAX);
  Serial.println(" AY trim value\t" );
  Serial.println(FTAY);
  Serial.println(" AZ trim value\t");
  Serial.println(FTAZ);
  SelfTestPercentage_GX = 100.0 + 100.0 * ((float)GX_selfTest - FTGX) / FTGX;
  Serial.println("SelfTestPercentage");
  Serial.println(SelfTestPercentage_GX);
  SelfTestPercentage_GY = 100.0 + 100.0 * ((float)GY_selfTest - FTGY) / FTGY;
  Serial.println("SelfTestPercentage");
  Serial.println(SelfTestPercentage_GY);
  SelfTestPercentage_GZ = 100.0 + 100.0 * ((float)GZ_selfTest - FTGZ) / FTGZ;
  Serial.println("SelfTestPercentage");
  Serial.println(SelfTestPercentage_GZ);
  SelfTestPercentage_AX = 100.0 + 100.0 * ((float)XA_selfTest - FTAX) / FTAX;
  Serial.println("SelfTestPercentage Acclero x, y, z");
  Serial.println(SelfTestPercentage_AX);
  SelfTestPercentage_AY = 100.0 + 100.0 * ((float)YA_selfTest - FTAY) / FTAY;
  Serial.println("SelfTestPercentage Acclero x, y, z");
  Serial.println(SelfTestPercentage_AY);
  SelfTestPercentage_AZ = 100.0 + 100.0 * ((float)ZA_selfTest - FTAZ) / FTAZ;
  Serial.println("SelfTestPercentage Acclero x, y, z");
  Serial.println(SelfTestPercentage_AZ);

  // get data outputs with self test enabled
  Wire.beginTransmission(DevID);
  Wire.write(DataReg_AX);
  Wire.endTransmission();

  Wire.requestFrom(DevID, 14);
  if (Wire.available() <= 14) {
    Acc_X = (Wire.read() << 8) | (Wire.read());
    Acc_Y = (Wire.read() << 8) | (Wire.read());
    Acc_Z = (Wire.read() << 8) | (Wire.read());
    Temp = (Wire.read() << 8) | (Wire.read());
    Gyro_X = (Wire.read() << 8) | (Wire.read());
    Gyro_Y = (Wire.read() << 8) | (Wire.read());
    Gyro_Z = (Wire.read() << 8) | (Wire.read());
    delay(500);
  }
  //print values with self test enabled
  Serial.println("Self test enabled values");
  Serial.println(" Accelero X " );
  Serial.println(Acc_X);
  Serial.println(" Accelero Y " );
  Serial.println(Acc_Y);
  Serial.println(" Accelero Z ");
  Serial.println(Acc_Z);
  Serial.println(" Gyro X " );
  Serial.println(Gyro_X);
  Serial.println(" Gyro Y " );
  Serial.println(Gyro_Y);
  Serial.println(" Gyro Z ");
  Serial.println(Gyro_Z);
  delay(500);

  //setup the device for normal OPS
  Wire.beginTransmission(DevID);
  Wire.write(AccConfigReg);
  Wire.write(NormalConfigAcc);
  Wire.endTransmission();
  delay(50);
  Wire.beginTransmission(DevID);
  Wire.write(GyrConfigReg);
  Wire.write(NormalConfigGyr);
  Wire.endTransmission();
  delay(50);

  //request data with self test not enabled
  Wire.beginTransmission(DevID);
  Wire.write(DataReg_AX);
  Wire.endTransmission();

  Wire.requestFrom(DevID, 14);
  if (Wire.available() <= 14) {
    Acc_X = (Wire.read() << 8) | (Wire.read());
    Acc_Y = (Wire.read() << 8) | (Wire.read());
    Acc_Z = (Wire.read() << 8) | (Wire.read());
    Temp = (Wire.read() << 8) | (Wire.read());
    Gyro_X = (Wire.read() << 8) | (Wire.read());
    Gyro_Y = (Wire.read() << 8) | (Wire.read());
    Gyro_Z = (Wire.read() << 8) | (Wire.read());
    delay(500);
    //print values with self test not enabled
    Serial.println("Self test not enabled values");
    Serial.println(" Accelero X " );
    Serial.println(Acc_X);
    Serial.println(" Accelero Y " );
    Serial.println(Acc_Y);
    Serial.println(" Accelero Z ");
    Serial.println(Acc_Z);
    Serial.println(" Gyro X " );
    Serial.println(Gyro_X);
    Serial.println(" Gyro Y " );
    Serial.println(Gyro_Y);
    Serial.println(" Gyro Z ");
    Serial.println(Gyro_Z);
    delay(5000);
  }
}
'''

You said you get good values then you said you get bad values.  What changes in between?   Do you think posting the code and the wiring would be smart?  Or do you think it’s smarter to have us guess at what you did?

Sorry! I attached my code. The only change I basically did was converting the same code from the Uno to a NodeMCU using the standard I2C pins. When the device is flat the Uno reads 0 degrees which is correct. But with the NodeMCU I get values of 45 degrees jumping up and down.

Aha, so there's a NodeMCU involved?  Why didn't you mention that in the question?  You didn't think that might be important?

I wrote that down in my question right? In case it was not clear, sorry.

I was talking about the "using the same code and same setup" which would imply the same board.  That confused me.

Ah ok, sorry for the confusion. I hope my problem is a bit clear. I am using the same code for the uno and NodeMCU. which compiles fine and I do get reading from both of the boards. The node MCU gives me incorrect values however. I have tried multiple I2C sensors and they appear to have the same issue. Can someone explain what I am missing?

Does I2C work the same on a NodeMCU as it does on Arduino?  Does it take the same code?

Yes from a hardware point of view for sure. I got the NodeMCU last week and I program it using the Arduino IDE. Including the same libraries etc. Is that what you mean?

Yeah, I've never done I2C on a NodeMCU but I've done a lot of other things and it seems pretty typical to have to use a different library or to have to do at least some things differently on the different platform for most of it.  So I wondered if you had checked out anything on I2C for NodeMCU to see if maybe there were any special considerations or if you just moved the code over.

True. It looks like an implementation "thingy" with the wire.h library. But I cannot figure out why or what.

I think I found the solution. Division /16384 somehow does not work on that platform. If I perform the formula with the raw values it works...Scaling of values according to register values seem to be the next challenge...

Division works.  You probably have a variable type issue.  What line?

Oh I see the line.  Could also be a sequence issue.  You don’t have any control over the order of the two calls to wire.read().  You should do those two reads on two lines.

It was a sequence issue I guess. Strange that I was not able to notice it on the UNO though!

The compiler gets its choice there.  If you want things to go in a certain order then make sure there is a sequence point between.   I can never remember what all constitutes that so I just go for separating to two lines of code and I know that will work.

I had the same issue sometime back.I was able to get good results using the example given for the ESP8266 in the MPU6050 library itself.You can make the necessary changes starting from that sketch.Hope this helps.
Heres the github link to the library https://github.com/ElectronicCats/mpu6050

Thank you! My purpose was to write with the Wire.h library. But for reference purposes I will try to use it. I let you know about the result!

It seems to work if I use the very standard output file and implementation of my formulas. But I am really wondering why? Do they use a different I2C library? What am I missing?

see my answer above....Don't know if you had the same issue?

Yeah I had the same issue.What happens when you try to get the readings out of the accelerometer and gyroscope like you have done is that all your reading aren't filtered.So things like gyro drift come into play and have a significant effect on the output.But the library is made so that those raw values you obtain go through a FIFO buffer and also the Digital Motion Processor on your MPU6050. These two will effectively fuse the sensor data and minimize the errors.I found that the best way to get readings is using the library but it has some drawbacks as well.

Well in my case the division after reading data and bitshifting was not working. If you comment it out feel free to try. I am not using any FIFO registers etc. I was just playing around with I2C. Thanks for your input!


text:
Using RST pin as external power switch
I have Arduino Nano with powered over USB. I have the request for external (physical) slide switch acting as power on/off for Arduino even if USB is always connected.
Looking at documentation and various posts, it seems the RST button could do just that. So when the "power" switch is on, RST is disconnected (= pulled high) and everything runs like normal. When the "power" switch is switched, it will pull RST low. As long as RST is pulled low, the board is stopped (the PWR led is lit, which is true and okay). Once released, the board will boot again.
Even though I agree this is not terribly elegant, is it going to work? I tried manually with the reset switch. Any side-effects I am overlooking?

That is a perfectly legitimate use of the RESET pin. Holding the chip in reset perfectly valid. Everything in the chip will be stopped.
Releasing it will start your sketch from the start again perfectly fine.
The only negative point is that your switch will be pulling power through the reset pin's pullup resistor, so will waste a little power.

Thanks! The power is fine, I guess.


text:
Scrolling an I2C text
I want tried to make a programm to display a text on an I2C LCD-Display.
The text should be scrolled for one position every time the function is called.
On the internet I saw a lot of solutions but there were all diffrent from what I need.
So I tried to make my own code.
The code works well except of the part where I try to scroll in the Text from the left.
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);

char Str[12] = {'T', 'r', 'u', 'e', 't', 'z', 's', 'c', 'h', 'l', 'e', 'r'};
int pos = 0;
int posretry = 0;
bool ledon = false;

void setup()
{
  pinMode(13, OUTPUT);

  lcd.init();
  lcd.backlight(); //lcd.noBacklight();
}

void scroll()
{
  for (int i = 0; i < 12; i++)
  {
    //Print text
    lcd.setCursor(i + pos, 0);
    lcd.print(Str[i]);

    //Move in text from the left

    if (pos >= 6)
    {
      lcd.setCursor(i + pos, 0);
      lcd.print(Str[i]);

      lcd.setCursor(posretry, 0);
      lcd.print(Str[11 - posretry]);

      posretry++;
    }
  }
  delay(500);
  lcd.clear();

  pos++;
}

void changeled()
{
  if (ledon == false)
  {
    digitalWrite(13, LOW);
  }
  else
  {
    digitalWrite(13, HIGH);
  }

  ledon = !ledon;
}

void loop()
{
  scroll();
  changeled();  //Example Event
}

The goal is to move the text to the right and show the not displayed letters on the left.
Example:
|er    Truetzschl|  -->
|                |

A Video about the error can be found here:
https://data.jonas-heinze.de/shares/stackexchange/lcd/
Thanks for your help.

What doesn’t work about it?  You didn’t give us a symptom.  You did describe your expected behavior so good job on that.  Now you need to say what actually happens and how that’s different from your expectations.

Oh im so sorry I forget to describe the problem. I added a video of the problem to my post.

OK, I would have helped if you could have described it, but I can't see the video on this device.  Good luck.

A diffrent Text seems to randomly shown up. Sometimes in the first other times in the second row. The often are strange characters. Its hard to explain. Cause of that I added the Video.

Hmm, should be an easy task where you just need to increment a string index and handle its overflow. What do you achieve by checking if(pos>=6)? Do you really need posretry (for what)? A serious problem is that you never reset pos and posretry, so they will exceed the allowed range and even become negative when the int overflows itself. Definitely not right

Not so easy to nail it down just by seeing the video and without having your hardware to actually test it, but I'm sure you are doing it way more complicated than neccessary.

I understand its difficult to nail it down. What would the way you do it?

The word should come in from the left if (pos >= 6): Cause if the first letter is around that position the last letter is cut of by the display limitation. So its like:
if (pos >=6){start coming in from left}.
The posretry was just a workaround to print the last letter(s) in the first position(s).
Do you understand what I mean?

You do some strange things that I, at least, don't understand (e.g. I don't see what you need posretry for), but you might have a reason for doing so.
But you don't reset posretry and pos, which means they will very soon be out of a reasonable range. At some point the int will actually overflow to negative values, which is definitely not going to work!
To make it less complicate, you should write a function that prints the char array shifted by a desired value as a beginning.
The below code is completely untested as I don't have your hardware and I'm aware that it does not include all your desired features. But it should give you an idea of how scrolling can be implemented in principle and it's up to you to improve/fix it.
#define LCD_SIZE 16
#define STR_LEN 12
char str_to_print[STR_LEN]={'T', 'r', 'u', 'e', 't', 'z', 's', 'c', 'h', 'l', 'e', 'r'};

void print_scrolled (uint8_t scrolled_by) {
  for (uint8_t i=0;i<LCD_SIZE;i++) {
    lcd.set_cursor(i,0);
    if (scrolled_by>=LCD_SIZE) scrolled_by=0;

    if (scrolled_by<STR_SIZE) lcd.print(str_to_print[scrolled_by]);
    else lcd.print(' ');
    scrolled_by++;
  }
}

You could call it like this:
for (uint8_t i=0;i<STR_LEN;i++) {
  print_scrolled(i);
  delay(500);
}

Once you are familiar with my approach you should be able to enhance it with additional features (end of text coming in from the other side, spaces between end and beginning, etc).

Thank you very much. I will do some testing tomorrow. Have a nice day


text:
Data transmission rate of accelerometer mpu6050 to arduino uno vs Sampling rate of mpu6050
mpu6050 has sampling frequency of 1kHz (mentioned in datasheet). But when i interface it with arduino uno via I2C communication (400Khz bus speed), i only get 50 raw data (each of x,y,z). There is no delay in the program. why is this happening. Why am I not getting 1000 or at least 800 samples. What is the concept I am missing here. Please explain in detail. I have also attached the code and output for 1 second.
#include "I2Cdev.h"
#include "MPU6050.h"
#include "Wire.h"
//#include <SoftwareSerial.h>
//SoftwareSerial BTserial(10,11);
MPU6050 accelgyro;
char ch;
int incomingbyte = 0;
int16_t ax, ay, az;
int16_t gx, gy, gz;

void setup() {

  Wire.begin();
  Serial.begin(115200);

  accelgyro.initialize();
  accelgyro.setXAccelOffset(542);
  accelgyro.setYAccelOffset(-835);
  accelgyro.setZAccelOffset(1651);
  accelgyro.setXGyroOffset(6);
  accelgyro.setYGyroOffset(-18);
  accelgyro.setZGyroOffset(23);
}
void loop()
{
  accelgyro.getAcceleration(&ax, &ay, &az);
  accelgyro.getRotation(&gx, &gy, &gz);

  Serial.print(ax); Serial.print("\t");
  Serial.print(ay); Serial.print("\t");
  Serial.println(az);
}

the datasheet indicates that the sample rate is programmable ... looks like register 25 is involved ... this document describes the register functions ... https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Register-Map1.pdf

HI @jsotola , thanks for the reply. I found out sampling rate divider that is at reg 0x25 , 255 was set. So the sampling rate should be either 31.25Hz DLPF is disabled or 3.9 hz  when DLPF enabled according to the datasheet (pg no 12 in the link you have provided). Still i am getting more than these values around 50 samples. How come? Also sampling rate is different from data transmission rate from mpu6050 to arduino uno right? Can you explain in detail like how many bytes would transmitted through i2c and all those calculation stuffs.  I am not getting that

Set the I2C to 400kHz using Wire.setClock(), I think by default it's set to 100kHz. That would bump up the sampling rate from 50 Hz to 200 Hz. If that's not enough I think you have to disable the digital low pass filter.

Your problem is the Serial.print which slows down the loop. Add a counter in your loop and do a serial.print just once in a while.

i want to know what is the unit of this signal? for example what is the 5608 ?? in first row

The reason is that Serial.print() is mush slower compared to reading a sample from the sensor.
If you comment the print(), then read sensor data for a certain time repeatedly and calculate the output data rate accordingly, you will find that the sampling rate is indeed 1000 Hz.
If what you wanted is merely to store the data and use it afterwards (instead of real-time processing), you can store the sensor readings in a SD card, which is always much faster than serial printing. A useful trick is that do not write data to the sd card whenever you get a new sample, but use a software buffer (i.e., array) to store the samples (the buffer size depends on the RAM of microcontroller) and then write the whole buffer to the sd card when it's full.
However, as long as you want to store the data (either print in serial or write in a file), you'll always have to 'sacrifice' some data rate and cannot get 1kHz as mentioned in datasheet.
Hope this helps.


text:
Confused as to how 2 of my interrupts are firing from just 1 pin input?
I have the following code which uses interrupts to set a flag for whether serial IO should happen to update my PC about a particular pin input. So I have interrupts on pins 2 and 3.
I am using the arduino's pin 13 as an output, and every 2 seconds send a pulse. On my arduino, I have 1 wire running from 13 to pin 3. Note: I have nothing at all inserted into pin 2.
Somehow, I get the following input every 2 seconds:
Pin 2
Pin 3
How is my interrupt for pin 2 firing??
boolean serialCommsQueue1 = false;
boolean serialCommsQueue2 = false;

void setup()
{
  pinMode(2, INPUT);
  pinMode(3, INPUT);
  attachInterrupt(digitalPinToInterrupt(2), pin2Fired, RISING);
  attachInterrupt(digitalPinToInterrupt(3), pin3Fired, RISING);
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop()
{
  digitalWrite(13, HIGH); // sets the digital pin 13 on
  delay(1000);            // waits for a second
  digitalWrite(13, LOW);  // sets the digital pin 13 off
  delay(1000);            // waits for a second

  if (serialCommsQueue1)
  {
    serialCommsQueue1 = false;
    Serial.println("Pin 2");
  }

  if (serialCommsQueue2)
  {
    serialCommsQueue2 = false;
    Serial.println("Pin 3");
  }
}

void pin2Fired()
{
  serialCommsQueue1 = true;
}

void pin3Fired()
{
  serialCommsQueue2 = true;
}

EDIT:
If I take the wire out of 3, pin 2 constantly (every 2 seconds) writes to serial. If I put the wire back in pin 3 regularly writes every 2 seconds - which itself is a problem too, since it should only be detecting a 'change'?

You probably have floating inputs.

The interrupt on pin 2 triggers, because the pin is floating. Since nothing is connected to the pin, it reacts to whatever noise is flying by (for example from pin 3). That can lead to the pin changing its state together with pin 3, or to just erratically randomly changing state.
You need to connect a pullup or pulldown resistor (one rather big resistor going from the pin to either Vcc or ground), which sets the pins state, when it is not actively driven otherwise. If you need a pullup or pulldown depends on your wanted behavior.
If a pullup is ok for you, you can activate the Arduinos internal pullup resistor by using
pinMode(2, INPUT_PULLUP);

I don't think you realise how much hassle this has saved me! Thank you very much mate, I will award a bounty as soon as poss.

This is a common issue with CMOS digital inputs. If they are not connected through a resistor (10k is a good choice) to either +5V or ground, they give semi-random 1s and zeros.


text:
LUFA with pro micro 3.3v 8mhz not working
I am trying to flash my pro micro 3.3v from sparkfun with a Lufa project to make it act as a pokken controller, i am using this project Github Project I have modified the makefile for 8mhz and set the bootstart pid, this has worked succesfuly on an arduino uno r3, with the same project. When i make the project it works fine then I run make avrdude, and it flashes succesfully. the problem though is the pro micro does not show up as a pokken controller as it should. I then tryed it on my switch to no avail. Here is the make file I am using
#
#             LUFA Library
#     Copyright (C) Dean Camera, 2014.
#
#  dean [at] fourwalledcubicle [dot] com
#           www.lufa-lib.org
#
# --------------------------------------
#         LUFA Project Makefile.
# --------------------------------------

# Run "make help" for target help.
PID          = 0x9203
BOOT_START   = 0x9203
ARDUINO_MODEL_PID = 0x9203
MCU          = atmega32u4
ARCH         = AVR8
F_CPU        = 8000000
F_USB        = $(F_CPU)
OPTIMIZATION = s
TARGET       = Joystick
SRC          = $(TARGET).c Descriptors.c $(LUFA_SRC_USB) $(LUFA_SRC_SERIAL)
LUFA_PATH    = ./lufa/LUFA
CC_FLAGS     = -DUSE_LUFA_CONFIG_HEADER -IConfig/
LD_FLAGS     =
AVRDUDE_PROGRAMMER = avr109 # Add this
AVRDUDE_PORT = COM5 # And this too (use your correct COM port)
MCU_AVRDUDE = atmega32u4
MCU_DFU = atmega32u4

# Default target
all:

# Include LUFA build script makefiles
include $(LUFA_PATH)/Build/lufa_core.mk
include $(LUFA_PATH)/Build/lufa_sources.mk
include $(LUFA_PATH)/Build/lufa_build.mk
include $(LUFA_PATH)/Build/lufa_cppcheck.mk
include $(LUFA_PATH)/Build/lufa_doxygen.mk
include $(LUFA_PATH)/Build/lufa_dfu.mk
include $(LUFA_PATH)/Build/lufa_hid.mk
include $(LUFA_PATH)/Build/lufa_avrdude.mk
include $(LUFA_PATH)/Build/lufa_atprogram.mk

Any Help would be appreciated

go back to the beginning ... configure the arduino as a usb keyboard ... that will confirm that your hardware and software works


text:
MKR Zero not showing up in WIN10 device manager / Arduino IDE cannot detect port / COM
I'm new to Arduino and hope you guys can give some advise.
I bought MKR Zero a few days before and tried to connect to my Win10 laptop. I can see the LED on the board is on, but the Arduino IDE cannot detect it. the "Port" is grey out. I tried 2 laptops which also Win10 but same situation happen. I tried different USB cables I had.
I checked the device manager in the control panel, there is no "Unknown device" under the USB port but also no MKR showing up. I don't know what to do.
I'm not sure if it is Win10 problem...Please kindly advise, thank you very much!!

Try a different cable?

You can try out this reference for your problem How To Disable Driver Signature Enforcement in Windows 10 . Also check the connections.

i bought another 2 cables and same situation still happen

did you install the SAMD boards package? https://www.arduino.cc/en/Guide/ArduinoMKRZero

yes i did - now the IDE can let me select MKR Zero board, but the "Port.  >" is grey out. I still cannot select the port that is connecting to the board

thank you kaviranga - i tried to disable the enforcement but still cannot connect to my board

Have you tried runnng the ArduinoIDE as admnistrator?

thank you Codebreaker007 - just tried to run as administrator, but the Port still grey out

Are you sure that you are using usb data cables, if the device shows not up in device manager you probably use a "charging only" usb cable used for mobile phones or similar to load. Can you see the MKR Zero in device manager?

thank you Codebreaker007 - no I cannot see it in device manager even if i plug it in my laptop, so maybe i am really using "charging only" usb cable...I will go to some shops and buy data cable and try again, thank you for your advice!

Take your laptop and your Arduino with you The right cable will let the Arduino show up in device manager (most sellers do not even know there are different types of usb cables on the market. Report back your proceedings

hello - i went to the shop and bought the "sync and charge" cable and tried on 3 different Win10 laptops, still same situation happen - the LED light is on but nothing detected in the device manager.
I think I will just simply go back to the shop and return the Arduino board...

hello - I went back to the hardware shop and they verified that my MKRZero is really not working...they changed another one to me and it works now...thank you everyone for your kind suggestion! I will close this question now. Thanks!

Hardware itself problem. Went to the shop and changed the board to me and now works.