text:
In multidimensional arrays, can you use variable arrays or their names instead of the actual data?
Referring to this thread
How to declare and use "Variabled arrays" inside arrays
Example
byte array[2][4] = { {1,2,3,4}, {5,6,7,8} };
Serial.println(array[0][2]); is equal to '3'.

Instead of using {1, 2, 3, 4} and {5, 6, 7, 8} I want to be able to declare separate arrays for each of them and just put the name.
Another big issue is putting arrays of different sizes for each entry and it would be wrong to do so. Is this really not possible? Do I have to use some other concept instead if I want to have an array that contains entries of arrays that have different sizes? I heard about pointers but not familiar with that.
Example,
byte arrayX[3] = {1, 2, 3}
byte arrayY[4] = {5, 6, 7, 8}

byte array[2][4] = { arrayX , arrayY };

Take note that the code was not taken from the link I mentioned, I just used the same array names. Also I changed arrayX from the link to 3 entries because I want to emphasize the part of my question if it is possible if arrays have different sizes and you would just use the biggest size?
Now I think this is wrong and I haven't tested it currently but I want to ask if there is a solution that makes use of what I have mentioned? The site I linked to gave a solution which feels very redundant in terms of declaration and I would not want that. This is the solution mentioned there.
byte arrayZ[2][4] = {
  {arrayX[0],arrayX[1],arrayX[2],arrayX[3]},
  {arrayY[0],arrayY[1],arrayY[2],arrayY[3]}
};

The issue I had when searching the internet is the same as the link. "Surfed on the internet to find a bunch of examples but the only difference is that they don't use arrays that have been declared to have a name inside array."

Here is everything you ever wanted to know about the relationship between arrays and pointers (and yet more). Note that it is about C, and C++ has some extra features alluded by the busybee in his answer.

Two-dimensional arrays come in two "flavours". Actually, multi-dimensional arrays are possible in any combination of these.

All elements in a rectangular grid, at least from the abstract view of the programming language;
A one-dimensional array of one-dimensional arrays.

If you declare:
byte array[n][m];

then you have reserved space for "n times m" bytes. From the programmer's view it is a rectangular grid, actually all bytes are in sequence in a one-dimensional array. This is because the memory of our computers are commonly organized as a big one-dimensional array of bytes. The compiler generates the correct calculation for the offset into this array, multiplying one index with the size of the width (or length, depending on your mental model) and adding the other index.
You can initialize such an array with the nested set of curly braces like this:
byte array[n][m] = {
    { /* ... */ },
    /* ... */
};

But you cannot initialize it as you show.
Otherwise, if you declare
byte* array[n];

then you have reseved space for "n" pointers to bytes, that is a one-dimensional array of pointers. Each of these pointers can point to a different or the same one-dimensional array of bytes, or to no array at all if it's nullptr.
Now you can set up the array as you like:
byte arrayX[m1] = { /* ... */ };
byte arrayY[m2] = { /* ... */ };

byte* array[n] = { arrayX, arrayY, /* ... */ };

The arrays arrayX and arrayY (and any further) don't need to have the same length. Each can have its own length. But beware, you need to trace the length somehow to avoid out-of-bounds accesses. And of course, you need to check or be sure that a pointer is not null before dereferencing it.
In both cases you can access a single element with:
byte element = array[i][j];
array[k][l] = 23;

This is because the syntax with the brackets is equivalent to the dereferencing operator:
x[y] == *(x + y)

Note 1: Since Arduinos are programmed in C++, there is another option. You can use references instead of pointers. Because it is really hard to create a null reference, some see it as a safety measure against null pointers.
Note 2: Again, since Arduinos are programmed in C++, you can implement an own class that provides the operator[]. With this option you can do any magical stuff, but it might break the user's expectation. Be careful if you go that route.


text:
Serial plotter looks different and doesnt print graph
When I open my serial plotter to get the graph for my HC-SR04 sensor it doesn't show anything. My plotter looks different too. I have attached images below as well.

Only those numbers on the top-most move with time.(100,200,300)
Here's my code:
int trigPin = 12;
int echoPin = 11;

int pingTravelTime;
float pingTravelDistance;
float distToTarget;

int baudRate = 9600;

int dT = 10;
int dT2 = 500 ;

String msg1 = "The distance is equal to ";
String msg2 = "cm";

void setup() {
  // put your setup code here, to run once:
  Serial.begin(baudRate);

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(dT);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(dT);
  digitalWrite(trigPin, LOW);

  pingTravelTime = pulseIn(echoPin, HIGH);

  pingTravelDistance = pingTravelTime * ((765. * 5280. * 12.) / (3600. * 1000000));
  pingTravelDistance = 2.54 * pingTravelDistance;
  distToTarget = (pingTravelDistance / 2);

  Serial.println(msg1 + distToTarget + msg2);

  delay(dT2);
}

What do I do??

Does the serial monitor connect without issue with this code?

Yes, the serial monitor behaves properly and poses no problem for me. It's just the serial plotter that seems to have a problem.

The serial plotter expects you to send numbers, and only numbers. If it
reads any other text, like for example
“The distance is equal to 9.88cm”
It assumes these are the names of the columns of data that are to
follow. So it chooses one color for each column and prints the color key
on top of the graph.

What do I do??

Just remove the prose and print only the numbers. You may print
something like “distance(cm)” in setup() if you want to have the key
displayed, but that is not required.

Ok thanks a lot, I will try that.

Yes, it works now, thanks.

@unibeam Then mark this answer as correct.

source: Stack Exchange

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

sort: votes


text:
What does an Arduino do if the serial connection is closed on the other end?
I have a simple method that simply waits for an input, computes a response, and sends it:
void loop() {
  if (Serial.available() > 0){
    input = Serial.read();

    if (input == 10){
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);

      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);

      duration = PulseDuration(echoPin, HIGH, 6000);
      distance = duration * 0.00034/2;  // 0.00034 m/us is speed of sound

      Serial.println(distance, 4);
      }
  }
}

My question: What happens to the arduino if I close the serial connection from the receiving end while it's printing out data (in the last line of the loop)?
Context and motivation:
The program works well most times. I can open a python program that sends the requests and prints out the reply using pyserial. After I close the python side and reopen it, connection is set and I can start listening on the side nicely just like the first time. Sometimes, however, when I try to restart the python program, I get a connection error saying that the port is already opened (I'm running in Windows.. there are tons of posts about this problem, but none of them have been helpful). Some other times, when connecting with the python program (which connects with connection = serial.Serial(self.arduino_port, 9600, timeout=0) it just blocks and doesn't connect, it doesn't give the "port already opened" error, and it doesn't advance to the next statement.
I am confident I did close the previous python run before attempting a new one (process explorer shows no active python programs running, it also shows no open processes using a serial handler). I'm not here to solve that problem directly, though, just to ask a related question.
I'm also confident running connection.close() does not terminate the arduino program, as I have been able to restart my python program without having to reset the arduino or anything, suggesting the arduino kept running its loop after I closed the connection on the python side.
All that to say that my latest hypothesis is that these issues arise when I close the serial connection connection.close() while the arduino is printing, but because the port is closed, that Arduino is stuck and cannot do the Serial.println(), as the USB never asks to flush the data in its buffer.
Is this possible/does it make sense? What happens to the arduino if I close the serial connection while it's printing out data?
I'm not posting my python program here as it's not directly relevant to the question and I can't seem to make a minimum reproducible program that doesn't expose confidential code.

Which Arduino? Please tag your question with that information. There are lots of Arduino models, and some have different ways of interfacing with USB than others.

the question is not about Arduino

@NickGammon It's an Arduino/Genuino 101

@Juraj He is asking what the Arduino does if the serial connection is closed so I think that is a relevant question. However the bulk of the question appears to be about the behaviour of Windows.

Yeah, I wanted to explain why I wanted to know what the arduino did, and perhaps got too much into the weeds of my overall problem (sorry), when all I wanted is to know what happens when the arduino tries Serial.println(..) while the other end is disconnecting.

That's some strange Intel monstrosity. It's impossible to know what it does or how. Intel's foray into the Arduinosphere was brief and somewhat abortive.
In general though (for most cores) the DTR signal (and sometimes the RTS signal too) of the CDC/ACM protocol is used to "gate" the serial data - if it's asserted then serial data gets sent through to the host PC. If it's not asserted then it just gets thrown away.
I have seen cores where if DTR is not asserted the data gets buffered until the TX buffer is full and then blocks, but that is rare.
You might find your answer if you delve into the core's source code, but you may find that big chunks of it are hidden away in closed source pre-compiled libraries, and the fact it seems to run some custom RTOS means it'll be even more obfuscated. YMMV...

or try it .....

Thank you @Majenko, that is helpful.

@Juraj, try what? I already am trying something (described in the post) and observing some behavior. I asked this question to see if my reasoning for said observation made sense. If you have suggestions for lower level tests to understand the behavior in this scenario, I’m all ears. I don’t know how to go lower level than what I’m doing now. How can I see the result of the arduino code if the test itself is to disconnect its serial communication? How can I tell whether the arduino is blocking or running its loop if I can’t re-connect to it?

@polortiz4, add Serial printing to the Blink sketch.

Hmm that’s a good and simple idea. Thanks

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


text:
Generating Externally Triggered Complimentary PWM with Arduino Due

I need a 2KHz complimentary PWM waves with adjustable duty and phase that is triggered by an external 4KHz source.
After reading the datasheet I think there might be 2 way to do this:

Use a TC unit in capture mode, and somehow generate an interrupt when the count reaches 2. Use another TC unit in waveform mode to output phase-correct PWM. Use yet another TC unit to implement dead-time and generate the complimentary PWM.

Use the PWM controller, which already have complimentary PWM with dead-time build-in, but I'm not sure if it accepts external trigger.

If either of them is possible, could you please provide and example code ?
Thanks in advance !


text:
2 instanced of ESP8266Ping
I'm using ESP8266Ping lib inside my iot lib which hanldes Wifi connectivity and MQTT messages. Since it create its own instance called Ping when calling #include <ESP8266Ping.h>- it had to be place in iot.cpp.
I writing another library, IPmonitor which checks clients on the network (using pings), I wanted to use ESP8266Ping again.
My sketch file, create an instance of iot and IPmonitor for check/ log errors on monitored clients.
But I get error of using the same library twice.
I guess that since ESP8366Ping.h library is defined it creates an instance of the class ( see mark below ):
class PingClass {
  public:
    PingClass();

    bool ping(IPAddress dest,   byte count = 5);
    bool ping(const char* host, byte count = 5);

    int averageTime();

  protected:
    static void _ping_sent_cb(void *opt, void *pdata);
    static void _ping_recv_cb(void *opt, void *pdata);

    IPAddress _dest;
    ping_option _options;

    static byte _expected_count, _errors, _success;
    static int _avg_time;
};

#include "ESP8266Ping.impl.h"
PingClass Ping;                     // <----- This

#endif

How can it be solved ?

With that library... you can't. All the code is in one big monolithic .h file. As you well know by now that is a big no-no. The author should be given a big slap on the wrists.
The closest you could do without re-writing the whole library is to just copy the class definition from the outer .h file and create an extern to the existing object - maybe make your own copy of the ESP8266Ping.h file without the #include "ESP8266Ping.impl.h" and PingClass Ping; (the latter of which you change to an extern).

Thank you. Since I don’t any future mishappens after lib update, I’ll probably use calling external function in ‘IPmonitor’ to call the relevant function from ‘iot’ class. And slapping

@Guy.D I have submitted a pull request with the required changes. You may like to test with my fork: https://github.com/majenkotech/ESP8266Ping

Well... this is very nice of you! Cheers


text:
Obtaining angular velocity from quaternion data (BNO055)
I'm able to get quaternion data from the BNO055 sensor, and would like to convert these to angular velocity for my project. I know you can pull the gyroscope directly for the data, but from what I understand using quaternions and converting those is more robust?
I found a function that does this in a Adafruit repository for the sensor. However, I'm not sure what the Delta time variable should be equal to, in relation to the sample frequency. Could anyone advise?
Here is the function code:
  Vector<3> toAngularVelocity(double dt) const {
    Vector<3> ret;
    Quaternion one(1.0, 0.0, 0.0, 0.0);
    Quaternion delta = one - *this;
    Quaternion r = (delta / dt);
    r = r * 2;
    r = r * one;

    ret.x() = r.x();
    ret.y() = r.y();
    ret.z() = r.z();
    return ret;
  }

And the link

Thank you for your time everyone. I really appreciate it.

I do not know how to interpret the data given by that sensor, but from
reading the code, the meaning of dt is pretty clear.
The function you show assumes that the sensor started in the reference
orientation (quaternion one), then rotated at a constant angular
velocity until it reached the current orientation (quaternion *this),
and this rotation happened over a time dt.
Then dt is the time required for moving from the reference orientation
to the orientation described by the quaternion *this. You should
probably check out the sensor's datasheet for more details on how the
orientations are provided.

Hi again Edgar and thanks for your response. I'll check and update the question.


text:
Calling functions between 2 classes
Class myIOT2 contains a function that need to be called from class IPmonitoring:
bool myIOT2::checkInternet(char *externalSite, byte pings)
{
    return Ping.ping(externalSite, pings);
}

This function is needed as a pinger in IPmonitor:
void IPmonitoring::start(cb_func ping)
{

        _ping_cb = ping;
}

and this cb_func is defined by (inside IPmonitor.h):
typedef bool (*cb_func)(char *externalSite, byte pings);
cb_func _ping_cb;

inside my sketch (relevant parts only) I fail when iot.checkInternet is passed, while using a function test that calls iot.checkInternet succeeds:
myIOT2 iot;
IPmonitoring WiFi_service(ROUTER_IP, "Router");

bool test(char *a, byte b)
{
        bool x = iot.checkInternet(ROUTER_IP);
        return x;
}

void setup()
{
WiFi_service.start(iot.checkInternet); // <---- Trial a)fails
WiFi_service.start(test);              // <-----Trail b)succeeds
}

error is :
home/guy/Documents/git/Arduino/IPmonitor/IPmonitor.ino: In function 'void setup()':
IPmonitor:436:45: error: no matching function for call to 'IPmonitoring::start(<unresolved overloaded function type>)'
         WiFi_service.start(iot.checkInternet);//
                                             ^
/home/guy/Documents/git/Arduino/IPmonitor/IPmonitor.ino:436:45: note: candidate is:
In file included from /home/guy/Documents/git/Arduino/IPmonitor/IPmonitor.ino:2:0:
/home/guy/Documents/git/Arduino/libraries/myIPmonitor/myIPmonitor.h:42:10: note: void IPmonitoring::start(IPmonitoring::cb_func)
     void start(cb_func ping);
          ^
/home/guy/Documents/git/Arduino/libraries/myIPmonitor/myIPmonitor.h:42:10: note:   no known conversion for argument 1 from '<unresolved overloaded function type>' to 'IPmonitoring::cb_func {aka bool (*)(char*, unsigned char)}'
Multiple libraries were found

What is done wrong ? and why test succeeds ?

Does this answer your question? Passing a method pointer

@Juraj No :( I didn't

@Juraj - mostly because Passing test succeeds

did you read that answer to the end?

@Juraj yes, but almost from start I fail to understand

the core of the problem is that a class method compiled has the object as first parameter so the parameters of the callback function don't match for cb_func

There is a fundamental difference between a simple function and a function that is a member of a class.  You can't use a function pointer to point to a member function of a class: simply because that member function also includes information about the class instance that it belongs to.
The proper C++ way to handle it is to use std::function, but the Arduino AVR compiler lacks the full STL (Standard Template Library), so that can't be used on normal Arduinos. Other cores do have it, so you may well be able to use it on the ESP8266.
If you want to make your code portable between systems that may not have the full STL then there's other tricks you have to do:

Use a wrapper function (which as you have found works), or
Make a polymorphic class and store a pointer to the instance cast to the parent class - the parent class defines the functions that are allowed to be called from the pointer.

Thank you very much for a comprehensive explanation. A) it is an ESP8366. B) wrapper function is needed for which one my member functions? C) can you please write or direct for such example ? I must say it is a bit vague for me.

The "wrapper function" is a simple function that calls the function in the object you want. Your "test" function from your example. Something like void test() { myObject.someFunction(); } - I use something similar here


text:
Initial setup print getting cut off from printing
I am writing a program in Python (using PySerial) that needs to read data from the Arduino quickly. For this reason I have set the serial timeout to 0.01 seconds. (Baud rate is 115k) If I don't set the timeout this low I run into issues with there being a noticeable delay between sending a command and receiving a reply. As long as I have the timeout set low enough then its all fine, but the downside is that I have a message print out when I first connect to the Arduino to confirm that it has indeed connected. (Message reads "Connected" once the serial connection has been established in void setup)
Okay, the problem: If I don't have the timeout set to 0.9 seconds or higher, the initial 'connected' message gets cut off. Of course if I have it set that high I get the issues I first described.
I'm looking for a way to keep the timeout very low but also get this first connected message when the void setup runs. Is there a way to have my cake and eat it too?
I did try starting with the timeout set to 1 second and once the connected message prints out change it to 0.01 seconds, but it just kept giving me an error.
Any help would be appreciated.

If you can send a character to mean “end of message” (typically CR and/or LF), then you will not need timeouts.

you can always check available() or change the timeout. but I am not sure if I understand what you do


text:
How can i call lcd.begin() from several different code files in a proper way?
I have a project split into several files:
//Loop.cpp
#include "LiquidCrystal.h"

void setup(){
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    lcd.begin(16, 2);
}

void loop() {
//Code
}

//Display.cpp
#include "LiquidCrystal.h"

namespace display {
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void displayData(const InputPacket &inputPacket, const DataPacket &dataPacket) {
    lcd.setCursor(0,1);
    lcd.print("Foo");    //This creates display error, unless i call lcd.begin(16, 2) in this function
}

} //namespace display

My initial problem is that - without calling lcd.begin() from within displayData() - the characters aren't displayed correctly. In other words, calling lcd.begin() in setup() doesn't help. (It appears to me that setup() has implicit static property, no?)
As an attempted solution, i could create an lcd object in Display.cpp, and call lcd.begin() from within displayData(). Even though characters are displayed properly, this gives me display flickering. (Presumably as a result of calling these functions repeatedly in the loop during runtime).
So, the only solution to this dilemma that i can come up with is to call lcd.begin() from a function written to run only once inside of displayData(). Or is it?
My question is, are there other more elegant solutions/alternatives?

The object called lcd that you create inside the setup function is a local variable. It only lives as long as that function is executing - so not very long. It doesn't exist outside that function.
The lcd object you have in namespace display on the other hand is a global variable. That one lives as long as your program, which means until you reset your Arduino here. (It is completely unrelated to the object inside setup.)
If you want all your LCD code to be grouped inside the display namespace, you could do this in Display.cpp:
namespace display {
  // This is a global variable, full name `display::lcd`
  LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

  void setup() {
    // this `lcd` refers to the global `display::lcd` defined above
    lcd.begin(16, 2);
  }

  // rest of the display functions
}

Create a Display.h file to provide prototypes for the display module:
#ifndef DISPLAY_H
#define DISPLAY_H

// Include the header that defines InputPacket and DataPacket here

namespace display
{
void setup();
void displayData(const InputPacket &inputPacket, const DataPacket &dataPacket);
}

#endif

Then your main file can call the display function. The main file doesn't even have to know that you're using an LCD if you do package all LCD code in the display file.
#include "Display.h" // no need to include LiquidCrystal.h if all
                     // LCD handling is done in Display.cpp

void setup(){
  // Initialize display
  display::setup();
}

Awesome, thanks. Your reply gave me a lot of interesting things to consider!


text:
Using or creating Wi-Fi Direct (P2P) connection on ESP8266
I want to make a Wi-Fi Direct connection with an android device using my ESP8266. According to ESP8266WiFi Documentation and ESP8266 datasheet, the board has a SoftAP mode which is I think what is needed in a P2P connection (Being an AP and a client at the same time).
There is also ESP-NOW in the Espressif website but I think it's made only for esp-to-esp p2p connection and I can't modify it. (Correct me if I'm wrong)
I couldn't find any pre-made libraries for this job, so I decided to make my own, but I can't seem to find anything related to making a new type of protocol or connection. Is it even possible to develop a new type of protocol? If yes, I'd really appreciate a guide on how to get started.

why not use esp8266 arduino? https://github.com/esp8266/Arduino#installing-with-boards-manager

@Juraj I'm sorry, but I looked into the Documentation mentioned in that repository but I couldn't find anything related to Wi-Fi Direct or P2P. Also when I mentioned "ESP8266WiFi documentation" I meant the library that you just shared. Can you please clarify which part of the library or documentation explains it?

the WiFi library of the "esp8266 Arduino boards support package" handles SoftAP and WiFi STA. AP and STA can be used together. you can receive and send data on both interfaces. btw; I wonder why you call the "esp8266 Arduino  boards support package" "documentation". the docs are here https://arduino-esp8266.readthedocs.io/en/latest/index.html

Maybe explain a little more what you want to achieve and why you need the esp to be both AP and station. I think you confuse some things, a client is usually sth on a different layer (you have websocket/http/... clients).

@SimSon As I explained, I need to establish a P2P connection (More specifically, use Wi-Fi Direct). A Wi-Fi direct connection requires both devices to be an AP & client at the same time (So they don't need to have the same access point to connect to) as explained here

@Juraj Yes, it does handle SoftAP and I can use it, but it's not obvious (or even possible) to make P2P connections with just that. You need more than just being an access point and connecting to an access point; To be able to make a P2P connection. Since ESP supports 802.11, It has the hardware capabilities for it. But I'm stuck at finding the right code/library to do it. Also, the exact link that you mentioned as "The docs are here" is the link in my comment.

what should that library do? P2P or WiFi direct is a connection without separate WiFi AP. if one of the esp starts the SoftAP and the other connects to it as STA, it is P2P.

i read it
can you do it in the end?


text:
What's the time out of Wire.begin()?
Here's a schematic of my project:

The purpose is to make laptop work as keyboard for desktop PC. Nano uses Serial.read() to get keystrokes from laptop and forwards key press and release data to Leonardo (using I2C) acting as USB-HID keyboard.
Nano's setup looks like:
void setup() {
  Wire.begin();
  Serial.begin(14400);
  Serial.write("Hello");  // https://serialport.io/docs/api-stream#serialpor|
  pinMode(LED_BUILTIN, OUTPUT);
}

Leonardo's setup looks like:
void setup() {
  Keyboard.begin();
  Wire.begin(4);
  Wire.onReceive(cbfunc);
}

I have tested both boards individually, but not the whole setup. Whenever either board connects to USB port it powers up due to +5 volt from USB. Now that I have i2c wires in place, I am confused -
if I connect leonardo & desktop first [and i2c-master (Nano) isn't powered on yet], what will happen at Wire.begin(4)? Will it wait (1s, 5s, forever) until i2c-master comes online?

why don't you write a sketch to test this?

Generally you should not provide power to any pin of a device, which is powered off. That can cause current flowing through clamping diodes to ground and might destroy the pins hardware or the device (also it can lead to weird situations, where the device is somewhat powered through the IO pin, which might lead to instability).
You can either cut the connection between the devices, if only one of them is powered (this should be possible with some extra components), or you can power both devices from one USB port. For the other port you would cut the V+ (positive supply voltage) line of the USB port/cable (this makes sure, that you don't get a bad current between both computers on the USB power line, if they provide a bit different voltage). Since the ground wire still connects both computers and the Arduinos, the communication will still work correctly.

if I connect leonardo & desktop first [and i2c-master (Nano) isn't powered on yet], what will happen at Wire.begin(4)?

The Wire.begin() line won't get stuck, since it doesn't do much on the lines and it doesn't know, if something is connected on the other end, until some transaction happens on the bus. But it might be, that any transaction from the powered Arduino (the master) might cause a blocked I2C bus (since at some places the library waits for the lines to get high. The connection through the clamping diodes might hold the line at low. I'm not sure about that). Then you would need to reset both Arduinos, to make sure, that the bus is in a healthy state.
The solution from above (powering both Arduinos from one USB port) will also make sure, that both Arduinos start at the same time and thus won't block the bus through the clamping diodes.


text:
Why AnalogRead shows value (395) when its on HIGH State ? why not shows 1023 when its high State
I Took a output from ESP8266 and Connected it with Arduino Nano Analog input A0
i use BLYNK app to on/off D0 pin in ESP8266 , and i connected ESP8266 D0 pin with Arduino Nano A0 analogPin.
when esp8266 D0 in high state , the analogRead value in arduino nano serial monitor it show the value 395.
why not 1023 on high state .

esp8266 has a 3.3 V TTL level. the ATmega analog pin reads 1023 at 5 V. and if you toggle the pin fast then not even 3.3 V will be read.

Did you connect the ground pins together?

@Majenko no i didnt connected the esp8266 ground pin to Arduino nano Ground pin , should i?

Absolutely - otherwise how can the nano know what the 3.3V from the ESP8266 is relative to...?

@Juraj please be specific , it will help me to learn .

datasheets are specific.

There are two problems here - one immediate and one which will be come apparent.
First off, you appear not to have connected the ground pins of the two boards together. This is important. Voltage is not an absolute value, it's a value relative to some other point in the circuit. This is why "voltage" is sometimes called "potential difference". Normally the point in the circuit that voltages are referenced to is termed "ground". Note: there is nothing special about ground, it's just an arbitrary point in the circuit - usually, but not always, the point where the voltage is lowest.  If the ground of the Arduino that it's using to compare incoming voltages against is not the same as the ground that the ESP8266 is using to create its output voltage in relation to, then the Arduino really can't know what the voltage is.
You can think of it as a person standing on the ground. Now I am about 6 feet tall. When I am stood up the top of my head is about 6 feet above the ground. But to someone who is stood on a nearby rise in the ground my head is only maybe 3 feet above the ground. Their ground is not the same as my ground.
The second problem, which will become apparent once you have connected the grounds, is that the Arduino measures voltages between 0 and 5V as values between 0 and 1023. However the ESP8266 doesn't operate at 5V, it operates at 3.3V. The highest voltage it can ever put out is 3.3V. The Arduino can never read that as 1023 because it's not 5V.  Instead it will read somewhere around 675. That is, 3.3V is two thirds of 5V, and 675 is two thirds of 1023.

yes now i got it ., thanks a lot . you are genuis.


text:
Programmatically-adjustable buck converter module?
LM2596 is easy to use and cheap, but I have to adjust the output voltage using a screw driver. On the web, there was a "hack" that someone posted, but that hack does not seem as clean or stable as using LM2596 as it is intended to be used, using screw driver. Is there something that is easy-to-use just like LM2596, but has some pins that can be used to dynamically adjust the output voltage using an Arduino?

Replace the pot with a digital potentiometer?

it's a lot easier to do with a linear supply; basically an npn voltage follower driven by an amplifying w/feedback opamp fed by smoothed PWM or DAC. The lm2596 isn't very clean anyway if that's your big conecrn; you would be better off with a newer offering from XLsemi, or use a linear for (by far) the best noise and stability.

@Majenko can you suggest a digipot that would actually be a suitable replacement for the analog? The affordable ones i've found have limited voltage ranges; often 5v, and we need a voltage divider here, not just a resistor, which makes it harder since specified voltage ranges are ref'd to a common ground. You can simply do the bottom half, but how to do the top half of the divider? How to control more than 0-5v output?

You could also do a design with a resistor ladder to replace the pot, shorting out various resistors with FETs or even relays, which would be very stable, but really drives up the parts count and complexity.

I've also found an cheapish ($10) SMPS module that took a pwm input to throttle the output voltage. I can't recommend it though because it bypassed feedback, and it smoked under a modest load...

The hack you described is most likely just feeding voltage from filtered PWM signal generated by microcontroller to the feedback loop of LM2596. I think you can get good enough noise performance with this approach if voltage change rate is not a concern. It all comes down to the PWM filter parameters. You can decrease noise by adjusting RC filter parameters (increasing capacitor and resistor values). It will cause increased delay in voltage change, but it will reduce the noise from PWM signal. Also, you can increase the PWM frequency by avoiding standard analogWrite which has pretty low frequency and configuring a separate timer for PWM generation.
Alternatively, if you need some specific voltages, you can replace the potentiometer with a fixed value resistor array connected in parallel and connect each resistor though separate low power MOSFET. This way, you can connect and disconnect a specific resistor which will change the total resistance of the array, changing the output voltage. It will only allow changing voltage by steps and the step size is dictated by the number of resistors, but the noise performance will be the same as using a potentiometer.


text:
How to declare char array[] using integers?
Can anyone please tell me how to declare a char variable using a few integers?
I need to declare a byte information for shiftOut() function as char.
int a = 0;
int b = 1;
int c = 0;
int d = 1;
int e = 1;
int f = 0;
int e = 0;
int f = 1;

char information[] = {"B" + a + b + c + d + e + f};

void setup() {
  Serial.println(information);
}

void loop() {
  shiftOut(pin, pin, MSBFIRST, information);
}

In command Serial.println(information); I want to get back B01011001
Now the output I am getting ⸮⸮
Of course the simpliest way to create that will be:
char information[] = "B01011001";
But I need to change the individual bits in int bit = variable.
Please note that substition int bit = with char bit = is unable for my code, using int of value of individual bits is necessarily. Because I am using my project with blynk, and there is function a = param.asInt(); ,  param.asChar(); does not exist.
How to do that?
Thank you for responses!

I think you are getting something wrong about shiftOut(). It will transfer exactly 1 byte (or 1 char). It does not take an array as parameter. I guess you want to write the 8 bits, that you are defining with your ints, as one byte out. Defining at byte directly would look like this:
byte information = 0b00101100;

The 0b tells the compiler, that the following number is encoded in binary. So you have one single byte, that contains all your information (all the bits). Then you can do
shiftOut(data_pin, clock_pin, MSBFIRST, information);

(Please note, that the data_pin and the clock pin need to be different).
If you want to print the information variable to Serial, showing the binary representation, you can use the corresponding parameter of the print() function.
Serial.print(information, BIN);

Will print the binary representation (zeros and ones as text) of the variable. So, to get "B1011001", you would do:
Serial.print("B");
Serial.println(information, BIN);

Note, that the print()/println() function will remove all leading zeros.

How to put the information byte with your ints? Each of them is either zero or one and represents one bit. So you can use the bitwise operators to put them together:
information = (a << 7) | (b << 6) | (c << 5) | (d << 4) | (e << 3) | (f << 2) | (g << 1) | h;

For each int only the first (Least significant) bit is important, since the others are always zero (because the int can be only one or zero). So we shift the int value to the left by the number of the corresponding bit minus 1 (so shifting a 7 places to the left to put its least significant bit to the most significant bit of information. We are doing that for all our int values. Then we put them all together into one byte by using the | (bitwise OR) operator.
Note: We don't know, where these ints are coming from. Even when stating, that you absolutely need those ints, you could organize them in an array instead of single variables. That would look like this:
int int_data[8] = {0, 0, 1, 0, 1, 1, 0, 0};
...
// in a function (like loop() or setup())
byte information = 0;
for(int i=0;i<8;i++) information |= int_data[7-i] << i;

It's up to you, if you want to do that.


text:
Help On Creating Derived classes in Headers
Here's a small problem I encountered while I was trying to make this small header file Devices.h:

Is it possible to use templates with abstract classes ? If yes, how and how can I use that abstract class to derive another class ?

Here's the contents of the header file :
#ifndef Devices_h
#define Devices_h

/* Initial build for MCUOS
Anybody can edit this according to their device needs */

#include "Arduino.h"

template < typename datatype>

class Device_Handler
{
    // a class to handle devices
    public:
        virtual void write_to_device(datatype *send_data)= 0; // write data to device
        virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location
        virtual void clear_device() = 0; // clear device state
};

class Serial_Handler:public Device_Handler<char*>
{
   public:
          void write_to_device(char *send_data);
          void read_from_device(char *store_location);
          void clear_device();
};

void Serial_Handler<char*>::write_to_device(char *send_data){
        Serial.println(*send_data);
 }

void Serial_Handler<char*>::read_from_device(char *store_location){
       *store_location = Serial.read();
}

void Serial_Handler::clear_device(){
        Serial.flush();
}

#endif

This is a small project I am trying at home nowadays (that MCUOS thing up there), also considering it a learning opportunity. I am not sure if I wrote the code in the header the right way. Initially, I made the Device_Handler class and used it in my sketch to craft the Serial_Handler class, but then it showed an error that the compiler expected a class name before the '{' character right at the place where I started writing the code for the derived class. Thus I decided to move the code for the derived class to the header, but I decided to seek your advice before heading further as I fear that more errors may come up and as I am kind of a beginner at C++.
Thanks in advance !
EDIT : I also doubt if it was because I wrote a comment near the starting line of the abstract class as the syntax highlighter here showed the comments in colour.
Edit: I resolved the issue up there (it was due to the misplaced comment), but a new issue has popped up saying that it expected an initialiser before the '<' token at the places where I had defined the functions in the derived class. This is where my actual is.
My snippets of main concern:
void Serial_Handler<char>::write_to_device(char *send_data){
        Serial.println(*send_data);
 }

void Serial_Handler<char*>::read_from_device(char *store_location){
       *store_location = Serial.read();
}

I doubt if these will be able to handle long sentences or have syntax errors.
Edit
I decided to move forward despite errors. Here's how I remade my header file:
#ifndef Devices_h
#define Devices_h

/* Initial build for MCUOS
Anybody can edit this according to their device needs */

#include "Arduino.h"

template < typename datatype>
class Device_Handler
{
               // a class to handle devices
    public:
        virtual void write_to_device(datatype *send_data)= 0; // write data to device
        virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location
        virtual void clear_device() = 0; // clear device state
};

class Serial_Handler:public Device_Handler<char*>
{
   public:
          void write_to_device(char *send_data);
          void read_from_device(char *store_location);
          void clear_device();
};

void Serial_Handler::write_to_device(char *send_data){
        Serial.println(*send_data);
 }

void Serial_Handler::read_from_device(char *store_location){
       *store_location = Serial.read();
}

void  Serial_Handler::clear_device(){
        Serial.flush();
}

#endif

Here's the sketch code:
#include <Devices.h>

Serial_Handler myserial;
char storage = '\0';
char test_string[] = "Hello";

void setup() {
  Serial.begin(9600);
  myserial.write_to_device(test_string);
  myserial.read_from_device(&storage);
}

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

}

(I know that the code up there may also be faulty)
and errors come up:
Arduino: 1.8.13 (Windows 10), Board: "Arduino Uno"
Devices_Test:3:16: error: cannot declare variable 'myserial' to be of abstract type 'Serial_Handler'

 Serial_Handler myserial;

                ^~~~~~~~

In file included from C:\Users\<smbdy>\Documents\Arduino\Devices_Test\Devices_Test.ino:1:0:

C:\Users\<smbdy>\Documents\Arduino\libraries\Devices/Devices.h:19:7: note:   because the following virtual functions are pure within 'Serial_Handler':

 class Serial_Handler:public Device_Handler<char*>

       ^~~~~~~~~~~~~~

C:\Users\<smbdy>\Documents\Arduino\libraries\Devices/Devices.h:14:16: note:     void Device_Handler<datatype>::write_to_device(datatype*) [with datatype = char*]

   virtual void write_to_device(datatype *send_data)= 0; // write data to device

                ^~~~~~~~~~~~~~~

C:\Users\<smbdy>\Documents\Arduino\libraries\Devices/Devices.h:15:16: note:     void Device_Handler<datatype>::read_from_device(datatype*) [with datatype = char*]

   virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location

                ^~~~~~~~~~~~~~~~

exit status 1

cannot declare variable 'myserial' to be of abstract type 'Serial_Handler'

How should I resolve this?

The Serial_Handler is not a template, so you are not supposed to be using SerialHandler <...> ::write_to_device / read from device

I edited it. Thanks @KIIV

Now I have run into another problem.

I defined the derived class definitions for the virtual functions is Device_Handler class but still the error came up... that is what is bothering me now.

Well, apparently that overrides are not the same as those pure virtual methods in the parent

@KIIV how come that be so ? I'd like to understand that a bit..

Also, I hope you know that I am a bit of a beginner ':)

The datatype is char*, that results into   char ** send_data etc. But don't worry, I didn't noticed this one much sooner

Let us continue this discussion in chat.

You are on the track, but it needs some adjustments:
template < typename datatype>
class Device_Handler
{
    // a class to handle devices
    public:
        virtual void write_to_device(datatype *send_data)= 0; // write data to device
        virtual void read_from_device(datatype *store_location)= 0 ; // read data from device to location
        virtual void clear_device() = 0; // clear device state
};

class Serial_Handler:public Device_Handler<char> // instead of char*
{
   public:
       void write_to_device(char *send_data) override;
       void read_from_device(char *store_location) override;
       void clear_device() override;
};

void Serial_Handler::write_to_device(char *send_data){ // It's not template, so no template specialization
        Serial.println(*send_data);
 }

void Serial_Handler::read_from_device(char *store_location){
       *store_location = Serial.read();
}

void Serial_Handler::clear_device(){
        Serial.flush();
}

The alternative is:
template < typename datatype>
class Device_Handler
{
    // a class to handle devices
    public:
        virtual void write_to_device(datatype send_data)= 0; // write data to device
        virtual void read_from_device(datatype store_location)= 0 ; // read data from device to location
        virtual void clear_device() = 0; // clear device state
};

class Serial_Handler:public Device_Handler<char*>
{
   public:
       void write_to_device(char *send_data) override;
       void read_from_device(char *store_location) override;
       void clear_device() override;
};

I worked it out.. thanks !

I have edited my project and it's in Github :https://github.com/Coder-X15/MCUOS


text:
How do I pause a loop just once?
I´m trying to make a pause in a loop, but just for the first time it loops. The next loops i would like the program to NOT do the pause. Just once time, each time a button is pressed. Does anybody knows how to do it?
Thanks!
This is the code i want to pause just once:
void loop() {
  if(digitalRead(switch_pin) == LOW){
    digitalWrite(led_green_pin,LOW);
    digitalWrite(led_red_pin,HIGH);
    lastMotionState    = currentMotionState;
    currentMotionState = digitalRead(MOTION_SENSOR_PIN); //
      if (currentMotionState == LOW && lastMotionState == HIGH) {
      servo.write(90);
      }
      else
      if (currentMotionState == HIGH && lastMotionState == LOW) { // pin state change: HIGH -> LOW
      servo.write(0);
      }
  }

Does anybody knows how to do it? is not a question that asks how to do it ... it is not a question about the arduino

what do you mean by pause? ... that implies that the code would somehow start up again, but you said nothing about what would stop it and what would start it again and where it should "pause"

Juan, https://stackoverflow.com/help/merging-accounts

The following code will pause (Give some delay) when it runs for the first time and also when you press the button.

void loop() {
  static int status = true;
  if(status){
    //Pause
    delay(15);
    status=false;
    return;
  }

  if(digitalRead(switch_pin) == LOW){
    digitalWrite(led_green_pin,LOW);
    digitalWrite(led_red_pin,HIGH);
    lastMotionState    = currentMotionState;
    currentMotionState = digitalRead(MOTION_SENSOR_PIN); //
      if (currentMotionState == LOW && lastMotionState == HIGH) {
        servo.write(90);
      }
      else if (currentMotionState == HIGH && lastMotionState == LOW) { // pin state change: HIGH -> LOW
        servo.write(0);
      }
  }
  else{
    status = true;
  }
}

Give delay according to your need.

I don't know what that continue; line does when there isn't a for/while/do-loop.

Better would be void loop() { static int status = true; ... } keeping the scope of status inside of loop() instead of global.

@Gerben and lurker thanks for pointing that out. I have made the changes accordingly. Instead of continue I have added return which will work as desired.

This is pretty simple, although you shouldn't see any difference, because loop() is running a lots of times in one second. But:
bool firstrun = true;
void loop() {
  if(firstrun == true){};
  else{
    if(digitalRead(switch_pin) == LOW){
      digitalWrite(led_green_pin,LOW);
      digitalWrite(led_red_pin,HIGH);
      lastMotionState    = currentMotionState;
      currentMotionState = digitalRead(MOTION_SENSOR_PIN); //
        if (currentMotionState == LOW && lastMotionState == HIGH) {
          servo.write(90);
        }
        else if (currentMotionState == HIGH && lastMotionState == LOW) { // pin state change: HIGH -> LOW
          servo.write(0);
        }
    }
  }
  firstrun = false;
}


text:
How to use float data from a sensor with the Arduino mouse library
I'm using a gyroscope, which returns angular velocity in floats. I'm trying to use this data with the arduino mouse library. The move function requires a signed character. I'm not what the best way is to convert the float data from the sensor into signed char.
In what way can I do this, losing the least in terms of precision?
I found out you can use dtostrf to transfer floats into an array of characters, but not sure what to do following this or if it's even the best way.
I would appreciate any guidance.

this appears to be a general C++ programming question, not an Arduino related question ... please do your research in the C++ language realm

Besides data type concerns, there are scaling concerns. Exactly what does the signed char represent for the mouse move function? What mouse library are you using? What range of float values might you get from the gyroscope? If it's, for example, -300.0 to +300.0 then you'll at least need to scale that down before converting to a char-sized integer.

this should help https://duckduckgo.com/?q=c%2B%2B+float+to+signed&ia=web

Thanks for the responses. Scaling will be necessary as the values do tend to be in the 300 range maximum per sample size. The signed character of the standard arduino library represents the amount of movement on screen, relative to the previous cursor position. I did try researching this in both the C++ and arduino realms, but couldn't find the answer so I decided to try asking.

The mouse library expects the movement coordinates to be provided as
8-bit signed integers, which corresponds to the int8_t data type. This
type is actually an alias to signed char, but calling it this way is
confusing, as the word char somehow implies a type meant to store
characters, which is definitely not the case here.
Converting a float to any integer type can be done by plain
assignment, with two caveats:

If the float exceeds the range of the integer, the assignment will
wrap around modulo 2^(integer size in bits). This is undesirable and
can be prevented by first constrain()ing the float to the
appropriate range.
The assignment rounds towards zero, whereas rounding to the nearest
integer is better if you want to minimize the errors. This can be
achieved with the round() macro.

In summary:
// In global context:
const float scale = 0.4;  // scale factor for mouse moves

// Within loop():
float rotation = get_data_from_gyroscope();
int8_t mouse_move = round(constrain(rotation * scale, -128, +127));

Note that the optimal scale can only be determined experimentally: you
have to tweak it until your input device “feels” right.

Thank you very much again, Edgar! It feels to me this is a very important part of the implementation as you can lose the precision of the sensor in the conversion, so I'm grateful to have an expert jumping in.

You are misunderstanding the type char. It is named character, because in ASCII representation you can use it to save one character. But internally it just is a number. The Arduino doesn't care, if you save characters in it or numbers, because characters are also numbers for it.
A signed char, like the move() function of the library uses` has 1 byte and is signed, thus can hold numbers from -128 to 127.
While the documentation is not clear about what the x and y parameters really represent the answer to this question is clear about it. Basically the whole range from -128 to +127 represents a whole inch (or what the computer thinks is an inch). So this results in a resolution of 1" / (127 - -128) = 1" / 255 = 0.0039" (or about 0.1mm). I don't know, what values you are getting from the sensor, but you will have to scale it to somewhere in the -128 to 127 range (depends on how sensitive you want it to be). And you won't loose precision here. The sensor values most likely are more precise, than the range of the mouse move() function.
The calculation will then be as simple as
signed char mouse_x = sensor_x * factor + offset;

The result of the calculation will implicitly converted to a 1 byte signed integer (this is what signed char is). If you want to make it clearer what happens here, you can also write:
signed char mouse_x = (signed char)(sensor_x * factor + offset);

This is not needed, but you might wanna do it for clarity.

Seen in Edgar Bonets answer: You might wanna contrain the value of above calculation to the -128 to 127 range. If you get an unexpected high value from your sensor, the above calculation would overflow the mouse_x variable (not good for correct values). So capping the values to that range with the constrain() function is definitely good. Refer to Edgars answer and the documentation for this.

Hi Chrisl, thank you very much for the detailed response. I really appreciate you taking the time. Between your and Edgar's responses I feel like I have a much better understanding of the issue. You both should know newbies are really grateful when you help out. Or they should be!


text:
ESP32 FREERTOS crash using Adafruit ST7789 in tasks with the Wifi enabled
I am trying to create a clock using a ST7789 display and a DS3231 RTC. In this clock I want to use NTP to keep it synced and maybe use the WiFi to anything else.
My problem started when I have tried to use tasks to split the code into pieces, manage priorities and to keep the loop code as clean as possible. When I try to update the display text from a task the ESP32 just crash and reboots.
I have cleaned the code to see where is the problem and I have noticed that the problem comes when I connect to my Router and then I try to update the text in the display, but doesn't fail if the WiFi is not started or I update the text outside the task. The cleaned code I am using is this:
#include <WiFi.h>
#include <Adafruit_ST7789.h>

#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 0
#else
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 1
#endif

#define TFT_MOSI 23  // SDA Pin on ESP32
#define TFT_SCLK 18  // SCL Pin on ESP32
#define TFT_CS   15  // Chip select control pin
#define TFT_DC    2  // Data Command control pin
#define TFT_RST   4  // Reset pin (could connect to RST pin)

// Colors
#define COLOR_TOP_BG tft.color565(125, 125, 125)
#define COLOR_TL_BG tft.color565(3, 96, 7)
#define COLOR_BL_BG tft.color565(3, 96, 7)
#define COLOR_TR_BG tft.color565(117, 70, 2)
#define COLOR_BR_BG tft.color565(117, 109, 2)

#define COLOR_TOP_TEXT ST77XX_WHITE
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK

static const char* ssid     = "WIFI_SSID";
static const char* password = "**REDACTED**";

// Initialize Adafruit ST7789 TFT library
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// the setup function runs once when you press reset or power the board
void setup() {

  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);

  // Now set up two tasks to run independently.
  xTaskCreate(
    updateDateTime,
    "updateDateTime",   // A name just for humans
    1024,  // This stack size can be checked & adjusted by reading the Stack Highwater
    NULL,
    3,  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    NULL
  );

  // Connecting to Wifi
   WiFi.begin(ssid, password);

  tft.init(240, 240, SPI_MODE2);    // Init ST7789 display 135x240 pixel
  tft.setRotation(3);
  drawBackground();
}

void loop() {

}

// Function to draw the display background
void drawBackground() {
  tft.fillScreen(0xFFFFFF);
  tft.fillRect(0, 0, 240, 24, COLOR_TOP_BG);
  tft.fillRect(0, 24, 120, 107, COLOR_TL_BG);
  tft.fillRect(0, 133, 120, 107, COLOR_BL_BG);
  tft.fillRect(120, 24, 120, 107, COLOR_TR_BG);
  tft.fillRect(120, 133, 120, 107, COLOR_BR_BG);

  tft.fillRect(0, 22, 240, 4, ST77XX_BLACK);
  tft.fillRect(0, 130, 240, 3, ST77XX_BLACK);
  tft.fillRect(118, 22, 4, 218, ST77XX_BLACK);
}

// Function to update the date/time
void updateDateTime( void * pvParameters ) {
  for( ;; ) {
    //tft.init(240, 240, SPI_MODE2);
    tft.setTextColor(COLOR_TOP_TEXT, COLOR_TOP_BG);
    tft.setCursor(6, 4);
    tft.println("MIE");

    delay(100);
  }
}

If I comment the WiFi.begin function or I call the function from loop without create a task or just move the three lines to loop function, it works perfectly.
#include <WiFi.h>
#include <Adafruit_ST7789.h>

#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 0
#else
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 1
#endif

#define TFT_MOSI 23  // SDA Pin on ESP32
#define TFT_SCLK 18  // SCL Pin on ESP32
#define TFT_CS   15  // Chip select control pin
#define TFT_DC    2  // Data Command control pin
#define TFT_RST   4  // Reset pin (could connect to RST pin)

// Colors
#define COLOR_TOP_BG tft.color565(125, 125, 125)
#define COLOR_TL_BG tft.color565(3, 96, 7)
#define COLOR_BL_BG tft.color565(3, 96, 7)
#define COLOR_TR_BG tft.color565(117, 70, 2)
#define COLOR_BR_BG tft.color565(117, 109, 2)

#define COLOR_TOP_TEXT ST77XX_WHITE
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK

static const char* ssid     = "WIFI_SSID";
static const char* password = "**REDACTED**";

// Initialize Adafruit ST7789 TFT library
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// the setup function runs once when you press reset or power the board
void setup() {

  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);

  // Connecting to Wifi
   WiFi.begin(ssid, password);

  tft.init(240, 240, SPI_MODE2);    // Init ST7789 display 135x240 pixel
  tft.setRotation(3);
  drawBackground();
}

void loop() {
  void * test;
  updateDateTime(test);
}

// Function to draw the display background
void drawBackground() {
  tft.fillScreen(0xFFFFFF);
  tft.fillRect(0, 0, 240, 24, COLOR_TOP_BG);
  tft.fillRect(0, 24, 120, 107, COLOR_TL_BG);
  tft.fillRect(0, 133, 120, 107, COLOR_BL_BG);
  tft.fillRect(120, 24, 120, 107, COLOR_TR_BG);
  tft.fillRect(120, 133, 120, 107, COLOR_BR_BG);

  tft.fillRect(0, 22, 240, 4, ST77XX_BLACK);
  tft.fillRect(0, 130, 240, 3, ST77XX_BLACK);
  tft.fillRect(118, 22, 4, 218, ST77XX_BLACK);
}

// Function to update the date/time
void updateDateTime( void * pvParameters ) {
  for( ;; ) {
    //tft.init(240, 240, SPI_MODE2);
    tft.setTextColor(COLOR_TOP_TEXT, COLOR_TOP_BG);
    tft.setCursor(6, 4);
    tft.println("MIE");

    delay(100);
  }
}

I am starting with FREERTOS and ESP32, and I am not sure what I am doing wrong... I have thougth that the problem was the RTC but after remove the RTC code and see that was the WiFi, I am not sure what can be the problem.
Best regards and thanks.

The ESP32 has a built in RTC. Why waste time adding an external one as well?

You're not the first to have problems using a display with code running on the same core as the WiFi (core 0). Bind the task to core 1.

Hello @Majenko, the internal RTC doesn't have battery to keep the hour even when the energy is gone, and that's the real reason. Also I have read that the internal RTC is not as precise as an external. I'll try to bind it, Thanks!.

But if you're using NTP for the time, what does any of that matter?

@Majenko I am also thinking in the posibility of loose the internet connection or doesn't have it at all. Also a way to learn doing things ;)

To pin the function to a core was not working for me surely because the init code is outside the function, so I have moved the init code to inside the function, out of the loop:
#include <WiFi.h>
#include <Adafruit_ST7789.h>

#if CONFIG_FREERTOS_UNICORE
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 0
#else
#define ARDUINO_RUNNING_CORE_0 0
#define ARDUINO_RUNNING_CORE_1 1
#endif

#define TFT_MOSI 23  // SDA Pin on ESP32
#define TFT_SCLK 18  // SCL Pin on ESP32
#define TFT_CS   15  // Chip select control pin
#define TFT_DC    2  // Data Command control pin
#define TFT_RST   4  // Reset pin (could connect to RST pin)

// Colors
#define COLOR_TOP_BG tft.color565(125, 125, 125)
#define COLOR_TL_BG tft.color565(3, 96, 7)
#define COLOR_BL_BG tft.color565(3, 96, 7)
#define COLOR_TR_BG tft.color565(117, 70, 2)
#define COLOR_BR_BG tft.color565(117, 109, 2)

#define COLOR_TOP_TEXT ST77XX_WHITE
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK
#define COLOR_TL_TEXT ST77XX_BLACK

static const char* ssid     = "MOVISTAR_F6112";
static const char* password = "C89qlqMifsjDMWhbdsJQ";

// Initialize Adafruit ST7789 TFT library
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);

// the setup function runs once when you press reset or power the board
void setup() {

  // initialize serial communication at 115200 bits per second:
  Serial.begin(115200);

  xTaskCreatePinnedToCore(
    updateDateTime,   /* Function to implement the task */
    "updateDateTime", /* Name of the task */
    1024,      /* Stack size in words */
    NULL,       /* Task input parameter */
    3,          /* Priority of the task */
    NULL,       /* Task handle. */
    0
  );

  // Connecting to Wifi
   WiFi.begin(ssid, password);

  //tft.init(240, 240, SPI_MODE2);    // Init ST7789 display 135x240 pixel
//  tft.setRotation(3);
//  drawBackground();
}

void loop() {
}

// Function to draw the display background
void drawBackground() {
  tft.fillScreen(0xFFFFFF);
  tft.fillRect(0, 0, 240, 24, COLOR_TOP_BG);
  tft.fillRect(0, 24, 120, 107, COLOR_TL_BG);
  tft.fillRect(0, 133, 120, 107, COLOR_BL_BG);
  tft.fillRect(120, 24, 120, 107, COLOR_TR_BG);
  tft.fillRect(120, 133, 120, 107, COLOR_BR_BG);

  tft.fillRect(0, 22, 240, 4, ST77XX_BLACK);
  tft.fillRect(0, 130, 240, 3, ST77XX_BLACK);
  tft.fillRect(118, 22, 4, 218, ST77XX_BLACK);
}

// Function to update the date/time
void updateDateTime( void * pvParameters ) {
  tft.init(240, 240, SPI_MODE2);
  tft.setRotation(3);
  drawBackground();

  for( ;; ) {
    //tft.init(240, 240, SPI_MODE2);
    tft.setTextColor(COLOR_TOP_TEXT, COLOR_TOP_BG);
    tft.setCursor(6, 4);
    tft.println("MIE");

    delay(100);
  }
}

I have kept the function pinned to a core to avoid problems if RTOS decides to run the function on another core later. I have to do more tests, but seems to works.
Best regards.


text:
connecting a MPU6050 and sabertooth 2x12 to a single Arduino Uno
so im using the sabertooth speed controller to control the two motors on my lawn mower and im trying to use the MPU6050 to keep the lawn mower straight. The problem im facing is that im trying to use the sabertooth and the MPU6050 on a single Arduino and the sabertooth uses the baud rate of 9600 but the MPU6050 uses 115200 and im trying to use a single .ino file to control everything. I want to receive the data from the MPU6050 and based of that make a program to move the motor so that the mower will go in a straight line and such.

so, what's your question?

I know only of MPU6050 boards, that use I2C. Are you sure your MPU is using Serial (UART)?


text:
Error message while trying to burn bootloader onto atmega 328p
I have tried to burn bootloader onto an atmega 328p chip onto a breadboard using another arduino uno , I am not using an external clock but I am doing all the steps to make this thing which are given on this site - https://create.arduino.cc/projecthub/techmirtz/arduino-without-external-clock-crystal-on-atmega328-d4fcc4
the error code I am receiving is this :
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\DELL\Desktop\arduino ide\arduino-nightly\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM4
         Using Programmer              : stk500v1
         Overriding Baud Rate          : 19200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    20     4    0 no       1024    4      0  3600  3600 0xff 0xff
           flash         65     6   128    0 yes     32768  128    256  4500  4500 0xff 0xff
           lfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           lock           0     0     0    0 no          1    0      0  4500  4500 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00

         Programmer Type : STK500
         Description     : Atmel STK500 Version 1.x firmware
         Hardware Version: 2
         Firmware Version: 1.18
         Topcard         : Unknown
         Vtarget         : 0.0 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.03s

avrdude: Device signature = 0x000000 (retrying)

Reading | ################################################## | 100% 0.03s

avrdude: Device signature = 0x000000 (retrying)

Error while burning bootloader.
Reading | ################################################## | 100% 0.02s

avrdude: Device signature = 0x000000
avrdude: Yikes!  Invalid device signature.
         Double check connections and try again, or use -F to override
         this check.

avrdude done.  Thank you.```

A device signature of 0x000000 usually means you've wired it wrong.

"I am not using an external clock" I take this to mean that you didn't attach a crystal or clock to it.  Or that you don't want to.  What it doesn't tell me is whether or not the ATMega328P you're using has previously been fused for an external clock or crystal.  So, where/what did you get the ATMega328P from?  Or alternately do you know that it is not currently configured for something other than internal RC oscillator?

@timemage Its totally new and has not yet been programmed for anything, I didnt take it out of any arduino or anything - bought it separately


text:
Issues with interrupts coming from RTC DS3231 and power supply interference
Several months ago I developed a device able to detect water flood in a closed space and do some operations in case (closing valves, issuing an acoustic and Bluetooth alarm etc.).
After 8 hours it tries to reopen the valves and restart the normal cycle. Arduino UNO is always in sleeping mode (this device remains active 7/24). It wakes up every minute (@ sec.00) to detect presence of water, checks for 4 cycles (4 minutes) the presence of water -if the sensors are on- and then, after have issued the alarms and closed the valves, it wakes up after 8 hours, in order to reopen the valves and come back in its normal check-mode.
It worked and works flawlessly, when left working on my table. I tried it for almost a month.  The problem raised when I installed it in place, because there is a water pump (an autoclave, of some 1,5Hp, 1 phase), connected on the same power supply line, that -of course- starts whenever somebody opens a water valve at home.
Whenever it starts, Arduino wakes up immediately and the 1 minute (or 8 hours waiting cycle) stops.

I tried to use several caps on the 12V power supply line (some 3000uF, 50Vl in total) and a EMI filter between the power supply line and my device, but nothing changed.

I made some mods on the software, checking if the wakeup hour and minute is compatible with the correctly wakeup time calculated and setted on Arduino, and storing an alarm flag with wakeup hour and minute in EEPROM, in order to manage the same check if Arduino undergoes a hardware reset or is turned off/on.

I suspect that the problem raises for the fact that the RTC interrupt is activated when the IRQ pin is lowered from the HIGH state.
There is a way to set the DS3231 to remain in LOW state always, and issue a HIGH level just for the interrupts?
Does anybody have any electrical suggestion? I use this 12V chinese switching UPS/power supply connected to a 12V-7Ah lead battery that assures no interruptions.

I don't know how to ask you clarifying questions about this without them also implicitly containing an answer: best attempt show the wiring and find out whether or not you're tripping the UNO's brownout detector.

Thank you very much for your answer.
I'm puzzled a little bit.
my power supply gives some 10A (@13,4V), and it's connected to a big 12V-7Amps (4,5lbs) brand new lead battery (*) to Arduino (on VIN pin+ground) + a 7805.
The 7805 feeds a couple of water sensors (less than 5mA each), the DS3231RTC, 3 LEDs plus the relais board (2 relais, some 55mA each when excited), of course all the grounds connected togheter.
(*)  https://www.amazon.it/gp/product/B071JMHMN6/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1
I did not draw the wiring diagram yet, but I will make it ASAP

It would probably help to see it diagrammed. In your setup() can you do something like blink an led with an easily recognizable pattern such that if your Arduino UNO resets, you will be able to tell very clearly?

yes. I normally do not write diagrams for very simple circuits, but its just a my fault, of course.
In the front of my device there are 3 main leds, I blink them all for 1/2 second in the setup function.
They don't light up during these strange "resets".
I believe that something different happens, like just a unexpected, wakeup that happens just when a transient noise happens in line power.
I prepared a new firmw. version (that I will try tomorrow) in which I always check datetime after the wakeup, reading it from the EEPROM, in which I write in case of flood, just before to go to sleep.

Today I've done other tests:

Arduino does not emit serial messags after those strange resets - it' clearly visible that continues to work by the blinking leds - to obtain messages it's needed to reset Arduino (close/reopen serial window in IDE or push reset);
changing power line does not change anything - I connected it to another power line, completely isolated from the original one and the problem persists;
leaving it powered just by the big battery does not change anything (!) when the pump starts Arduino wakes up!

...an EMI? I connected all the grounds to earth

Without compilable code and a diagram there's not much for me to ask, say, or do.

My guess would be EMI. Can you twist and shield the power lines from the big battery to the Arduino? Do you have a oscilloscope? You could try to see if there is a spike in the 5V power to the Arduino when the pump starts running.


text:
Best way to add external power supply when main PSU is a solar charge controller?
I have a 12V 20A Solar Charge Controller (which is part of my existing Solar Panel System Setup connected to a 12V Sealed Lead Acid Battery) that I will use to power up some pumps with the help of relays and some sensors. And because its a solar charge controller, the output varies depending on the sun, from 12.1v to 13.8v (I set the Load Reconnect, Load Disconnect, Float Charge etc which technically 12V to 13.8V)
How do I power my Arduino Mega safely in this case?
I am planning on using a separate buck converter that will give my Arduino a fixed 9V from the Solar Charge Controller.
Should I power the Arduino with the buck converter parallel to the same PSU (the 12V 20A Solar Charge Controller) I'm using for the pumps and is it safe that way?
or
Should I use a 9V battery to separately power the Arduino Mega?  and what is the explanation behind the concept of using an external PSU for the Arduino Mega when the total Amperes all in all is not exceeding the limit 20A at all?

I'm no expert in this, but isn't a buck converter holding the set voltage independent of the input, as long as it is high enough (giving it some headroom for working correctly). Then a varying voltage from 12 to 13V should not cause problems.

You didn't mention that you had a 12 volt nominal battery.  Maybe because there's a reason why you don't want to use it. I bring this up because typical solar charge controllers of the kind that would normally have something like an 12 VDC nominal lead acid battery bank (perhaps just one battery) attached to them, have their internal electronics powered from the battery bank itself.  In other words, most solar charge controllers cannot be used just as live voltage regulator powering a load without also a battery. I just want to make sure you have considered this.

20A is the redline on the charge controller.  It doesn't output 20A unless the solar panels are delivering >=20A.

@timemage, yes i edited my question. thanks for the information.

@Harper-ReinstateMonica may load total is lower than 20A, and the pumps and sensors will not turn on at the same time, thats why i want to integrate Arduino in my set up. I used fuses and relays just in case so that my set up will be safe

@chrisl thats what i thought too but then my arduino's ground is connected to the positve of the scc when i check for continuity and i find it strange, im not an expert in electronics and im scared i might fry m arduino

"arduino's ground is connected to the positve of the scc" Did you mean "negative" instead?  Because this makes no sense to me generally, nor in connection with chrisl's original comment.

@timemage not negative,i really meant positive which i know is not right and im weirded out, i thought  its because of i paralled the Arduino the the SCC Vout with the pumps

Should I power the Arduino with the buck converter parallel to the same PSU (the 12V 20A Solar Charge Controller) I'm using for the pumps

Yes. However I wouldn't use a 9V buck regulator, but a 5V one and feed it to the 5V pin. That way you bypass the wasteful LDO on the Arduino, and when running from solar every bit of power saving you can muster helps.

and is it safe that way?

Yes, it's safe. As long as the buck regulator you are using is rated for the voltages in question.

An Arduino is no load for a solar panel that can provide 20A. So I wouldn't bother the complexity and just use a 12V battery and the on-board converter.

@PMF is not about the load. It's about the heat with such a massive voltage drop.

I see, but wouldn't you have that anyway, even if you use some external DC/DC converter? Or are those more efficient than the onboard one?

@PMF They are massively more efficient. The LDO converts the voltage difference into heat. A DC/DC converter chops it up to change the average power throughput.

If possible, I would feed the 5V via the USB connector rather than 5V pin, so you can take advantage of the Arduino Mega's PTC fuse.

@Majenko i'll definitely do that  thank you so much

Ok first, you need a battery for all this to work.  The solar charge controller won't drive into nothin', that is not what they are designed to do.
Its full name is "solar battery charge controller".   Size the battery any way you like, just make sure the charge controller knows what kind it is, so it sets the proper charge curves and doesn't overcharge it/boil it dry/make it catch fire (lithium).
Once you have a battery in the system, paralleling in another battery charger is not a problem, be it wind, AC mains, or another solar CC.

Now, you will need to manage the case where the Arduino calls for the pump to turn on, but the solar panel is not making enough power to successfully power the pump.  This will not magically sort itself out.

If you did not have a battery, it'll "crow bar".  The pump would effectively pull the solar voltage to near zero, which would cause the Arduino to shut down, turning off the pump and causing solar voltage to recover.  The Arduino would reboot, try again, and fail again.  Repeating.  So a crow-bar condition.

If you do have a battery, then the Arduino will successfully spin up the pump, but, the solar won't be enough and this will be depleting the battery.  If your usage runs the battery flat, see crow-bar above.

If you have a battery and the Arduino monitors battery voltage, it can defer operation until the Arduino knows the battery is sufficiently charged for the work needed.  At this point you don't need to care if the solar is up, the battery will carry the "buffer".    Make sure to shut the load off before the battery is depleted enough to create a crow-bar condition.

Note that if the battery is lead-acid, it should be managed to stay within 60-100% state of charge.  Depleting a lead-acid below 60% of max will rapidly age the battery.  It probably will be, since they are a happy intersection of "cheap" and "well-supported by every charge controller ever made".
Power to the Arduino itself should be taken as close as possible to the energy source (e.g. battery) — even if that means a long, redundant cable, especially in that case actually.  Do not share a supply cable with motors or pumps or other heavy loads!!!  I have seen many installations where the startup current of the motor causes enough voltage drop down the shared supply cable to cause the Arduino to lose power and reboot.   That is quickly cured by running a redundant V+ and V- power cable just for the Arduino.

Thanks for that detailed explanation, im sorry that my scc info was unclear and so i edited my question.. im using thick wires at short distance to prevent voltage drop. i used cable terminals to easily manage the wires of the system. Should i use the same breaker for the main Output of my SCC and parallel my arduino power right there with the pumps(but a different wire for the arduino)? or can i just use the terminals? thanks


text:
Using MCP23017 with 5 rotary encoders, WITHOUT missing a single step from any of them?
I have recently followed the instructions in the answer to this question:
Reading several rotary encoders
posted by maximilian-gerhardt
I've wired everything up, and am using the interrupts example that can be found here:
https://github.com/maxgerhardt/rotary-encoder-over-mcp23017/tree/master/examples/Interrupt
Everything seems to work as expected, except that my assumption was that since this was an interrupt-based solution, that I wouldn't be missing any steps of any of the encoders. There are a total of 5 that will move at the same time, and it is clear that while it almost works, there are many steps that are missed.
I'm guessing that is because while one interrupt is being handled, all other interrupts are disabled?
Is there any way where I can ensure that every single motion (step CW or CCW) is registered on all 5 encoders?
Thanks!
Brian

Interrupts are no garant for missing no steps. The steps need to happen only as fast, as the interrupts need to execute. The reading of the MCP over I2C alone would take 100us min (assuming 1 byte of data. With 2 bytes you would have 150us min). And then the executing time of the logic how fast are your steps coming in?

I would use a different approach. Consider setting a flag when an interrupt occurs, a different flag for each interrupt then processing that in the main loop rather then the ISR (Interrupt Service Routine). Connecting with the SPI  in the 1.7 MHz mode will allow you to get in check the interrupt set the flag and leave the ISR. This will be a bit difficult to write but I think it would work very well. Taking a quick scan of the data sheet the MCP23917 should be the correct part to accomplish this. Also do the debouncing externally, will save a lot of code and speed up the process.

Interrupts don't mean that you can do lots of things at the same time. All they mean is that something can be responded to rapidly, as long as nothing else is being responded to of an equal or higher priority.
And coupling that with an IO expander which will inevitably slow things down means that you really can't do what you are trying to do.
If you want to respond instantly to every single pulse of every single encoder then each encoder has to be attached to something that can itself respond to those pulses.
I would be inclined to have a small microcontroller attached to each individual encoder (or maybe two encoders if you have enough interrupt pins) and deal with each separately - that way one encoder cannot interfere with any other. The small MCU can then keep track of position or count (depending on what it is you are trying to do) and you communicate that to a "master" controller (the Arduino for example) over some other bus, asynchronously to the encoder's pulses.
If you want more rapid response to the encoder movements then it could be possible to implement your own interrupt signal from the small MCU to the Arduino to say "My encoder has been moved", at which point the Arduino can collect the data. It won't matter how long that takes to happen as the small MCU will be keeping track of any other changes. The ATTiny85 using Pin Change Interrupts could be a good low-cost choice for this.


text:
strange strings

#include "Keypad.h"

char Incoming_value = 0;
String password = "123456";
String input = "";
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6,7,8,9}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

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

void loop()
{
  if (Serial.available() > 0)
  {
    Incoming_value = Serial.read();
    Serial.print(Incoming_value);
    Serial.print("enter value");
    if (Incoming_value == '1') {
      digitalWrite(13, HIGH);
      Serial.print("ON");
    }
    else if (Incoming_value == '0') {
      Serial.print("OFF");
      digitalWrite(13, LOW);
    }
  }
  // Read the pushed button
  char key = keypad.getKey();
  input = input + key;
  // just print the pressed key
  if (key) {
    Serial.println(key);
  }
  if(key == '*' ){
    Serial.println(input);
    if( input == password){
      digitalWrite(13, HIGH);
    }
  }
  if(key == '#'){
    digitalWrite(13, LOW);
    input = "";
  }

/*
  // this checkes if 4 is pressed, then do something. Here  we print the text but you can control something.
  if (key == '4') {
    Serial.println("Key 4 is pressed");
          digitalWrite(13, HIGH);
      Serial.print("ON");
  }
    if (key == '5') {
    Serial.println("Key 5 is pressed");
          digitalWrite(13, LOW);
      Serial.print("ON");
  }
  */
}

when print input variable i get strange text like

⸮⸮⸮⸮⸮⸮⸮;⸮⸮ߵ⸮⸮⸮⸮u⸮⸮⸮⸮⸮⸮?/}⸮⸮⸮⸮⸮⸮~⸮⸮⸮⸮⸮-d

what i can do ?

Probably you haven't added a delay towards the end of void loop()

As an example : download JohnsProject/ArduOS from Github and run the main sketch there after putting the line of code that invokes the registry to run the shell app. You'll see the same strange thing happening

Also, try adding the delay as I said in void loop() in you sketch and see if it works.

Have you confirmed that your IDE serial monitor baud rate setting is 9600 (which is what your code assumes it is)?

@lurker , is my answer okay ? (Perhaps I can add your point on the baud rate setting in the Serial Monitor, if you wish ;) )

First of all you have to make sure, that you select the same baudrate in the Serial Monitor, that you used in your sketch with Serial.begin(). This error is very common and garbage values is the symptom of this.
But your code also has problems. You have the input variable of type String, which should hold the user input for comparison with the password. Directly after getting the key, you are appending this key to the string. You are assuming here, that keypad.getKey() is waiting for the user to actually press a key and then return that. But this is not the case. keypad.getKey() will return NO_KEY, when the user currently isn't pressing a key. This is defined in the Keypad library as '\0' (the null character), which marks the end of a string. Your code runs very fast, so you are adding more and more null characters to your string. Your strings gets bigger and bigger, filling your RAM very fast.
How to solve this: You should only use the return value of keypad.getKey(), if a key was actually pressed. Put all the code after it in an if statement, checking for NO_KEY:
// Read the pushed button
char key = keypad.getKey();
if(key != NO_KEY){
    input = input + key;
    // just print the pressed key
    if (key) {
        Serial.println(key);
    }
    if(key == '*' ){
        Serial.println(input);
        if( input == password){
            digitalWrite(13, HIGH);
        }
    }
    if(key == '#'){
        digitalWrite(13, LOW);
        input = "";
    }
}

Nice answer ! You corrected the code I wasn't able to ! (+1)

PS: @lurker's suggestion in the comments - check the baud rate setting in your serial monitor as well.
EDIT: I admit that the code in the previous version of this answer was foolishly typed out by me due to lack of patience, so I'll make up for my mistake(not in code, but as a full answer).
First of all, I didn't understand what you wanted to do with the Incoming_value variable in your sketch, so I'm not gonna talk about it; I'd suggest adding a sufficiently small delay at the end of the code in the loop. This should provide the serial port some time to handle the incoming data and stop printing the confusing output (perhaps; just because delays make your microcontroller wait for a while to get things done elsewhere , especially where the reception of data is slow and thus avoid collisions)
Also note that I am not a CS student or an electronics geek, but I am speaking from my guesswork. Any correction is accepted.

Given that most often delays do more harm than good, what is the rationale for adding them here? I can see how they could help on a program that sends data to a very slow receiver, but this is not the case here. To make the code “run smoothly” is overly vague.

@EdgarBonet sorry for the late reply. Note that at the place where the system is made to receive the keypresses, adding a delay allows the person to type the password (As in the example) key by key -  and now that reminds me of how foolishly I have added the code in my answer. Thanks a lot !! :D


text:
Receiving DMX512 on STM32F103C8
tl;dr: trying to receive DMX512 (via a RS485 module) on a STM32 and not going well.
I am trying to modify the firmware of a commercial lighting fixture with a STM32F103C8 clone as it's MCU. It basically receives DMX and converts it into a single axis of motion and a lighting fixture with ~24 WS2812B LEDs. Unfortunately, all of the DMX libraries available (DMXSimple2, Conceptinetics) only support avr, and I don't have very much experience with the lower level hardware/library interactions.
I am looking at this tutorial because it seems easier to modify to work with the STM32, but the tutorial says

Now just do a search for "ISR(USARTn_RX_vect)" in HardwareSerial.cpp

which I can't find in the Arduino STM32 core.
Can someone help or point me towards resources about how to modify the existing libraries to work for my application?

Are you using Arduino STM32 core or STM32 HALs?


text:
My LED display fails with MSGEQ7 output stuck
I have an Arduino setup with a pro-mini, a MSGEQ7, and a auto-gain mic. Even if I remove the audio input to the MSGEQ7 remains the same in the 890s (out of 1024). It's the same on each of two new MSGEQ7. I've checked the schematics, https://www.instructables.com/Music-Sync-Flashing-LEDs-Arduino-MSGEQ7/, multiple times and everything seems in order including components.
I'm using the #include <MD_MSGEQ7.h>, but I've tried it without.
Any ideas?
#include <Adafruit_NeoPixel.h>
#include <MD_MSGEQ7.h>

int LEDPIN = 12;
int MODEPIN = 10;

int mode = 0;
int lastState = LOW;

int NUMPIXELS = 50;

int DATA_PIN = 1; // read from multiplexer using Analog Pin 1, MSGEQ7 pin 3
int STROBE_PIN = 2; // MSGEQ7 pin 4
int RESET_PIN = 3; // MSGEQ7 pin 7

int spectrumValue[7];

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB + NEO_KHZ800);
MD_MSGEQ7 MSGEQ7(RESET_PIN, STROBE_PIN, DATA_PIN);

void setup() {

  Serial.begin(9600);
  pinMode(MODEPIN, INPUT);
  pixels.begin();
  MSGEQ7.begin();
}

void loop() {
  int currentState = digitalRead(MODEPIN);

  if (currentState == LOW && lastState == HIGH) {
    mode++;
    if (mode > 2) {
      mode = 0;
    }
  }
  lastState = currentState;

  MSGEQ7.read();

  for (int i = 0; i < 7; i++) {
    Serial.println(MSGEQ7.get(i));
  }
  if (mode == 0) {
    for (int i = 0; i < NUMPIXELS - 1; i++) {
      pixels.setPixelColor(i, pixels.Color(30, 60, 60)); // RGB
    }
  } else if (mode == 1) {/////////////////////////////////////////////////////////
    int height = (NUMPIXELS - 1) * MSGEQ7.get(1) / 1024;
    for (int i = 0; i < NUMPIXELS - 1; i++) {
      if (i < height) {
        pixels.setPixelColor(i, pixels.Color(60, 60, 0)); // RGB
      } else {
        pixels.setPixelColor(i, pixels.Color(0, 0, 0)); // RGB
      }
    }
  } else if (mode == 2) { /////////////////////////////////////////////////////////
    pixels.setPixelColor(0, pixels.Color(120 * MSGEQ7.get(5) / 1024, 0, 0)); // RGB
  }
  pixels.show();
}

Not much to go on here. Where's your code? Are you saying you followed the schematic in that article exactly, including components? What does "...I remove the mic the output..." mean?

Edited. Thank you.


text:
Dealing with noise in arduino interrupt
I'm makeing two modules,
module2 gets sensor signal, and send wireless message to module1, with HC-12. Then module1 is going to do some work it is supposed to do. Circuit configuration is in the picture.
I tested HC-12 communication, and they send, receive well. But my problem is that,
when module1 gets turned ON, Interrupt gets activated (LOW) and module2 sends signal that's not supposed to send. It seems it is because of electromagnetic wave noise, from HC-12.
How can I filter this noise, using code ? Now I'm stuck for the last 3 days.

code
Module1
#include <SimpleTimer.h>

#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>

// #define IDlen 4
#define maxID 5

SoftwareSerial mySerial(2,3);
LiquidCrystal_I2C lcd(0x27, 16, 2);
int upButtonPin = 7;
int selectButtonPin = 6;
int downButtonPin = 5;
int sensors[maxID] = {1001,9999,9999,9999,9999};
int receivedID = 0;
int currentPos = 0;
String rcvMsg = "xxxx";

//void printSensor(int intID);
void menu();
void showAllSensors();
int removeID(int senNumInt);

void setup()
{
  Serial.begin(9600);
  Serial.println("Serial began.");

  mySerial.begin(9600);
//  mySerial.println("0000");

  lcd.begin();
  pinMode(upButtonPin,  INPUT_PULLUP);
  pinMode(selectButtonPin, INPUT_PULLUP);
  pinMode(downButtonPin, INPUT_PULLUP);
}

void loop()
{
  rcvMsg = "xxxx";
  lcd.setCursor(1,1);
  lcd.clear();
  lcd.print("Ready");
  if(digitalRead(upButtonPin)==LOW){
    lcd.clear();
    lcd.print("Up btn pressed!");
  }
  if(digitalRead(downButtonPin)==LOW){
    lcd.clear();
    lcd.print("Down btn pressed!");
  }
  if(digitalRead(selectButtonPin)==LOW){
    lcd.clear();
    lcd.print("Registered sensors:");
    delay(1000);
    lcd.clear();
    showAllSensors();
    menu();
  }
  if(mySerial.available()>0){

//    String rcvMsg = mySerial.readStringUntil('\n');
    rcvMsg = mySerial.readStringUntil('\n');
    Serial.print("Received msg: ");
    Serial.print(rcvMsg);
    Serial.print('\n');
    receivedID = rcvMsg.substring(0,4).toInt();
    Serial.println(receivedID);
    delay(50);

    for (int i=0;i<maxID;i++){
      if(sensors[i] == receivedID){
        String temp = String(receivedID);
        String ack = String(temp + "01"); // 01: success 02: reject (ID does not exist)
        mySerial.println(ack);
        Serial.print("Ack sent: ");
        Serial.print(ack);
      }
    }
  }
}

void menu(){
  lcd.print("UP: add sensor");
  lcd.setCursor(0,1);
  lcd.print("DOWN: del sensor");
  lcd.setCursor(0,0);

  while(1){
    if(digitalRead(upButtonPin)==LOW){
      lcd.clear();
      lcd.print("Add sensor:");
      delay(1500);
      lcd.clear();
      int senNumInt = 1000;
      char senNum[IDlen];
      sprintf(senNum, "%d", senNumInt);

      while(1){
        lcd.print(senNum);
        if(digitalRead(upButtonPin)==LOW){
          senNumInt++;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(downButtonPin)==LOW){
          senNumInt--;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(selectButtonPin)==LOW){
          lcd.clear();
          lcd.print(senNum);
          lcd.setCursor(0,1);
          lcd.print("Menu: OK, Down: Cancel");
          //센서 입력값을 받아서, 리스트에 넣어 놓기
          sensors[currentPos] = senNumInt;
          lcd.clear();
          showAllSensors();
          delay(1500);
          break; // 값 입력 후 저장한 것 보여주고... 나가기.
        }
        delay(200);
        lcd.clear();
      }
      delay(200);
      break;
    } // up button 누름 메뉴 끝

    if(digitalRead(downButtonPin)==LOW){
      lcd.clear();
      lcd.print("Remove sensor:");
      delay(1500);
      lcd.clear();
      int senNumInt = 1000;
      char senNum[IDlen];
      sprintf(senNum, "%d", senNumInt);

      while(1){
        lcd.print(senNum);
        if(digitalRead(upButtonPin)==LOW){
          senNumInt++;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(downButtonPin)==LOW){
          senNumInt--;
          sprintf(senNum, "%d", senNumInt);
          lcd.clear();
          lcd.print(senNum);
        }
        if(digitalRead(selectButtonPin)==LOW){
          lcd.clear();
          lcd.print(senNum);
          lcd.setCursor(0,1);
          lcd.print("Delete sensor");
          delay(600);
          lcd.clear();

          //센서 입력값을 받아서, 리스트에서 찾은 후 삭제
          int result = removeID(senNumInt);
          if(result==1){
            lcd.print("Deleted.");
            showAllSensors();
          }else{
            lcd.print("No such ID!!");
          };
          delay(1500);
          break; // 값 입력 후 저장한 것 보여주고... 나가기.
        }
        delay(200);
        lcd.clear();
      }
      delay(200);
      break;
    } // down button 누름 메뉴 끝

    delay(200);
  }
  return;
}

void showAllSensors(){
  char imsi[IDlen];
  for(int i=0;i<maxID;i++){
    Serial.println(sensors[i]);
    sprintf(imsi, "%d", sensors[i]);
    lcd.print(imsi);
    delay(800);
    lcd.clear();
  }
  return;
}

int removeID(int senNumInt){
  int isFound = 0;
  for(int i=0;i<maxID;i++){
    if(sensors[i] == senNumInt){
      sensors[i] = 9999;
      isFound = 1;
    }
  }
  return isFound;
}

codeModule2
#include <SoftwareSerial.h>
#include <avr/sleep.h>
#include <SimpleTimer.h>

SimpleTimer timer;
const int wakeUpPin = 2; // pin of interrupt 0
const int LED = 8;
const int numMsg = 1; // For the safety, send multiple messages, everytime.
boolean armed = false;
SoftwareSerial mySerial(4,5);
String ID = "1001";
String code = "01";
String msg = "xxxx";
String rcvMsg = "xxxx";
int timerID = 0;
boolean isWaked = false;
int pulseWidth = 0;

/*
  Communication protocol
  01: powered on
  02: Sensor touched (Feed is full)
  03: alive
*/

void setup()
{
  String msg = String(ID + code);
  pinMode(wakeUpPin, INPUT_PULLUP);
  pinMode(LED, OUTPUT);
  timerID = timer.setInterval(1000, sendMsg);

  Serial.begin(9600);
  mySerial.begin(9600);
  Serial.println(msg);
  delay(100);
}

void loop() // 반복
{
  pulseWidth = pulseIn(wakeUpPin, LOW, 100000);
  Serial.println("start loop.");
  armed = true;
  delay(100);
  Serial.println("Now sleeping..");
  delay(200);
  sleepNow();

  Serial.println(pulseWidth);
  if(armed){
    Serial.println("Waked up. Send Feed full msg.");

    delay(200);
    code = "02";
    msg = String(ID + code);
    sendMsg();
    int count = 0;
    while(1){
      count++;
      if(count>200){      //prevent infinite loop
        count = 0;
        break;
      }
      Serial.print('*');
      if(mySerial.available()>0){
        Serial.println("RECEIVED!!!!");
        rcvMsg = mySerial.readStringUntil('\n');
        if(rcvMsg.substring(0,4).equals(ID)){
//          timer.deleteTimer(timerID);
          Serial.println("My msg is received successfully. Now sleep again..\n");
          break;
        }
      }
      delay(50);
    }
    armed = false;
  }
}

void wakeUpNow(){
  isWaked = true;
  return;
}

void sleepNow(){
  Serial.println("Entered sleep now()");
  delay(100);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  attachInterrupt(0,wakeUpNow, LOW);
  sleep_mode();
  // When wakes up, resume codes from here.
  sleep_disable();

  detachInterrupt(0);
  return;
}

void sendMsg(){
  for (int i=0;i<numMsg;i++){
    mySerial.println(msg);
  }
  return;
}

I'm not sure if this is a diagnostic test or an answer, because they may be roughly the same thing.  I'm guessing your testing these in close proximity.  What I'd tell you to do is put a stronger pull-up on pin 2.  Put 1kOhm (just to pick a number) from pin 2 to 5V and switch pinMode to INPUT rather than INPUT_PULLUP.  See what, if any, difference that makes.

emi/rfi choke collars/ferrite "beads" on vcc and signal wires might solve your problem in hardware. Try some from an old miniUSB cord and see if they help.

I know, it is not exactly what you asked for, but I recommend hardware filtering. I had problems with noise on interrupts and I was able to solve that with this component: https://www.st.com/content/st_com/en/products/emi-filtering-and-signal-conditioning/integrated-emi-filtering-and-esd-protection/computer-legacy-port-ipad/kbmf.html#overview
It is not expensive and saves you a lot of headache.
If you can't use SMD components, you can rebuild the circuit of that filter with capacitors and resistors, just be sure, that you put the filter as close as possible to the interrupt pin.