text:
I need help producing 2 pwm signals
My project is to use an Arduino to control two solenoid valves with PWM and receive an input signal from a sensor as feedback.

The valves direct the flow of water which cause a hydraulic actuator to move which is detected by an LVDT sensor.
What I want my program to do is to allow me to set a desired displacement as a goal which causes the Arduino to dynamically change the duty cycle of the pwm signal based off of the feedback input the Arduino receives. I am going to implement a PID to control it.
The circuit consist of the Arduino sending PWM signals to two logic level NPN mosfets to control the solenoids that are powered by 2 external 12V sources.

What I specifically need help with is how to write the part of the program that will let me produce 2 PWM signals that will allow me to change the frequency of the pwm waves so that the solenoids have enough time to switch and then also the ability to set the duty cycle.
I am a total novice programmer and its my first time working with electronics. I'm just hoping someone can point me in the right direction.

What sort of frequency do you need to run the solenoids at? If it's on the order of 10Hz, 1Hz, or slower, you might consider implementing a software PWM rather than use hardware PWM.

If you only need two PWM pins, I suggest using hardware PWM with
Timer 1. The Timer 1 library makes the process quite easy. It
supports frequencies from 0.12 Hz up to a few MHz, although the
resolution degrades above 7.8 kHz.
Compared to an interrupt-based solution, hardware PWM has less jitter
and it does not consume CPU cycles. The drawback is that you will be
limited to 2 channels operating at the same frequency, but this
doesn't seem to be an issue for your project.

I agree, for one or two signals: noting the comment in the sourcecode regarding which pins may be used. I'd also comment that it's to Paul's credit that he respects the license of predecessor code.

You can try to use my AVR_Slow_PWM Library, which can provide these following features and generate 2 independent PWM signals to any GPIO pin. Certainly only if your hardware design can correctly use PWM signals.

This library enables you to use ISR-based PWM channels on AVR-based boards, such as Mega-2560, UNO,Nano, Leonardo, etc., using AVR core to create and output PWM any GPIO pin. Because this library doesn't use the powerful purely hardware-controlled PWM with many limitations, the maximum PWM frequency is currently limited at 500Hz, which is still suitable for many real-life applications

Just out of interest: are you using digitalWrite() for your software PWM?

Yes. digitalWrite() is used whenever a change is necessary.

I've been looking at something similar to this application over the last few days, trying to prepare a skeleton project as a learning exercise for a friend with limited programming experience. While the AVR_Slow_PWM Library looks very good in principle, in practice it desperately needs a simple example generating just one or two signals: nothing clever, just minimal setup and adjustment code similar to the TimerOne library's fan example and definitely not containing any interrupt handler etc. unless this really is necessary.

Tacking on this as a belated observation more than anything else.
Since there is no indication of an accumulator on the hydraulic circuit and the two valves are working in opposition, it might be necessary to maintain both complementary PWM ratios and consistent relative phase.
The TimerOne library appears- by eye- to maintain a consistent relative phase. The AVR_Slow_PWM library definitely doesn't.
If it is /not/ necessary to apply an offset to the PWM edges to accommodate the valves having different open and close times then it might be easiest to simply change the switching sense of one of the FETs with both driven from the same PWM signal (i.e. when one sees 75% on, the other sees 75% off).
If it /is/ necessary to apply an offset then it might end up being best to manually code something in a timer interrupt handler, particularly since I am told that typical valves should operate at about 10Hz but not much faster: this eliminates most of the standard PWM libraries.


text:
Measure voltage in 14 points 0 - 60 volts (14s LiPo battery) with single ADC
I wish to measure 14S battery voltage on each cell with single ADC.
I guess I need some ADC built-in or external (I2C), voltage divider and switch chip that will allow me to select one of 14 pins to measure.
Am I correct?
Could you advice what switch chip should I use?
or Should I build that curtuit myself with 2 74HC595 and mosfets? (not sure if that will ever work)

You may want to search on the term “analog multiplexer”.

I would do it manually (but then I am a bit sadistic like that).
The circuit for one cell is pretty simple, and you just need to replicate it 14 times. A P+N pair of MOSFETs to switch a battery channel on and off, and a pair of resistors to make a voltage divider. You can keep the "lower" of the resistors common between all channels if you like to reduce the number of components and complexity, but once you have 14 channels the complexity will become pretty silly anyway.  Here's an example with just 3 channels:

simulate this circuit – Schematic created using CircuitLab
You would need to size RA|RL, RB|RL and RC|RL (etc) accordingly to get the right voltage ranges for the ADC input, and keep the output impedance low enough (<10k) for the ADC to handle it properly. You may want a couple of different load resistors (RL) for different groups of cells.
All the N-channel MOSFETs could be replaced by a 4-to-16 decoder with open-collector outputs (such as, if you can get it, the 74xx159), which would also protect against switching on multiple channels at once, which you never want to do.
Note that this arrangement gives you the voltage of the first cell, the voltage of the first two cells, the voltage of the first three cells, etc. To get the voltage of just the third cell (for example) you will need to subtract the voltage of the lower cells.

source: Stack Exchange

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

sort: votes


text:
How to power ESP32 with 230V AC
I want to power ESP32 with 230V AC and I don’t know how to do it. The requirement is that it must never overheat. What components should i use? The ESP will be in small space with no airflow. Will it be even possible?

with an AC/DC switching power supply?

What do you mean "overheat"? The ESP32 is robust microcontroller, according to the datasheet, the board can work in a temperature range of -40 to +125 degrees Celsius. Do you think that your setup will get that hot?

And regarding the power, you can just use a standard 5V Wall adapter with a  voltage regulator

I’m not experienced with changing voltage and this kind of stuff, but I expexted it to produce quite a lot of heat. Am I wrong?

Yes, it generates very low heat. It gets a bit warm during Wifi operation, but even without any airflow in a tight container it will not get damaged.

Switched mode power supplies do not generate any major heat, and if your only load is the ESP32 then good luck trying to get anything hot

@Coder9390 thanks

I would just suggest standard USB chargers. They give you 5V and are very cheap

The folks over at Random Nerd Tutorials offer a solution for this exact scenario using a HLK-PM03 Hi-Link 100-240V AC to 3.3V 1A DC converter. They add electrical and thermal fuses to mitigate some of the possible failure modes of over-temperature or over-current.
The specifications of the HLK-PM03 are here. I suspect there will be a few alternatives available that do a similar function.
My suggestion is to be hyper-aware of the safety issues of dealing with mains power, and to be realistic about your own capabilities.

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


text:
Power Arduino MKR GSM 1400 via VIN
I am working on a project with Arduino MKR 1400 GSM and I would like to power the arduino board using an external power source (https://www.reichelt.de/raspberry-pi-netzteil-5-1-v-3-0-a-usb-type-c-eu-stecker-s-rpi-ps-15w-bk-eu-p260010.html?PROVID=2788&gclid=CjwKCAjwy7CKBhBMEiwA0Eb7ah0tvjJTgi1IruE69oZEm51ONn9dgkCZK45JE1EU5hNgoXfJ1CA8NBoCJLgQAvD_BwE) via the VIN pin without an additional 3.7V battery.
I have copied the code that I am using and the board resets and restarts every time the board tries to initiate GSM connection (gsmAccess.begin(PINNUMBER) == GSM_READY). According to the documentation, this operation needs more current and the board restarts when it does not get enough current for this operation and 5V 3A power supply should be enough to power the board for cellular transmission without the need for an additional battery. However, I am not able to start GSM connection with this power source. I have cut the micro USB end and connect GND from the power source to GND on the arduino board and VCC from the power source to 5V/VIN on the arduino board. As mentioned, the board is not able to initiate the GSM connection with this set up.
I have gone through all the suggestions on the forum and I have not been able to resolve this. Could you please let me know the best way to power the arduino MKR 1400 GSM via VIN such that GSM connection is initiated.
The board works with the additional 3.7V battery (https://www.amazon.de/VinCorp-2500mAh-Stecker-Empf%C3%A4nger-Quadrocopter/dp/B0863PZPSM/ref=asc_df_B0863PZPSM/?tag=googshopde-21&linkCode=df0&hvadid=447410901006&hvpos=&hvnetw=g&hvrand=1221952135560228729&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=9044320&hvtargid=pla-925522392231&psc=1&th=1&psc=1)
Please let me know if you need more information from my side.
Please ignore the values given for the variables server and path
#include <MKRGSM.h>
#include <ArduinoHttpClient.h>
#include <ArduinoJson.h>
// PIN Number

const char PINNUMBER[]     = "";

const char GPRS_APN[]      = "";
const char GPRS_LOGIN[]    = "";
const char GPRS_PASSWORD[] = "";

GSMClient client;
GPRS gprs;
GSM gsmAccess;
String currentBarcode;

char server[] = "test.net";
char path[] = "/test";
int port = 80;

StaticJsonDocument<200> jsonBuffer;
HttpClient httpClient = HttpClient(client, server, port);
JsonObject root = jsonBuffer.to<JsonObject>();
int count = 0;

void setup() {
  Serial.begin(9600);
  boolean connected = false;
  while (!connected) {
    if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
        (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY)) {
      connected = true;
    } else {
      delay(1000);
    }
  }
}

void loop() {
  root["boxid"] = "Test";
  root["gtin"] = "Test";
  if (client.connect(server, port)) {
    postToWia(root);
    delay(1000);
  } else {
  }

  if (!client.available() && !client.connected()) {
    client.stop();
    for (;;)
      ;
  }
}

void postToWia(JsonObject& data) {
  String dataStr = "";
  serializeJson(data, dataStr);
  httpClient.beginRequest();
  httpClient.post(path);
  httpClient.sendHeader("Content-Type", "application/json");
  httpClient.sendHeader("Content-Length", dataStr.length());
  //httpClient.sendHeader("Authorization", "Bearer " + String(device_secret_key));
  httpClient.beginBody();
  httpClient.print(dataStr);
  httpClient.endRequest();

}

Do you have a multimeter? Are you able to measure the current draw on the VIN pin at the time of the GSM connection. Firstly using the battery (working scenario) then using the modified wall wart (failing scenario).

Thank you for the response, the multimeter fluctuates between 400mA and 600mA when I power the arduino using the modified wall wart (rated 5V, 3A). When I connect an additional battery (3.7V LiPo battery) to this set up, the multimeter reads 900mA and the GSM handshake is successful. Is it possible that the flow of current is regulated when powered through the VIN pin. As mentioned, I would like to remove the dependency on the battery. Please let me know if you need more information from my side.

USB C wall warts can be pretty sophisticated these days (e.g., with USB power delivery variable output). Are you sure that after chopping off the USB-C plug, that your wall wart is still making 3A available? Do you have a test load you could try it on? I >think< the RPi wall wart you referenced is an old school straight supply, but given your failure scenario it might be good to test?

The MKR 1400 GSM (https://store-usa.arduino.cc/products/arduino-mkr-gsm-1400) is specifically designed to take a higher current in the VIN pin for the scenario you describe. My suspicion is that the limitation is the modified wall wart, not the Arduino.

I have tried this with different adapters as well. I used a samsung adapter(5V, 2A), apple charger (5V, 1A) and Amoner adapter (5V, 3A) without any success.

Fiddling with this sort of problem is why I invested in a bench power supply. A handy bit of kit for testing and figuring out power requirements.

Thank you for the response, do you have any recommendation how I can achieve the required current in my setup. According to the documentation this should work however, I am not sure what I am doing wrong.

I think you are on the right track. Maybe try your Amoner adapter and again measure the current drain. Adding some pictures of your setup and the details of your measurements to your question may assist someone else to identify what’s going on .


text:
Serial Monitor in Arduino works, but other Serial Terminal work only one way
I have a Arduino code working on a Adafruit Feather STM32F405 Express, and as long as I test it with Arduino serial Monitor, everything works perfect. As I want to use a serial terminal (a C# application, or the "Terminal Br@y++") through the same COM port, then I can write my commands, there are executed (output pins send expected signal), but I don't received the serial feedback.
My Arduino code :
void setup() {
  Serial.begin(115200); // initialise USB Serial Port
  pinMode(pumpP, OUTPUT);  // Pump Pin is an output
}
void loop() {
    if (Serial.available() > 0) {
      command = Serial.readStringUntil('\n');
    }
    if (command == "do-it"){
        digitalWrite(5, HIGH);
        Serial.println("did it!");
    }
}

In my Arduino Serial Monitor, I write "do-it", and I recieved "did it!" and I can see the Pin 5 changing level.
In all serial application I could use, I can see the pin 5 changing level, but not the "did it!".
I configured Arduino as described on this Adafruit page :
https://learn.adafruit.com/adafruit-stm32f405-feather-express/arduino-ide-setup [ summary: use STM32F4 library, board number = "Adafruit Feather STM32F405", USB support = "CDC ( Generic Serial supercedes USART)", upload method = "STM32CubeProgrammer (DFU)" ]
And I connect the DFU pin to 3,3V during upload, and reset the board after it.
The worst in this story, is that at first time, it worked OK. Since a week or two, I don't get it to work again.

That sounds like a problem with the Serial Terminal programs. In the end they should exactly do the same: Connect to the COM port, configuring it and listening/sending on it.  So if they don't work, but the Arduino Serial Monitor works, that would mean that they are doing something wrong.

Check that your serial terminal program is asserting the DTR and RTS flags of the CDC/ACM port.

It "kind of work". I have to connect without RTS function, and after connection, I click on the RTS button and it works. When I connect with the RTS function on, then it does not get any message.
Seems a bit strange and not stable working thing.
Does the DTR should be actively put on/off before each expected message ? when I kept it high, it did not work (except for one or 2 messages)

Thank you @Majenko, you gave the solution :
I checked the box "RTS/CTS" in the "handschake" section of Terminal by Bray, and I got all my serial message back from the STM32.
I guess this is a common think on more that stm32?
how did you know, is that somewhere written in Arduino documentation?
for people like me who do not know what is RTS/CTS, here you are: http://www.brainboxes.com/faq/items/what-is-rts--cts-hardware-flow-control-
or not so straight-forward https://en.wikipedia.org/wiki/RS-232#RTS,_CTS,_and_RTR
Funny to figure out that this "5 pin communication" is virtualise in USB.
@Majenko: if you want to "own" the solution, I let you do write it yourself, I will set your answer as solution.

I had a similar issue on the Adafruit Feather M0 Express, which uses an ATSAMD chip, and enabling DTR (DtrEnable of the SerialPort class) in my C# program fixed the issue for me.


text:
NodeMCU with a 5V latching relay - LOW triggers relay
I am going to connect NodeMCU to a latching relay board like tis one (4 channel version): LINK
Both MCU board and relay board will be powered from the same 5V voltage regulator.
Now I have two problems to solve:
Problem 1 - logic levels
NodeMCU logic level is 3.3V and relays board works in 5V levels.
I can either use logic level converters or simple transoptors. Because I am going to attach NodeMCU to a custom PCB, I think transoptors will be simpler to solder.
Problem 2 - relay triggers with low pulse on the control pin
This relay boards works like this: every time the channel pin (T1 - T4) is connected to ground for few miliseconds - the relay flips to other state.
Here is the question: when the MCU board resets/reboots on power cycle, how do I ensure that the control pins are HIGH from the beginning? If they are not, the relay can flip randomly before my program starts and I will not know the initial state of relay.
What would be the best approch here ?

How do you ensure that the relay module is in a certain state at power-up? The linked resource says nothing concerning this.

It seems that my particular relay board is always in the same (NO) state after connecting 5V power. So there is no ambiguity at start, unless some random low-pulse is not send to control pins

Seems High Impedance won't trigger. So first set pin to HIGH, then pinMode OUTPUT.

Since ports commonly are configured as inputs at reset, you will need to add a pull-up resistor.
Then write your setup so that the pin is high before switching to output mode.
EDIT:
Some microcontrollers have internal pull-ups, that are even activated at reset, see the specific data sheet. (Thanks, Juraj. I don't know NodeMCU enough to go in details. Anyway, my answer might apply to other controllers and other loads, too.)
The value of the pull-up can be determined by the maximum input current for the relay module (or your adapting circuitry) and the respective voltages. To be sure, make it a bit smaller, for example to the next E-series value. Just an example: minimum supply voltage is 3.15V (3V minus 5%), the maximum input voltage to detect "high" is 2.4V and maximum input current is 10 µA. Then the resistor will need to be at most Rmax = (Vdd_min - Vin_max) / Iin_max = (3.15V - 2.4V) / 10 µA = 75kOhm. This value is part of the E24 series, but is can be 68kOhm that is in the E6 series.
However, it seems as if the circuit of the modules contains a simple PNP BJT, a pull-up will not work here, because the input needs to be pulled up to the supply voltage of the module. You need a level converter, this could be a simple transistor. How to design that circuit, is another issue. There are lots of information in the web how to do this.

Thanks! This seems as a solving answer!
Any hints what resistor values I should choose? What do I need to know before choosing resistors ?

esp8266 has internal pullup activated on io pins at boot

use pins 4 and 5, they are quieter during power-up than other GPIOs.


text:
Arduino crashing during serial print
I am trying to determine why my Arduino MKR NB 1500 code keeps crashing when the serial monitor is open and I look for data. I removed the string functions to prevent it from causing memory fragmentation, but does not seems to have helped.
#include <ArduinoMqttClient.h>
#include <MKRNB.h>

// Please enter your sensitive data in the Secret tab or arduino_secrets.h
// PIN Number
const char PINNUMBER[]     = "";

// MQTT Broker and Port
const char broker[] = "test.mosquitto.org"; //
int        port     = 1883;

// Pub/Sub Topics - Make it something unique since we are using a public broker
const char subscribeTopic[]  = "channel";
const char publishTopic[]  = "channel";

// To connect with SSL/TLS:
// 1) Change NBClient to NBSSLClient.
// 2) Change port value from 1883 to 8883.
// 3) Change broker value to a server with a known SSL/TLS root certificate
//    flashed in the WiFi module.

NBClient client;
GPRS gprs;
NB nbAccess;
MqttClient mqttClient(client);

int LED = 6; // Onboard LED

// Publish interval
long previousMillis = 0;
long interval = 2000;

void setup() {
    pinMode(LED_BUILTIN, OUTPUT); // Set built in LED pinMode

    //Initialize serial and wait for port to open:
    Serial.begin(9600);
    /* while (!Serial) {
        ; // wait for serial port to connect. Needed for native USB port only
    }*/

    // attempt to connect to GSM and GPRS:
    Serial.print("Attempting to connect to GSM and GPRS");
    // connection state
    bool connected = false;

    // After starting the modem with GSM.begin()
    // attach the shield to the GPRS network with the APN, login and password
    while (!connected) {
        if ((nbAccess.begin(PINNUMBER) == NB_READY) &&
                (gprs.attachGPRS() == GPRS_READY)) {
            connected = true;
        } else {
            Serial.println("Not connected");
            delay(1000);
        }
    }

    Serial.println("You're connected to the network");
    Serial.println();

    Serial.print("Attempting to connect to the MQTT broker: ");
    Serial.println(broker);

    if (!mqttClient.connect(broker, port)) {
        Serial.print("MQTT connection failed! Error code = ");
        Serial.println(mqttClient.connectError());

        while (1)
            ;
    }

    Serial.println("You're connected to the MQTT broker!");
    Serial.println();

    // set the message receive callback
    mqttClient.onMessage(onMqttMessage);

    Serial.print("Subscribing to topic: ");
    Serial.println(subscribeTopic);
    Serial.println();

    // subscribe to a topic
    mqttClient.subscribe(subscribeTopic);

    Serial.print("Waiting for messages on topic: ");
    Serial.println(subscribeTopic);
    Serial.println();
}

void loop() {
    unsigned long currentMillis = millis();

    // call poll() regularly to allow the library to receive MQTT messages and
    // send MQTT keep alives which avoids being disconnected by the broker
    mqttClient.poll();

    // Enforce Interval
    if (currentMillis - previousMillis > interval) {
        previousMillis = currentMillis;

        // Call a function that handles publishing message
        publishSensorVal();
    }
}

void publishSensorVal() {
    // read the first Analog pin
    int sensorVal = analogRead(0);
    //String speak = "The sensor val is " + String(sensorVal);
    char adc_sv[30] = { 'T', 'h', 'e', ' ', 'a', 'd', 'c', ' '' ', 'v', 'a', 'l', 'u', 'e', ' ', 'i', 's', ' ', '\0' }; //adc_step value
    // Publish our sensor value to the publish topic
    mqttClient.beginMessage(publishTopic);
    mqttClient.print(adc_sv);
    mqttClient.print(sensorVal);
    mqttClient.endMessage();
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(1400);                       // wait for a second
    digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
    delay(100);                       // wait for a second
}

void handleCommand(String cmd) {
    if (cmd == "on") {
        digitalWrite(LED, HIGH);
    } else if (cmd == "off") {
        digitalWrite(LED, LOW);
    }
}

void onMqttMessage(int messageSize) {
    // we received a message, print out the topic and contents
    Serial.println("Received a message with topic '");
    Serial.print(mqttClient.messageTopic());
    Serial.print("', length ");
    Serial.print(messageSize);
    Serial.println(" bytes:");

    // We want to read each character into a useable String
    String content = "";
    char character;

    // use the Stream interface to print the contents
    while (mqttClient.available()) {
        character = (char)mqttClient.read();
        content.concat(character);
    }

    handleCommand(content); // This function does something with our incoming string

    Serial.println(content);
    Serial.println();
    Serial.println(); // double spacing
}

The output looks as follows when it gets stuck:

I still have memory left on the arduino which should not be the reason for the crash:
Sketch uses 41676 bytes (15%) of program storage space. Maximum is 262144 bytes.
Global variables use 3456 bytes (10%) of dynamic memory, leaving 29312 bytes for local variables. Maximum is 32768 bytes.

how do you know it crashes?

it stops printing data in the serial monitor. I reopened the serial monitor even after that there was no info on it. I reset it fixes the issue.

Where exactly does it stop printing? In the middle of a message? Or inbetween messages? Btw: For defining adc_sv you don't need to set each character like an array element. char adc_sv[30] = "The adc value is "; does exactly the same and is easier to understand.

If it stops sending on the serial line, does it still blink the LED?

The devices prints complete message and then stops. Have never seen where it stopped in between printing a message on the serial monitor

Change the while (mqttClient.available()) loop where it using String.concat() function, it is likely causing heap fragmentation.

@hcheung: I am trying to send 0 to turn off the LED and 1 to turn on the LED and I modified the section to get the data in just char and the handle command to accept char but that leads to the error: ISO C++ forbids comparison between pointer and integer [-fpermissive].

here is the modified snippet:      char character;
// use the Stream interface to print the contents
while (mqttClient.available()) {
character = (char)mqttClient.read();
//content.concat(character);
}
handleCommand(character)

void handleCommand(char cmd) {
if (cmd == "1"){
digitalWrite(LED, HIGH);
}else if(cmd == "0"){
digitalWrite(LED, LOW);
}
}

For comparison of a char, it should be cmd='1', notice the difference between single quote and double quote? if you want to compare with an array or c-style string, you need to learn on how to use  functions such as 'strstr()orstrcmp()`.

{ 'T', 'h', 'e', ' ', 'a', 'd', 'c', ' '' ',  You appear to have a pair of adjacent character literals in your code.  So far as I know this isn't valid. So, you want to check your post for errors in pasting.

yeah i fixed that after I complied the code.

Maybe you can try SafeString https://www.forward.com.au/pfod/ArduinoProgramming/ArduinoStrings/index.html#stringvchar


text:
How to debug an error which occures after a long time only?
I've got an ESP32 with an CO2 sensor attached. The Arduino script I'm using is quite old and worked for sending them over LoraWAN to TTN and is stable. I added an Wifi-Client to read data more frequently when an Wifi is near. The data get send over to my server via MQTT. Now after some time the device stops sending; I think it's just a few hours working. (I used libraries)
Now my question -  how do I find the problem? I mean it has something to be the memory, doesn't it? The code is quite long so I would prefer to find the actual problem on my own - but how? My idea was to send debug messages by MQTT, hooking up a client to save all the MQTT messages so I can view the last messages the device sent. (I'm not even sure if the device fully stops or just loses connection etc). This whole thing sound like a tedious problem as I'd have to wait a few hours after every code fix I'd have implemented..
Thank for any help!

Without any detail to work with, there's not much help I can give. If your sensor is being read periodically, take out the delay so you're spamming output as quickly as possible. Hopefully, you'll get to the error more quickly that way. Remove every call to malloc() in your code - it leads to unavoidable fragmentation problems. Without more info, there's not much more I can suggest.

@Sniggerfardimungus Okay I understand that. - I'm not using malloc in my code.

@Juraj I'm using a String indeed to concat several values, then I convert this to an chart array. On every sensor refresh the string gets re-set again.

Add Serial.println(ESP.getFreeHeap()); to your sketch and monitoring the value the first step for debugging.

@wernersbacher there’s a relevant post regarding use of strings you should have a look through. https://arduino.stackexchange.com/questions/85157/using-string-instead-of-c-string-yet-another-attempt-to-touch-a-loaded-issue (Arduino strings are a bit of a rite of passage in the Arduino world - causes a lot of discussion. The referenced answers are a solid intro to the issues and resolutions)

@wernersbacher If you're doing string concatenation, you may not be allocating, but the concatenation methods are. If you're doing much of this, particularly if you're slowly growing a string over time, I'd say there is a strong possibility that you're fragmenting memory. What String library are you using and exactly what function are you using to do concatenation?

report to the server more often to make it fail sooner. I would also bet on Strings. I have some older stuff I should but never have rewritten that also hangs after a long time; I have it reboot the ESP every few hours to avoid it, and it reboots in seconds, so i never miss my 5-min reporting interval (which is why i've never gotten around to rewritting the strings)...

I'm using a String indeed to concat several values. If you using String.concat, take a look at this answer from me on how it could create the problem and how to avoid it.


text:
Use and definition of a destructor class
I created a class for TFT buttons and messages when using a Wemos 2.4 tft touch display.
In a code I use about 12 buttons (3 different screens with 4 buttons in each screen ), for example in my home control code "Main Screen" has Lights, Windows Alarms, Temperatures, and each screen below has set of others.
Since button's life expectancy is only for current screen (also in loop() since it monitor press at defined location), and each button take no little resources as show below in lib's .h file (other class with touch function are not show here), I would like to know how to create a destructor to free up space, since main resources are used in MessageTFT class.
#ifndef TFT_GUI_h
#define TFT_GUI_h

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <XPT2046_Touchscreen.h>

extern XPT2046_Touchscreen ts; /* Touch screen */
extern Adafruit_ILI9341 tft;   /* Graphics */

const uint8_t _pos_corr_factor[3] = {3, 6, 9}; /* Center text inside a box */
class MessageTFT
{
public:
  uint8_t a, b;
  int xc, yc;
  uint8_t txt_size = 1;
  uint8_t screen_rotation = 0;
  uint8_t border_thickness = 1;
  uint16_t face_color = ILI9341_GREEN;
  uint16_t border_color = ILI9341_RED;
  uint16_t txt_color = ILI9341_BLACK;

  char txt_buf[30];
  bool roundRect = false;

public:
  MessageTFT(Adafruit_ILI9341 &_tft);
  void drawMSG();
  void text(char *txt);
private:
  uint8_t _radius = 15;

private:
  void _drawFace();
  void _drawBorder();
  void _put_text();
};
#endif

I don't see anything in the button that needs cleanup on destruction. Destructors are used to clean up an instance's dynamic resources (like malloc-ed memory).

Destructors, despite their name, are not used to destroy the object. They are, instead, a "hook" that is called when the object is destroyed. Much like the "constructor" is called when the object is created - it doesn't do the creating.
A destructor is intended to "clean up" an object before it is deleted. That usually entails freeing any memory allocated at runtime (through malloc(), new, etc) by the object.
Since you don't do anything at runtime that needs to be cleaned up there is nothing for your destructor to do. All your variables are simple statically allocated memory as part of the object istelf, so those automatically get destroyed when the object is destroyed.
You can think of it as crushing a car. The seats, engine and steering wheel all get crushed without you having to worry about it. But first you want to take the dog out of the boot - you really don't want him in there when the car gets crushed, it'll get really really messy and the dog will be lost forever ... :(

Why is there a dog in the trunk of the car

@DaveNewton So it doesn't interfere with you while you're driving. It's an estate, not a sedan.

lol-whew Just wanted to make sure the doggie was ok ;)

@DaveNewton As long as you take it out of the car before crushing it, yes.

Is there a way to destroy an instance? leaving the dog out of it...

@Guy.D If you created it as a local variable (not using new and not having it static or in the global scope) then it gets destroyed when it goes out of scope. If you made it with new then you can delete it any time. If it's in the global scope then it's there forever.

@Majenko since it has to run in loop() to detect touch, it has to be global.... TNX


text:
Convert float to int error
I am trying to convert 1.06 to 106 by multiplying by 100 but the answer comes 105, I do not know why. Variable ver can be any decimal in this format x.xx
float ver = 1.06;
int vers = ver * 100;
vm[0] = (vers / 100U) % 10;
vm[1] = (vers / 10U) % 10;
vm[2] = (vers / 1U) % 10;
Serial.println(vers);

Could  you let me know what I am doing wrong or maybe I have to do something else.

1.06 is not a float. The closest float is 1.059999942779541015625. If
you multiply that by 100 you get a number that, again, is not a float.
Rounding to the nearest float yields 105.99999237060546875, which is the
result of the expression ver * 100, and just one ULP short of 106.
Yes, floating point computations do quite usually involve rounding
steps.
Casting to an int implicitly rounds towards zero, and you get 105,
which is the correct result. Correct according to the rules of IEEE 754
arithmetics.
You may want to round() to the nearest integer before the cast.

Variable ver can be any decimal in this format x.xx

No, a float cannot be “any decimal” in this format. Floats are stored
in binary, and most decimal numbers (numbers that can be written with a
finite number of decimal digits) cannot be written in binary with a
finite number of bits.
Except for a few values (namely the multiples of 0.25), ver can only
store an approximation of the decimal number.

Thanks for the answer, now it make sense.


text:
Delay() and millis() functions don't work in cpp external files
I'm currently facing an issue using delay() and millis() functions in an external cpp file.
The issue is that when I used delay() in my main program (meaning .ino file) it works well but when I call the same function in an external cpp file, I'm stuck in the delay function. Concerning the setup, the .hpp linked to the used cpp is well included in the .ino file and the librairy Arduino.h is included in my cpp. I also tried to replace delay by a loop using millis but the value returned by millis is always 0.
I'm using an Arduino mega2560 and a water level sensor in the follwing example. The Arduino IDE version is 1.8.16.
Here is an extract from my ino file:
#include <Arduino.h>
#include "DS3231.h"
#include "MyGardenClock.hpp"
#include "sensors.hpp"
#include <LiquidCrystal.h>
#include "Keypad.h"
#include <Wire.h>

///Time object creation
DS3231 clock; //Clock object -> contains basic Real Time Clock functions
RTCDateTime dt; //Struct from DS3231 lib - contains date and time
mG_RTC myClock; //Object that contains specific clock functions to my project like printing date and time on the lcd...

///LCD object creation
//--Pin allocation
const int rs = 2, en = 1, d4 = 4, d5 = 7, d6 = 8, d7 = 10;
//--LCD dynamic object creation
LiquidCrystal* pLCD = new LiquidCrystal(rs, en, d4, d5, d6, d7);

///Keypad parametrization and object creation
//Define col nb and row nb
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {52, 50, 48, 46}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {44, 42, 40, 38}; //connect to the column pinouts of the keypad
//Keypad dynamic object creation
Keypad* pKpd = new Keypad(makeKeymap(hexaKeys),rowPins,colPins,ROWS,COLS);

///Sensors object creation
//WaterLvl Sensors
//--Pin allocation
const int WtrLvlAnalogPin = 8; //pin used to read value from water lvl sensor
const int WtrLvlPowerPin = 35; //pin used to power the sensor before reading a value
//--WaterLvl dynamic object creation
Water_Lvl_Sensor* pWtrLvlSens = new Water_Lvl_Sensor(WtrLvlAnalogPin,WtrLvlPowerPin); //contains the delay and millis functions that don't work

/////////// TEST FUNCTIONS ///////////
void testLCD_Kpd(Keypad*,LiquidCrystal*); //test lcd and keypad
void testWtrLvlSens(Water_Lvl_Sensor*,LiquidCrystal*); //test water lvl sensor

void setup()
{
    Serial.begin(9600);
    pLCD->begin(16,2);
    testLCD_Kpd(pKpd,pLCD);
    testWtrLvlSens(pWtrLvlSens,pLCD);

}

void loop()
{

}
////////////////////// TEST FUNCTIONS ///////////////////////////
void testLCD_Kpd(Keypad* pKpd, LiquidCrystal* pLCD)
{
   char test;
   test ='i';

   pLCD->print("Hello");
   do
   {
    test = pKpd->waitForKey();
   }while(test=='i');
   pLCD->clear();
   delay(3000); //This one work well
   pLCD->print("test = ");
   pLCD->print(test);

}

void testWtrLvlSens(Water_Lvl_Sensor* pWLS,LiquidCrystal* plcd)
{
  int wtrLvl;
  wtrLvl = pWLS->getCurrentWaterLvlValue();
  plcd->setCursor(0,1);
  plcd->print("wtrLvl = ");
  plcd->print(wtrLvl);

}

Here is an extract from my cpp file:
#include <Arduino.h>
#include "sensors.hpp"

/********************************************
*   CLASS WATER LvL SENSOR DESCRIPTION      *
********************************************/
///Constructor
//-- Assign pin number (analog & digital)
//-- Define pinMode for VCC + set to low
//-- read and store actual waterLevelValue as initial val
Water_Lvl_Sensor::Water_Lvl_Sensor(int anPinNb, int DigPinNb)
{
  //Variable used for millis
  unsigned long prevTime;
  unsigned long currentTime;
  const unsigned long delayTime = 100;

  Serial.begin(9600); //to debug

  //Assign analog and digital pin numbers
  analogPinNumber = anPinNb;
  VCC_digitalPinNumber = DigPinNb;
  pinMode(VCC_digitalPinNumber, OUTPUT); //Digital pin to power the sensor
  digitalWrite(VCC_digitalPinNumber,HIGH);//Turn sensor ON before reading initial value

  //delay(100); //not working ???
  prevTime = millis(); //get and store actual time
  do
  {
    currentTime = millis(); //get actual time
    Serial.println(currentTime); //print actual time (debug only)
  }while(currentTime<(prevTime+delayTime)); //while time spent < 100

  currentValue = analogRead(analogPinNumber); //read analog value

  digitalWrite(VCC_digitalPinNumber,LOW); //turn sensor OFF
  historyValue = currentValue; //init history val
  minValue = 0; //default value - sensor dry
  maxValue = 520; //default value - sensor under water
}

Does anyone has a solution?
I hope I've given enough details. If not, please feel free to ask.
Thanks!

The Arduino framework does some initializing for you before going into setup() and loop(), for example configuring Timer0 correctly for millis(), delay() and siblings. This is done in the main() function, which then after the first initializing calls setup() and loop().
But the creation of globally defined objects (and thus the execution of their constructors) is done even before the main() function. At that time neither millis(), nor delay() will work, since the hardware Timer0 is needed to be configured correctly for them to work. The hardware timer generates interrupts with a specific frequency and in the corresponding ISR (Interrupt Service Routine) the variable for millis() is incremented. If the Timer0 isn't configured, it's interrupt cannot trigger and thus millis() will stay zero. So you cannot do all that in the constructor of the object, or you always need to create the object in setup() or loop().
For this very reason most hardware related Arduino libraries use a .begin() method to initialize the hardware related stuff. That function can be called on the global object in the setup() function, when everything else is already configured correctly.
What to do now? Create a .begin() method for your class. Move all the code from the constructor (except for the pin number assignment) into this .begin() function. And then call that function in setup().

Thanks a lot for your quick answer. It really makes sense, indeed.  I'll make the change and tell you if it works, but I'm confident.

Hi chrisl, just to let you know your solution works well. Thanks a lot.


text:
How do I find out the maximum current through VIN on a NodeMCU board?
I read this answer https://arduino.stackexchange.com/a/51878 to a different, but related question. It seems like VIN on the NodeMCU is directly or via diode connected to the USB connector.

Image source: https://arduino.stackexchange.com/a/76119
I'm going to run my NodeMCU with a 5 V power supply connected to the USB connector. And I also need approximately 5 V for another part. So I was thinking of connecting it to VIN of the NodeMCU. So I don't want to power the NodeMCU from VIN, but I want to draw power from VIN for another part.
Is that a bad move or perfectly fine? And if it's okay, how do I find out the maximum current? Because I think the line from USB connector to VIN has some limits, so to not damage the board?

There is some unknown quantities here. NodeMCU made a couple of versions of the ESP8266 development board we all know and love. That was well documented and schematics are available. Then the Chinese took it and cloned it changing the schematic in the process, and called it the V3.  But no one has published official schematics of it, and no one really knows how the diodes are actually connected on that board. I have just ordered one of them from Amazon to do a bit of reverse engineering on it to finally get a definitive answer.

I'll post an answer on this thread, and possibly also write a blog post on my site about it with more detail if I think it's worth it.

You cannot power items from the VIN pin of the NodeMCU V3.
The power circuit is like this:

simulate this circuit – Schematic created using CircuitLab
As you can see no current can flow out of the VIN pin because of diode D2.
You could, though, draw current out of the VU pin, though (situated at the top left of the board when the text is normally oriented) which is directly connected to the USB port's 5V pin.  How much current can you draw? Well, there's nothing in the circuit to limit it, so whatever the USB port that the board is connected to will provide (less enough to run the ESP8266 module).
If you want to draw 1A through the VU pin and the power supply is rated for 2A there should be no problem. The traces for the VU pin are reasonably chunky.
A better solution though would be to power the NodeMCU board and your external components through separate power feeds from the power supply - that way there can be no interference from the board.

Huh... First of all: thanks for looking into it. However, second of all, I don't understand how this is possible. https://i.stack.imgur.com/6NKYn.png This is exactly how my board looks like. Maybe there are different NodeMCU v3? In your schematic, shouldn't I measure 0 V on VIN because it's against the diode direction? But when I connect USB and measure from VIN to GND pins, I read 5 V. (I get 5 V as well from VU to GND, by the way.) Again, thanks for you help :)

The only way you can get power out of VIN is if the diode is faulty or installed backwards. That board is identical to the one I've torn down. I am half way through a full reverse engineering of the circuit at the moment.

Hmm, no idea what to tell you. The board is basically new, I haven't done anything with it so far. I also read 2 to 3 ohm resistance between VIN and VU in both directions. I think if there would be a diode installed like in your schematic, that also shouldn't be the case. I cannot explain my readings. Is there anything I can do? Which part would be the diode in question? Maybe I can test something there? My equipment is very limited though. :(

@rattlesnake If you have a DMM it should have a diode test mode. It should tell you the forward voltage of the diode. In one orientation it should give you abou 0.25V. In the other it should read open circuit. The diode in question is the one closest to the pins.  If you're interested the copper traces can be viewed here: https://cloud.majenko.co.uk/index.php/s/ewCn6JmYdWWglRj The two diodes are in the bottom left - you can just make out the pads in silver above the bottom left mounting hole. You can see both the diodes connecting the power to the 5V rail - the lower one going right to left...

...from the USB power, the upper going left to right from the VIN pin. From there the 5V goes to the input of the LM1117 voltage regulator.

Well, this is interesting. I do have a digital multimeter. However, it is a very cheap one. It does have a diode test program though. I have never used that before. Can I used it while the diodes are soldered onto the board? On the diode closer to VIN I read 233 in one direction and 1. in the other direction. (Not 1, but 1. which mean infinite for the resistor test program.) For the other diode closer to the edge, I measure 002 or 003 in both directions. So... no idea what that means, but it doesn't make any sense to me.

With the diode near VIN which way round are the probes when you read 233? It should be red towards the outside and black towards the inside of the board. The other diode sounds broken or short circuited. 233 sounds correct though - 233mV is about the same as I measured and is typical for a small schottky diode. If you peer closely at the diodes you should see a stripe at one end, which is the cathode (where the black probe goes for it to read right).

Yes, I can see the stripe with a magnifying lens: https://i.stack.imgur.com/5Adnr.jpg I hope the photo is good enough. I measure 233 with red left side (towards the outside) and black right side (towards the inside of the board). Isn't that what you said?

@rattlesnake Yep, that's correct. That diode is working fine. You may be measuring 5V on VIN because there's no load and it's just floating. Maybe try powering something small from it and see if it works. The other diode, though, is short circuited. Either because the diode is dead (they usually fail short) or there is a defect in the PCB.

I'm sorry to say but it seems like VIN does indeed work as an output: I connected a 10 kΩ resistor (to limit current to a minimum) and a white LED in series between VIN/VU to GND on the NodeMCU. With both VIN, as well as VU, the LED is on. The NodeMCU is powered by USB from my laptop.

@rattlesnake Maybe these diodes are dodgy pieces of spit then, as the circuit says that shouldn't work, if the diodes were behaving as they should.

Yes, I think I'm not going to look further into it at this point. :) Everything works so far. Thank you very much for your help

Oh, and by the way, reminder if you want to add your findings for the v3 NodeMCU to your previous answer that I found: https://arduino.stackexchange.com/a/51878 (I couldn't comment there because my reputation is too low.)

Just found at least a partial answer in this answer https://arduino.stackexchange.com/a/61030 to a different question:

The component that blew up is a diode. It is designed to protect the USB from voltage being injected into the board. That diode can handle an absolute maximum of 1A. (...) the ESP8266 itself can take more than half that 1A power budget when communicating.

That sounds to me that beginning at about 500 mA, I will risk damaging the NodeMCU if I use VIN as a power supply. So to play it safe, I should probably stay below 250 mA...? Just a guess though. Not a perfect answer yet.

this is what i was going to post. mind the diode; the drop and the heat. sometimes diodes burn up closed, in which case power handling goes up. Replacing or Chernobyl-ing the diode with solder will also multiply the current capabilities at the cost of usb backfeed protection.


text:
Where are source files for Due?
Where are the source files containing the definitions and the HAL functions located for the Due?
I am trying to do CMSIS programming.

There is an interesting discussion about Hardware Abstraction Layers (HAL) on Reddit’s r/Arduino. They assert that the Arduino environment as a whole is a HAL. https://www.reddit.com/r/arduino/comments/2y61su/when_would_you_start_caring_about_the_hal/?utm_source=share&utm_medium=ios_app&utm_name=iossmf

There is also an interesting discussion on the Arduino forum about getting started with the common microcontroller interface standard (CMSIS) https://forum.arduino.cc/t/anyone-using-cmsis-how-to-get-started/226150

Also there are a number of CMSIS libraries available for Arduino.

The Arduino Core for supporting Arduino Due is called ArduinoCore-Sam, which can be found at https://github.com/arduino/ArduinoCore-sam, inside the system directory, you will find the CMSIS device driver.


text:
Trying to program a Led Counter Want a Led to flash every 5 minutes however it flashes twice every second (Noob)
Heres the code i've Wrote i feel like the issue lies in how ive used the if statement
int ledPinS = 13; //Classifies pin 13 as Connected to an LED
                //Flashes every second
int ledPinM = 12; //Classifies pin 13 as Connected to an LED
                //Flashes every minuite

byte seconds;

byte minutes;

  void setup() {
   pinMode(ledPinS, OUTPUT);
   digitalWrite(ledPinS, LOW);
   pinMode(ledPinM, OUTPUT);
   digitalWrite(ledPinM, LOW);
  }

    void loop() {
     while (seconds<=59){//flash every second and reset when Seconds =59
     delay(900);
     digitalWrite(ledPinS,HIGH);
     delay(100);
     digitalWrite(ledPinS,LOW);
     seconds++;
    }
 delay(200);   // flash ledPin M Once when Seconds = 59
 digitalWrite(ledPinM,HIGH);
 delay(100);
 digitalWrite(ledPinM,LOW);
 seconds = 0;
 minutes++; // add a minute
 if(minutes=5){ // if minutes = 5 flash ledPinM twice and reset
          delay(200);
        digitalWrite(ledPinM,HIGH);
        delay(100);
        digitalWrite(ledPinM,LOW);
        delay(200);
        digitalWrite(ledPinM,HIGH);
        delay(100);
        digitalWrite(ledPinM,LOW);
        minutes = 0;
    }
}

Any Help would be Appreciated.

your code is very badly formatted ... proper indentation is very important, especially for a beginner programmer

Although your code is formatted horribly, it does appear to be mostly correct.
I also  recommend making your pin numbers "const int". This tells the compiler that they cannot be changed. Otherwise you could change those values in your code accidentally.
You also have un-initialized variables. Best practice would be to declare and initialise them at the same time. E.g.
byte seconds = 0;

Props for adding comments, though. Well done there.
You need an extra equals sign in your if statement.
if (minutes = 5) {

should be
if (minutes == 5) {

Classic mistake. We've all done it. You are assigning the value of 5 to minutes instead of checking for equality. This will always return true.

Thanks so much I know I'm very new to C++ programming you've helped me a great deal thank you.


text:
How to save sensor value in EEPROM? (ESP8266)?
I would like to save the height of a tank in case of power outage with EEPROM and every time I reboot the board. However, I could not do so after using EEPROM.commit() , EEPROM.get and EEPROM.put as the reading of the height tank changes every time I tried to reboot it . Am I using it wrongly?
I used EEPROM.get , EEPROM.put , EEPROM.commit in the void setup section so that it will save the data during boot up. However, the tank height just change whenever I changed to a different tank with different height after boot up.
How could I recalibrate the height of the tank if I would like to change to another tank one day, can I just click the RST button on the ESP8266 board?
Thank you
#include <LiquidCrystal_I2C.h>  //1602 LCD library
#include <Wire.h>
#include <EEPROM.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>  //NodeMCU ESP8266 library
#include <BlynkSimpleEsp8266.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

WidgetLED led1(V2);

char auth[] = ""; //Enter your Auth token
char ssid[] = ""; //Enter your WIFI name
char pass[] = ""; //Enter your WIFI password

BlynkTimer timer;
bool pinValue = 1;

long duration;
int distance;
int percentage;
int addr=0;
float tankheight, val;

#define trig D7
#define echo D8
#define relay D5

void setup() {
  Serial.begin(9600);
  EEPROM.begin(512);
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  pinMode(relay, OUTPUT);
  Wire.begin(D2, D1);
  lcd.init();
  lcd.backlight();
  Blynk.begin(auth, ssid, pass);
  digitalWrite(trig, LOW);
  delayMicroseconds(4);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  tankheight = duration * 0.034 / 2;
  Serial.print("Tank height");
  Serial.print(tankheight);
  EEPROM.put(addr, tankheight);
  EEPROM.commit();
  val=EEPROM.get(addr, tankheight);
  Serial.print("Addr");
  Serial.print(val);
  timer.setInterval(1L, Wlevel);
  digitalWrite(relay, HIGH);
}

BLYNK_CONNECTED(){
  Blynk.syncAll();

  }

BLYNK_WRITE(V0) {
  pinValue = param.asInt();

}

void loop() {
  Blynk.run();
  timer.run();
  WiFi.setSleepMode(WIFI_NONE_SLEEP);

}

void Wlevel(){  // Initialize detecting water level and relay)
  {
  digitalWrite(trig, LOW);
  delayMicroseconds(4);
  digitalWrite(trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  distance = duration * 0.034 / 2;
  percentage= map(distance,val,10 ,0, 100);

  Blynk.virtualWrite(V1, percentage);

  if(percentage<0)
  {
    percentage = 0;
  }
  else if(percentage>100)
  {
    percentage = 100;
  }

 }

 if (pinValue == 1)
    {
       if (percentage < 100)
       {
          digitalWrite(relay, LOW);
          Serial.print("Water level:");
          Serial.print(percentage);
          Serial.print("%");
          Serial.println(" Pump is ON");
          led1.on();
          lcd.setCursor(0,0);
          lcd.print("Water Lvl:");
          lcd.print(percentage);
          lcd.print("%  ");
          lcd.setCursor(0,1);
          lcd.print("Pump: ON  (AUTO)");

       }

       else
       {
          digitalWrite(relay, HIGH);
          Serial.println("Water level is 100%   Pump is OFF");
          led1.off();
          lcd.setCursor(0, 0);
          lcd.print("Water Lvl:");
          lcd.print(percentage);
          lcd.print("%  ");
          lcd.setCursor(0,1);
          lcd.print("Pump: OFF (AUTO)");

       }
    }
   else
    {
      digitalWrite(relay, HIGH);
      Serial.print("Water level:");
      Serial.print(percentage);
      Serial.print("%");
      Serial.println("System is OFF, Check Blynk");
      lcd.setCursor(0,0);
      lcd.print("Water Lvl:");
      lcd.print(percentage);
      lcd.print("%  ");
      lcd.setCursor(0,1);
      lcd.print("System is OFF   ");
      led1.off();

    }

   }

have you actually examined your own program? ... what's the point of using the EEPROM when first thing you do is to wipe out the stored value ?

@jsotola I am a beginner to programming and I am trying very hard. Which part of the code that will wipe out the stored value? I thought I put the EEPROM command in the void setup so that the tank height will be put inside the EEPROM? Am I doing it wrongly?

take a look at all program lines that start with EEPROM ... see what each one does

why do you want to save the water level?

@jsotola
I would like to save the tank height at the start so that whenever there is a power outage, the tank height will not erase on itself after reboot.
From the code, I first put the tank height into addr using EEPROM.put and then save it using EEPROM.commit. After that, I read it again and put into "val".
Down below I also wrote "percentage= map(distance,val,10 ,0, 100);" , the val should be the saved tank height and the 10 is the distance from the ultrasonic sensor to maximum water height.

and you do not see a problem with first saving the water level after reboot? ... think about it ... this really has nothing to do with programming

Use a different button - you may have to wire something up...
In the loop, read the button and only if it is pressed should you re-calibrate and set the value to eeprom.  You can do it in setup too but then you would have to reboot with the button pressed to trigger re-calibration.
You can also read a serial command in the loop.  Anything external that can be triggered with a separate intent to re-calibrate would work.  A power outage resembles the normal reset too much.  To execute different behavior in two different scenarios, you must be able to detect which scenario you are in.

How about if I add an virtual button in the Blynk apps so that I can calibrate it using the Blynk app instead a physical button? Regarding the calibration and EEPROM, am I supposed to create another loop in another function or inside the void setup function is enough ? Thank you

virtual button could work.  if there is some gui in the Blynk apps, then your call to write eeprom belongs in something called by Blynk.run() (which your loop function calls) not setup.


text:
1.) How do I delay a servo motor from turning in a loop? 2.) How do I make a servo motor's change in position dependent on temperature?
I'm super new to the c++ programming world (currently taking the class now) and I'm in need of some assistance with some coding that's way beyond my knowledge at the moment. I have to write a code for Arduino interfacing with servo motor, ezButton, water-proof sensor and ada fruit motor shield.
the project entails building a moveable arm that holds a hot metal post that needs to be submerged into water for cleaning, BUT before it can be submerged I need to give the metal time to cool so it doesn't fracture. (Question 1, how do I delay the servo motor from moving to allow the metal to cool.) After the metal is submerged for cleaning, the servo motor needs to move back to the starting position ONLY if the temperature is less than 50 degrees Celsius. (Question 2, how do I make the servo motor dependent on temperature.)

#include <OneWire.h>
#include <DallasTemperature.h>
#include <AFMotor.h>
#include <Servo.h>
#include <ezButton.h>

#define ONE_WIRE_BUS 2
#define LOOP_STATE_STOPPED 0
#define LOOP_STATE_STARTED 1

OneWire oneWire (ONE_WIRE_BUS);
DallasTemperature sensors (&oneWire);

ezButton button(7);
int loopState = LOOP_STATE_STOPPED;

Servo name_servo;
int servo_position = 0;
int Celsius = 0;

void setup() {
  sensors.begin();
  Serial.begin(9600);
  name_servo.attach (10);

  button.setDebounceTime(50);
 }

void loop() {
  button.loop();

if (button.isPressed()) {
    if (loopState == LOOP_STATE_STOPPED)
      loopState = LOOP_STATE_STARTED;
    else // if(loopState == LOOP_STATE_STARTED)
      loopState = LOOP_STATE_STOPPED;
  }

if (loopState == LOOP_STATE_STARTED) {
    sensors.requestTemperatures();
    Celsius = sensors.getTempCByIndex(0);
    Serial.print(Celsius);
    Serial.print(" C  ");
    delay(1000);

//ADD COOLING PERIOD (3min)

  for (servo_position = 0; servo_position <=180; servo_position +=1){
      name_servo.write(servo_position);
      delay(10);
      ;
   }

// ADD CONDITIONAL STATEMENT (if temp < 50, motor returns from 180 to 0)

  for (servo_position=180; servo_position >= 0; servo_position -=1){
      name_servo.write(servo_position);
      delay(10);

    }
  }
}

how do I delay the servo motor from moving to allow the metal to cool ... press the button when the metal is cool

@jsotola yes that true but, The project is supposed to be a push button operation that you can walk away from after loading in the metal post. I guess the key is efficiently, the operator can go finish/do other tasks while this program is running

do this with pencil and paper ... write down in great detail how the program should behave ... if the description is very detailed, then it will translate into code almost directly

write a simple state machine ... use flags to interface the button and the temperature sensor to the servo control code ... all code would be in loop() ... do something like this read remperature ... if below 50 then dipDone = true ... if below 100 then okToDip = true .... read button ... if pressed then doDip = true ....... next comes the logic that controls the servo ... if doDip and okToDip and notDippingAlready then start servo ... etc. etc.


text:
How Arduino IDE work with ESP32?
I understand how compiler compile our code to make binary code. Then we can use avr gcc to upload bin code to atmega chips via programer (USB ISP) or via USB serial (required bootloader).
I'm using ESP32 for a while and notice they work in difference way. As far as I know

It  not required Arduino  bootloader.
It not reset when re-open serial monitor.
It use external memory chip.
It have boot and reset button
The USB Serial connect to ESP32 and we can upload bin code with it. (maybe the only way)
In IDE it run python scrip (esptool.py)
I wonder how the process going and how each element work for its part for completely understand the process.

avr gcc is the compiler ... it does not do the code upload

Arduino IDE is one possible way of getting code onto the ESP32. There’s lots of info available about using Arduino IDE with ESP32 (e.g., https://randomnerdtutorials.com/installing-the-esp32-board-in-arduino-ide-windows-instructions/). There are also other IDEs that will work see https://randomnerdtutorials.com/getting-started-with-esp32/ for a list.

@RowanP That one confuse me. so with one bootloader  esp32 can work with all environment??? or the system not required bootloader at all???

@Mlab Explaining that’s beyond my expertise. I know that it uses a boot loader, and that it’s compatible with several environments. I’ll pass the baton to someone with deeper expertise.

Its more like the programming environments/IDEs are made compatible with the bootloaders (not other way round). For the Arduino IDE you need to install the ESP32 core, which includes the upload tool for its bootloader, making the Arduino IDE compatible with the bootloader of the ESP32. There are many other IDEs, which can be made compatible. I think only the native ESP IDE from Espressif is specifically made for ESPs

The ESP32 has a bootloader that uses serial embedded in its internal ROM. Whether that bootloader runs or not depends on the state of certain IO pins when the ESP32 starts up.
Those states are controlled by a small circuit that is triggered by the serial control lines (DTR and RTS).
On the Arduino there isn't that requirement, and the bootloader always runs when the chip resets, so a much simpler circuit is used to trigger a reset using just the DTR signal.
So for an Arduino whenever the serial port is opened the DTR signal resets the board. But for the ESP32 the RTS signal also has to be asserted along with the DTR signal in the right sequence to both set the correct IO pins and to reset the chip.
Whether the target device has internal flash or an external flash chip makes no difference. It is the bootloader's job to get the data into that flash. The AVR chips have a way of interfacing with the internal flash (ISP) to program it without a bootloader, but the ESP32, as it has external flash, doesn't need that (you can interface directly with the flash chip if you so wish).
The software on the PC that communicates with the bootloader has to speak the "language" the bootloader expects. Each family of chips has its own bootloader (some don't even have a bootloader, but that's another story) which speaks its own language. On the AVR chips that's usually a variant of the STK500 protocol, and the program avrdude is what communicates with it to send the program to flash. On the ESP32 (and the ESP8266 too) it's esptool.py that does the job. On chipKIT boards it's pic32prog. On Digipark it's micronucleus. There's as many upload programs as there are families of boards. Some programs, like avrdude and pic32prog are more flexible and can also talk to hardware programmers (USBASP, PICkit2 etc), but in general the upload program is written specifically for a particular bootloader.

So all ESP32 have build-in bootloader right? means I don't need to re-install it ever? I never see someone done that before

@Mlab That is correct. It is getting more common to have a bootloader in ROM instead of (or as well as) having a hardware programming interface. The Arduino Due also has its bootloader in ROM, as do many other high-end ARM chips. It's common to have the bootloader operate in multiple modes, including booting off SD card (like the Pi does) depending on settings on certain IO pins.

That really anewer my question. I just self learner. By missing that information make my life a hard time figured out how things work. Thank to you.


text:
Can I use an arduino as an interface to pass files between a device and a PC?
Or maybe you guys can point me towards another direction...
You may ask, why not connect the device directly to the PC?
Well, the device is designed to recognize only USB sticks, and dump the data into them, so I cannot just plug my PC into it and retrieve the data (as far as I know...), because the PC acts as a USB host (I think).
So I thought about using an arduino and make it act as a USB stick, and then pass the data from the arduino to the PC.
Is this possible? Or maybe what I need is a raspberry pi?
Every suggestion is welcomed. Thank you in advance!

use an SD-USB adapter and an arduino sd card reader module, and of course an sd card.

Please post answers in the answers section. I don't know if your "answer"
is correct but I can't vote it down as it isn't an answer.

To do what you suggest you'd really need a microcontroller with two native USB interfaces. I only know of one family like that off hand (the PIC32MK series), and that doesn't have an Arduino core available for it yet (as I haven't had time to add support to chipKIT).

You have a device that saves information to a USB stick, is that right? Like a scanner or some sort of temperature logger?
To emulate a USB stick would be quite a task, because what you would have to do is pretend that you have a file system, as your device will be opening files, writing to them, and closing them.
It sounds like a lot of work - it might be easier to get another device that actually logs to something like a serial port.
Having said that, it seems on the face of it to be a reasonable request. Just as an example, I have a scanner that writes to a USB stick. It would be handy to have it send files directly to my PC without having to move the USB stick around all the time.
See Make a computer act as a virtual USB device for other equipments as an example of a similar question, with answers suggesting that it might be possible, for example USB-USB cables.
Even if you got it to work, it might be tedious to use. For instance, if your gadget appends to some file on what it thinks is a USB stick you would have to emulate that file system, and then check on your PC if the file has got larger, and thus have new data on it.
Plus possibly the expense (and time) involved in getting this working might be more than just getting another gadget that actually logs via some sort of port, like serial or RS485.


text:
Is there an Apple Silicon (M1) driver for CH34x devices?
I just migrated to a new computer running on an M1 CPU (the new Apple Silicon, arm64 based). I've been searching for CH34x drivers for my TTGO-Lora32 board, but can't find any around, nor can I find mentions of them existing or not. The x86_64 driver installs, but obviously can't run due to it being an incompatible architecture.
Thus, is it currently possible to use a CH34x based board on an M1 Mac?

Turns out there is such driver, but it hasn't been listed yet on the WCH website. I've posted it down below in a new answer.

It isn't working for me on Monterey. I've tried all the versions installing and uninstalling. It simply doesn't work. No idea why.

As it turns out, I found in the following post:
https://github.com/LilyGO/LILYGO-T-OI/issues/3#issuecomment-907645945
a link to a particular build of the CH340 drivers that is properly signed and can be installed on the M1 mac with no troubles.

Nice find. Now if only it were listed officially on the CH340 website so people could actually find it. Maybe now it's here it may get more attention from GoogleBot...

So they pushed a new version to GitHub late september:
https://github.com/WCHSoftGroup/ch34xser_macos
This should be the maintained version ahead of what they offer as a download on the official website.
Common other issues:

When reinstalling, make sure to first remove all old files:

sudo rm –rf /var/db/receipts/*CH34xVCPDriver*.*
sudo rm -rf /Library/Extensions/CH34xVCPDriver.kext

also don't forget to check for any related files in /dev/ and the .app file in your applications folder if these already exist.

Restart the device before reinstalling.

Restart the device after installation.

Try a different USB-Cable / USB-Hub.

Note: steps listed here were reportedly solutions I came across during my research which worked for other people and my colleagues. For me it still doesn't work; but I am using a lot of unstable builds for my OS and other software that might interfere.
Update February 2022: Now with Monterey out of closed Beta this works like a charm for me. At least for the Web IDE.

The installer is still requiring Rosetta 2, which makes me worried about the implementation of the driver. Although it might work, it is probably not written for M1 silicon.

After hours of mindless reinstalling of the drivers on M1, reboots and other magic tricks, I almost decided to switch to windows to make my arduino ide work. My NodeMCU board with CH340G would either show up as a serial port or not.
So I leave this message here as clearly many people struggling with M1 end up on this page: buy good microUSB cable. And I mean a good one. All problems disappeared right away. I had three cables at home but none was working - clearly most are only good for charging the phone, but suck at data transfer.

Indeed! In my experience, microUSB cables are the most likely to not work as expected.

✅ I can attest to this: you need a "data" cable not just a "charging cable". I tried 2 different cables that are just for charging, then I got a data cable and it worked immediately.

Big true, I just grab another microUSB cable and all works smoothly. cu.usbserial-210 port appeared right away.

Worth the try. The .pkg file from here worked in my High Sierra. I've turned-on the "csrutil enable" before install, and it still worked...:
https://github.com/WCHSoftGroup/ch34xser_macos

High Sierra is not compatible with M1 macs


text:
Obfuscate string with on SAMD21
I'am looking for a way to obfuscate string at compile time on my personal board build with an SAMD21, i'am using Arduino IDE to compile and upload code. All solution I've found like this one for example doesn't work with Arduino IDE beceause it's for c++14 (using constexpr doesn't compile) is there a solution working for Arduino?

Arduino can use even c++17 https://forum.arduino.cc/t/c-14/633553


text:
I'm getting really unstable analog values with my B103348 joystick
I'm trying to make my B103348 joystick control a DC motor but I'm getting very unstable values from it specifically when the y axis is at 0. This is what my Serial monitor shows...

0,
21,
21,
21,
0,
22,
23,
21,
21...

This is the wiring...

And here's the code...
int y_pin = A0;
int y_val;

int in_1 = 3;
int in_2 = 4;
int clock_wise_speed;
int counter_clock_wise_speed;

int en = 2;

int dt = 500;

void setup() {
pinMode(y_pin, INPUT);

pinMode(en, OUTPUT);
pinMode(in_1, OUTPUT);
pinMode(in_2, OUTPUT);

Serial.begin(2000000);
}

void loop() {
  //Clock wise = in_1 LOW and in_2 HIGH.
  //Counter clock wise = in_1 HIGH and in_2 LOW.
  y_val = analogRead(y_pin);
  clock_wise_speed = .21994 * y_val;
  counter_clock_wise_speed = 90;

  if(y_val >= 506){
    analogWrite(en, clock_wise_speed);
    digitalWrite(in_1, LOW);
    digitalWrite(in_2, HIGH);
  }

  if(y_val >= 501 and y_val <= 505){
    digitalWrite(en, LOW);
  }

  if(y_val <= 500){
    analogWrite(en, 225);
    digitalWrite(in_1, HIGH);
    digitalWrite(in_2, LOW);
  }

Serial.println(y_val);
delay(dt);
}

Thanks in advance.

what's your question?

do you honestly believe that the picture shows clearly where each wire is connected? ... please draw a wiring diagram

"specifically when the y axis" If this is meant to imply that it behaves differently when wired to the x-axis, that should probably be spelled out.  Not being able to actually see the joystick or know its model, the distinction seems otherwise fairly meaningless.

@jsotola Is there a free software I can use to make a schematic for it?

If nothing else, you can hand draw it.  It doesn't have to be professional; just readable.  You could also retake your picture under good light, e.g. near a window during the day.

How stable to you need the values to be? You’re dealing with analog-to-digital conversion which will always bring some noise. If you need values that change less abruptly, run the raw analogRead() values through a filter (for example a simple moving average filter).

Personally I've used Express PCB for free schematics. However you could just sketch out on a bit of paper how you wired up the joystick. I would test without what looks like a motor in your photo - that might be influencing things.

Could you try a sketch that does nothing other than Serial.println(analogRead(A0)); delay(500);?

There is a video which appears to be about your joystick. Can you perhaps try what is suggested there and report what happens?

21/1023 possible readings is only 2%, perhaps that is normal for this joystick.

There is a schematic editor built into this website. Just edit your question and click the schematic button at the top of the editor.


text:
How to know if GPS module is dead?
I can't make function the NEO-6M-0-001 GPS module, this is the third one that already bought! I'm using an ATmega2560 as microcontroller for obtaining the data from the module and seems that the module never initializes.
I bought an USB-UART converter for checking if there is something that I did wrong (soldering, bad wiring, burned circuit, etc.). I connected the the module to the converter, opened the serial monitor to see what is happening and this is what I found:
$GPRMC,,V,,,,,,,,,,N*53
$GPVTG,,,,,,,,,N*30
$GPGGA,,,,,,0,00,99.99,,,,,,*48
$GPGSA,A,1,,,,,,,,,,,,,99.99,99.99,99.99*30
$GPGSV,4,1,15,02,,,23,05,,,23,07,,,21,12,,,22*78
$GPGSV,4,2,15,13,,,22,16,,,22,17,,,23,18,,,22*70
$GPGSV,4,3,15,19,,,22,20,,,22,21,,,22,24,,,22*74
$GPGSV,4,4,15,26,,,22,27,,,22,50,,,27*7C
$GPGLL,,,,,,V,N*64

Seems that the data is missing, or I have to some how initialize the module. This is happening with the three modules. In the picture you can see the antenna that I'm using, I'm outdoors testing it. By the way, its true that without antenna the gps could be damaged?

I really appreciate if someone could help, thank you.

Are you indoors? Do you have a suitable antenna attached? It can take a long time to connect to the satellites, so you need to be patient.

I went outdoors, I'm attaching a picture of the antenna. Its true that I did'n  wait so much.

This is pretty much what Majenko is saying, but just to be more explicit: Empty fields are normal for not having acquired a fix.

@timemage I went outside and I'm getting nothing, the quantity of satellites changes from 1 to 10 without getting a fix. Maybe something wrong at hardware level?

If it difficult to say. Just to warn you, without some fairly Arduino specific stuff in the question it's liable to get closed, although I'm not sure where the right place to ask it is. Thoughts are: make sure the power going to the GPS is clean. I'm don't know (or remember really) what all of the ramifications of that number going to 10 are.  I know you only need 3 for a 2D fix, but I've seen GPS report quite a pile of satellites before getting a proper fix.  If you have at least three for a two or three minutes solid, then I'd worry more.

to reiterate what's already been said, you need good visibility of the sky to get a strong signal and it can take a long time to get a fix especially with a weak signal

You are probably not waiting long enough. It can take a good 15 minutes for a satellite to send all its orbit data that the module needs to triangulate its position. So that's your wait time you need to account for. Your phone cheats by going online and downloading that data from an online database.

"Trilaterate", I think.  It can take while to download WAAS information, to get a good fix. I can't remember the last time, if ever, I saw a GPS take anything like 15 minutes to get an initial crude (within 50 meters or so) fix outside.  It seems like if you don't get one within about 3 minutes, you're just not going to.

I’m voting to close this question because its not about Arduino but about a GPS module

Well, I waited. Like 1 hour with every single GPS module. I have 2 conclusions: I'm in the wrong place (even though I went outside and is clear), or the GPS modules are obsolete by now and I have to buy newer versions. Thank you all by your help!

You are getting correctly formed NMEA sentences from the GPS module, so it looks like it is working ok. The $GPGGA sentence says: no fix and zero satellites. An uncovered place outside (no trees) should be sufficient. So it looks like an antenna problem.


text:
I2C 16x2 LCD - Will Initialize (sometimes) - Holds Up The Code
Basically I have a keypad, that when a certain code is entered, it will write either "Wrong code" or "Good code" on the LCD.
At the same time a timer will count down until 0 is reached, in which case the whole LCD will display something (undecided/irrelevant).
I have tested the keypad module/part of the file, and it works exactly as expected. Each loop is entered correctly, and I have tested this part several times.
The problem, I believe, lies with the LCD. It will initialize, i.e It will display
"Time:
Code:"
But then, what comes after feels like it is randomly decided.
Sometimes I can press 1 button, and it will be printed to the serial. Other times I can press more. Sometimes it will lag for every button press, sometimes it will only be the first button press that is slow.
Secondly, if I try to re-run the script nothing will happen. I have another script (see the 2nd code,) that will usually do the trick.
But all of this takes forever. My code is suppossed to run independently, such that I can play multiple code games, will this obstruct it? Any ways to fix it?
Main code:
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>

//LCD Setup
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

//Keypad Setting

  char resetTrigger = '*';

//KeypadCodes

  String goodCode1 = "3569";
  String goodCode2 = "69696969";
  String enteredCode = "";
  //Len has to be declared before the "checker" loop
  int len = enteredCode.length();

const byte ROWS = 4; /* four rows */
const byte COLS = 4; /* four columns */
/* define the symbols on the buttons of the keypads */
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {10, 9, 8, 7}; /* connect to the row pinouts of the keypad */
byte colPins[COLS] = {6, 5, 4, 3}; /* connect to the column pinouts of the keypad */

/* initialize an instance of class NewKeypad */
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

void setup(){
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.clear();
//Sets "Timer: " in the top and "Code: " in the bottom
lcd.setCursor(0,0);
lcd.print("Time:");
lcd.setCursor(0,1);
lcd.print("Code: ");
}

void loop(){
  char customKey = customKeypad.getKey();
  len = enteredCode.length();

  if (customKey){
    //Reset Trigger
  if (customKey == resetTrigger){
    //LCD clear code
    enteredCode = "";
    Serial.println(enteredCode);
    Serial.println("Reset trigger");
    len = enteredCode.length();
  }

  //Char added to code
  else{
    enteredCode.concat(customKey);
    Serial.println(enteredCode);
    Serial.println("Char added to code");
    lcd.setCursor(5,1);
    lcd.print(enteredCode);
    len = enteredCode.length();
  }
    //Correct code
  if ((enteredCode == goodCode1) or (enteredCode == goodCode2)){
    //LCD Correct Code
    //Good sound
    //Door open
    lcd.setCursor(2,0);
    lcd.print("Correct code");
    delay(1);
    Serial.println("Correct code");
  }
  //Wrong code
  if ((len==8) && (enteredCode != goodCode1) && (enteredCode != goodCode2)){
    //LCD clear code
    //Bad sound
    enteredCode = "";
    Serial.println(enteredCode);
    Serial.println("Wrong code");
    //Changes the LCD to wrong code, waits 2 secs and then back to code
    lcd.setCursor(2,0);
    lcd.print("Wrong code!");
    len = 0;
    delay(2);
    lcd.setCursor(2,0);
    lcd.print("Code:");
  }}

}

2nd code (reset code):
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd
  // Print a message to the LCD.
  lcd.backlight();
  lcd.clear();
}

void loop()
{
}

EDIT:
So now it will work more regularly after changing it from (LiquidCrystal_I2C lcd(0x27,16,2)) -> LiquidCrystal_I2C lcd(0x27,20,4).
I am still having problems with it though.
I have noticed, that sometimes it won't update the screen unless I physically nudge the LCD-screen, which is weird.
Also if it runs for "too long," the screen will stop updating at all.
Maybe a hardware issue?

If nudging helps, it is a clear sign of a hardware issue. Check your wiring and make sure you have a certain quality of components.


text:
Extract Static Acceleration from MPU6050 using Formula
I am trying to implement a research paper for my project and there is a formula which I am failing to interpret:

According to the research paper, we extract the static acceleration component for each axis µ, (i=X, Y, Z) by using a running mean filter (the formula), where t is time index, win_size is the window size, and ,∗ is the acceleration data, respectively.
The research paper using MPU6050 to implement this formula. My question is how do I calculate these values using MPU6050. I am currently using MPU6050_Light.h library to calculate acceleration values and I have no idea where to move from here.
Help would be greatly appreciated.

You could change the limits to 0 to win_size - 1 so that they are compatible with C arrays. Then cycle around the array putting a new float into it at the current index while updating the sum and rolling average. Then update the index.

Are you asking about how to read the acceleration from the MPU6050? Or are you asking about how to compute a running average?

@EdgarBonet, Thank You for your reply. You have nudged me in the right direction by telling me about running average. I didn't know that this formula was of calculating running average since nothing was mentioned in the research paper.


text:
How to control multiple servo motors simultaneously using protothreading?
So I'm trying to control 4 servo motors simultaneously using the Protothreads library by Ben Artin, but I am starting with 2 just to see if it works.
I have succeeded in getting two LEDs to blink at the same time but at different frequencies.
When I try to connect the 2 servo motors using exactly the same technique as the LEDs to get them to sweep simultaneously, they don't work together. Only one works.
Below is the code I am using:
#include <protothreads.h>
#include <Servo.h>

Servo myservo1;
Servo myservo2;

int pos1 = 0;
int pos2 = 0;

////////////////////////     T H R E A D    1     /////////////////////////

pt ptServo1;
int servoThread1(struct pt* pt) {
  PT_BEGIN(pt);
  for(;;) {
    for (pos1 = 0; pos1 <= 180; pos1 += 1) {
      // in steps of 1 degree
      myservo1.write(pos1);
      delay(2);
    }
    delay(500);
    for (pos1 = 180; pos1 >= 0; pos1 -= 1) {
      myservo1.write(pos1);
      delay(2);
    }
    delay(500);
  }
  PT_END(pt);
}

////////////////////////     T H R E A D    2     /////////////////////////
pt ptServo2;
int servoThread2(struct pt* pt) {
  PT_BEGIN(pt);
  for(;;) {
    for (pos2 = 0; pos2 <= 180; pos2 += 1) {
      // in steps of 1 degree
      myservo2.write(pos2);
      delay(2);
    }
    delay(500);
    for (pos2 = 180; pos2 >= 0; pos2 -= 1) {
      myservo2.write(pos2);
      delay(2);
    }
    delay(500);
  }
  PT_END(pt);
}

void setup() {
  myservo1.attach(9);
  myservo2.attach(6);
}

void loop() {
  PT_SCHEDULE(servoThread2(&ptServo2));
  PT_SCHEDULE(servoThread1(&ptServo1));
}

In the loop() function, whichever thread is called first, that's the servo that sweeps. The second servo does not do anything at all.
Any help would be greatly appreciated!
Thank you so much,
H

You must use PT_SLEEP not delay to allow your threads to co-exist. That's what the examples use, so why did you decide not to?

@Majenko Thank you, yes that has indeed solved my first problem....I have another problem which I will post in another question. Thank you so much, please have a look at that also if you can! Thank you so much :)


text:
How to control multiple servo motors at the same time with protothreading using an I2C PCA9685 PWM board?
I'm trying to use protothreading to control two (and eventually four) servo motors over I2C using a PCA9685 PWM board.
To start, I am simply trying to sweep the two motors back and fourth at the same time.
Here is the code I am using:
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#include <protothreads.h>

#define SERVOMIN  150
#define SERVOMAX  600
#define USMIN  600
#define USMAX  2400
#define SERVO_FREQ 50

int servo1 = 0;
int servo2 = 4;

////////////////////////     T H R E A D    1     /////////////////////////

pt ptServo1;
int Servo1Thread(struct pt* pt){
  PT_BEGIN(pt);
  for(;;){
    for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
      pwm.writeMicroseconds(servo1, microsec);
    }
    PT_SLEEP(pt, 500);
    for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
      pwm.writeMicroseconds(servo1, microsec);
    }
    PT_SLEEP(pt, 500);
  }
  PT_END(pt);
}

////////////////////////     T H R E A D    2     /////////////////////////

pt ptServo2;
int Servo2Thread(struct pt* pt){
  PT_BEGIN(pt);
  for(;;){
    for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
      pwm.writeMicroseconds(servo2, microsec);
    }
    PT_SLEEP(pt, 500);
    for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
      pwm.writeMicroseconds(servo2, microsec);
    }
    PT_SLEEP(pt, 500);
  }
  PT_END(pt);
}

////////////////////////////////////////////////////////////////////////////

void setup() {
  Serial.begin(9600);
  PT_INIT(&ptServo1);
  PT_INIT(&ptServo2);
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates
}

void loop() {
  PT_SCHEDULE(Servo1Thread(&ptServo1));
  PT_SCHEDULE(Servo2Thread(&ptServo2));
}

I am noticing that Servo 1 turns to -90 and stops. While it has stopped, Servo 2 turns to -90 and then stops....then Servo 1 turns to +90 and stops and so on. They are not doing the sweeping at the same time.
Any help would be greatly appreciated!
Thank you,
H

Without knowing Protothread in detail: It is most likely handling the threadchange during PT_SLEEP(), which you are only executing after one "sweep" (one of the inner for loops), not giving any opportunity to change to the other thread.
Additionally this way you don't have any delay in the inner for loops, thus they get executed very fast. Faster than the motor really can follow. This means, that the servo just moves to the end position as fast as it can and the for loop is essentially useless. You need a delay inside the inner for loops for slowing the signal down.
Please try something like this:
pt ptServo1;
int Servo1Thread(struct pt* pt){
  PT_BEGIN(pt);
  for(;;){
    for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
      pwm.writeMicroseconds(servo1, microsec);
      PT_SLEEP(pt, 50);
    }
    PT_SLEEP(pt, 500);
    for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
      pwm.writeMicroseconds(servo1, microsec);
      PT_SLEEP(pt, 50);
    }
    PT_SLEEP(pt, 500);
  }
  PT_END(pt);
}

Change the sleep time in the inner loop according to your wanted sweep speed.

Thank you for your answer! Curiously, once I add PT_SLEEP(pt,50) inside the for loop as you suggested, nothing happens. The motors do not move at all...is it possible that protothreading does not work with I2c perhaps?

You might have to make the sleep time significantly lower (havent registered before that you write the microsecond range from 600 to 2400 with step size of 1) or increase the step size from 1 to a higher number. With the current setting it might just take too long to notice the movement


text:
Mini Arducam module camera shield - 2MP ov2640 interface with Arduino Uno
MINI ARDUCAM MODULE CAMERA SHIELD - 2MP OV2640
Arducam Multi-camera adapter board for Arduino SPI Mini Camera
I have the above two components with me along with ARDUINO UNO R3.
I want to stream video using these. ARDUCAM provides library for this.
ARDUCAM LIBRARY
ARDUCAM DATASHEET
When I have chosen example program ArduCAM_Shield_V2_Video_Streaming and tried uploading it to Arduino it showed no ArduCAM.h: No such file or directory.

I have downloaded the library and kept it in the libraries folder of ARDUINO.
Can someone help me out with this??

what's the picture with the horizontal orange bar? ... difficult to see

how are you going to stream video from the arduino?

did you install the library?

The error message in the image (”ArduCAM.h: no such file or directory”) can only mean that the library hasn’t been installed correctly.

As Nick Gammon wrote: There is no way, that you are sending video with an Uno. Its just not up to the task

https://www.youtube.com/watch?v=07UwmbeFCZQ

Please refer this YouTube Video

The Uno which you mention has 2 KB of RAM. 2 MP of data would be 2,000,000 x 3 bytes (red, green, and blue), in other words 6 MB.
The screenshot you showed seems to show that the library is designed to take a still photo and buffer it. As you might imagine, buffering 6 MB would take a while, especially as you can only fit 2 KB at a time.
You simply won't be streaming video using the Uno, so the error message is more-or-less irrelevant.
It might be relevant if you actually wanted to take single photos and send them.
In that case, you probably haven't installed the library properly.

https://www.youtube.com/watch?v=07UwmbeFCZQ

Please refer the YouTube Video above...

Yeah, OK. I can't see the resolution but that looks like a whole series of stills at about 1 frame per second. I suppose you can call that "streaming video" if you want to have a security camera taking photos of a room in your house. I assumed by "video" you meant what most people would call video, namely around 24 FPS or more.


text:
SIM808 does not support SSL related AT commands

I am using a SIM808 module. It's working fine with normal MQTT over TCP, but does not work when trying secured MQTT.

I sent AT+SSLSETROOT="C:\USER\HENRY_SSL.CRT" to set the root certificate (see this document: "SIM800 Series_MQTT_Application Note_V1.03"). The response I'm getting from the GSM is: +CME ERROR: unknown.

When I try AT+SMSSL=1, I get the same error. I checked with HTTP commands and it's working fine, but the AT+HTTPSSL=1 command does not work. The SIM808 does not respond to SSL related commands.

But as per the Simcom website, the SIM808 does support SSL. Do I need to upgrade any firmware?

could you send me that firmware version (1418B05SIM808M32)? or could you tell me the site that you download it?
Also, is there any newer firmware now?

I updated the firmware version: 1418B05SIM808M32. Now all commands are working fine.

please send link of download firmware version: 1418B05SIM808M32


text:
I need help making an arduino control system
My project is to use an Arduino to control two solenoid valves with pwm and receive an input signal from a sensor as feedback.

As can be seen from the picture, the valves direct the flow of water which cause a hydraulic actuator to move which is detected by an LVDT sensor.
What I want my program to do is to allow me to set a desired displacement as a goal which causes the Arduino to dynamically change the duty cycle of the pwm frequency based off of the feedback input the Arduino receives.
I am a total novice programmer and its my first time working with electronics. I'm just hoping someone can point me in the right direction.
Based off of youtube videos this is the code I've written.
int myPin1=3;
int myPin2=5;
int readPin=A3;

//V2 is input from sensor
int V2=0;
int delayTime=50;
float D1=0.5;
float D2=0.5;
int readVal;

int goal=;

void setup() {
  // Set pin states:
  pinMode(myPin1,OUTPUT);
  pinMode(myPin2,OUTPUT);
  pinMode(readPin,INPUT);
  Serial.begin(9600);

  //set frequency of the PWM pins
  SetPinFrequencySafe(myPin1, 1000);
  SetPinFrequencySafe(myPin2, 1000);
}

void loop() {
  // Volatge reading from the VTLD:
  readVal=(5/1023)analogRead(readPin);
  V2 = (5./1023.)*readVal
  Serial.print("Voltage is ");
  Serial.println(V2);

  //PWM for the 2 output pins
  analogWrite(myPin1,D1);

  analogWrite(myPin1,D2);
  delay(delayTime);

  //Varying of dutcy cycle untill getting the desired actuator position
while (V2!=goal) {
  if (V2>goal) {
    D1=D1+0.01;
    D2=D2-0.01;
  }
   if (V2<goal) {
    D1=D1-0.01;
    D2=D2+0.01;
  }
}
  if (V2=goal) {
    D1=0.5
    D2=0.5
  }

}

I have seen people using PID libraries but I'm not sure which one is suitable to use for my project.

I successfully used this PID library before. Just try it

Welcome Marius, it would be much easier to answer your question if we had more information. Can you post your schematic or drawing of the circuit. What are you using to drive the solenoids, what is the sensor? Post links to the hardware devices that give technical information.


text:
Mixed SHARP IR Sensor Readings
I'm using the GP2Y0A21YK Sharp IR Sensor in a ball and beam system where I'm trying to balance the ball in the center of the beam using the IR Sensor as a distance locator and a servo motor to tilt the beam. I'm using a PID Controller for the system. However, something odd happens when I apply the code. When the servo motor is disconnected, I'm getting accurate readings of the location of the ball. However, as soon as I plug in the servo motor, the distance reading is completely off and inaccurate. I've read that powering the Arduino using both the USB port and Plug will make the readings more stable. However, I've tried that and it only improved the readings by a small bit. What can be causing this problem? Since the code and the schematic would take a bit of a space, kindly let me know if they are needed and I'm happy to provide.

It is likely your power source supplies insufficient current to power both the servo and the Arduino reliably.
It is also possible that the motor in the servo is creating noise on the power rails and inducing unexpected behavior in the Arduino.  But the former is more likely.
Consider using a power source which can supply more current.  For instance, D size cell batteries can supply much more current than a small 9 volt battery.
Also consider using a separate power source for the Arduino and the motor.  Many resort to this option for such projects as you describe here.

Thank you for your reply. How do you suggest I power the motor separately? Since it's plugged to the 3.3V port on the Arduino. Would two AAA batteries do the job?

With out knowing more about the servo it is difficult to tell.  However, Alkaline Primary AAA batteries provide less current than AA sized, and those less than C sized.  The same can be said for D size. This is why I suggested the largest commonly available battery.  To address a possible and likely problem you are having.  For common servos only the controlling wire is connected to the Arduino.  The ground is common to both the Arduino and servo.  The power leads of each can be connected to one sufficiently large or two smaller power sources.  Usually these need to be the same voltage.