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:
strcat appending multiple times when called in loop
The strcat function is working fine when called for the first time but when the broker goes down and it's attempting to reconnect it is appending the value twice. I am not able to figure out the problem as i am writing C code for the first time.
void reconnect() {

  while (!client.connected()) {
    const char* cid = clientID.c_str();
    if (client.connect(cid)) {
       const char* sTopic = strcat("clm/",cid);
       client.publish(outTopic, sTopic);
       client.subscribe(sTopic);
    } else {
    // Wait 5 seconds before retrying
    for(int i = 0; i<5000; i++){
      delay(1);
    }
  }
}

}
It is called in the loop method
void loop() {
  if (!client.connected()) {
    reconnect();
  }
}

The value of sTopic for the first time is clm/5C:CF:7F:3D:5B:F6 but when the broker restarts and the client connects again it is clm/5C:CF:7F:3D:5B:F65C:CF:7F:3D:5B:F6
What could be the reason for the same ?

strcat won't allocate any memory for the new string. So what really happens is that the location where the string constant "clm/" is stored gets the id appended.
In other words the second time around it's as if you passed "clm/5C:CF:7F:3D:5B:F6" as first parameter.
To fix that you need to supply a proper buffer for strcat to do its work:
if (client.connect(cid)) {
   char[64] sTopic ={0};
   strcat(sTopic , "clm/");
   strcat(sTopic , cid);

Appends a copy of the source string to the destination string.

source
Congratulations, you've broken your string literal. Either stick to using String or make sure you allocate a string properly and then concatenate into that.

You have to cat only one string per time. Your assumption is that it performs
dest = strcat(string_1, string_2)

However, it is:
dest = strcat(dest, string_1)

So you should use
char sTopic[256]; // Max possible length

...

strcpy(dest, "clm/");
strcat(dest, cid);

This will first copy "clm/" to dest, than cid will be concatenated.
(code not tested)
See reference: reference

source: Stack Exchange

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

sort: votes


text:
Simplest/best way to control a set of 8-10 PWM signals from a smartphone
As part of a larger project, I would like to be able to control a set of 8-10 PWM signals remotely, from a smartphone at a distance of 10 meters or more.  I will probably convert the PWM signals to analog voltages, and reduce their voltage swings to more like 0-1v, using a resistor divider and RC filter; they will drive high impedance loads in the remainder of the project.  I’d write an app for the smartphone allowing user control over the duty-cycle of each PWM signal (and thus the analog signal levels).
It seems to me that the way to go is Arduino, interfaced to the phone with Bluetooth.  I'd need one of the higher end Arduinos to get enough PWM signals (the basic ones like Uno only have 6 PWM outputs).  Software-generated PWMs are probably not high-frequency enough, as I’d like the filtered analog signals to be as ripple-free as possible. There seem to be several ways to interface Bluetooth to Arduino, such as the HC-05.
If people here concur with this approach, I shall move this question to the Arduino forum.
`

Do you need a PWM output or just the analog value?   Might be easier to get a DAC with 8 or more outputs than to fool around generating 8 PWM signals then filtering and scaling them to get what you need.

From phone to Arduino via bluetooth, then drive something like the AD5669.  That has 8 channels, and you can connect a couple of them to the Arduino.

Interesting idea.  I think though that there's no reason to introduce another piece of hardware.   Since each signal will be driving a small subcircuit anyhow, adding a couple resistors (and a cap, though I'd probably want that anyhow) isn't really much of a burden.

might consider "splurging" for an ESP32, which has wifi and btle support.

Looks to me like ESP32 is the ticket.  Gives me Bluetooth, with optional wifi.    Gives me 16 outputs, at high frequencies (to facilitate filtering to analog).   A nice development board for $20 ... https://www.sparkfun.com/products/13907

Never heard of MQTT.   Can you tell me more ?

HC-05 is rated to about 9m so it wouldn't necessarily meet your requirement. The ESP8266 (example of one implementation called the Node MCU) can output PWM on any of the 0-16 pins. It can easily implement a web server which would let you control your outputs via 8026.11 (wifi). It also means you don't need to build anything for the phone/ tablet/ PC just use a web browser. The duty cycle could be set through the web server on the ESP. The ESPs are around the same price as an Arduino.
I've used the HC-05 with an arduino. It works very well, though not very far. For the Android side I used app inventor which is extremely easily to use for bluetooth.

Using wifi instead of Bluetooth had occurred to me and maybe that'd be better.  I'm a little confused though: the part# you cite looks like it's just a wifi adapter for Arduino.  But you seem to be saying it's an alternative to Arduino and can provide the PWM outputs by itself.

It does look like that at first glance but is in fact an complete MCU, no Audrino required. It can be programmed using the Arduino IDE and you can use the GPIO pins.

I can live with 9 meters. This thing is more likely to be controlled by a phone (than a computer), through a GUI probably not much more complicated than 8-10 sliders (one for the duty-cycle of each PWM output).  Maybe the question I should be asking is whether that'd be easier to implement in Android or in HTML.  I'm not really familiar with doing either.

If it's < 9m and you want to choose between HTML and android for the phone side; then check out app inventor. If you go with the HC-05, then the Android side can be done entirely in app inventor which is very easy to use - no coding, just blocks.

If you're going to go with the esp32 you can't use the Arduino development environment for the Bluetooth functions and other functions are not yet implemented.

Yeah, they say you have to use the Espressif IDF instead; since I'm not familiar with the Arduino IDE anyhow, that shouldn't be a hardship for me.   This wouldn't prevent me from using App Inventor for the Android side though, would it ?

It would not prevent you from using App Inventor.

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


text:
LCD library and timer2 CTC interrupt not working together
I want to set up real time counter along with lcd functions from LiquidCrystal library. But they don't work together. However, they work fine separately.
The code is working by itself, but by implementing counter function, LCD just freezes with other functionality.
Part of code:
    #include <LiquidCrystal.h>

LiquidCrystal lcd(2, 3, 4, 5, 6, 7, 8, 9, 13, 12, 10);

volatile boolean timerFlag = false;
volatile unsigned long int tmr2Count = 0;

void setup(){

    timer2Init();
}
void loop(){
    checkState();

}
//everything works by commenting out ISR and timer2Init
//===================================================
ISR (TIMER2_COMPA_vect){
  if (timerFlag)
    tmr2Count++;
}
void timerStart(void){
  if ( !timerFlag )
    timerFlag = true;
}
void timerReset(void){
  timerFlag = false;
  tmr2Count = 0;
}
void timer2Init(void){
    //Timer 2 interrupt service routine CTC settings, 1 uS:

    TCCR2A = 0;
    TCCR2B = 0;

    //set CTC mode
    TCCR2A |= (1 << WGM21);
    //prescaler 1 for timer2
    TCCR2B |= (1 << CS20);

    // prescaler for 1 uS.
    OCR2A = 15;
    //set compare match for register OCRA
    TIMSK2 |= ( 1 << OCIE2A);
}
//========================================================

// menu
void checkState(void)
{
  // if button is pressed without menu being displayed
  if (userSettings.currentState == STATE_IDLE && encButton == true){
    userSettings.currentState = MENU_CHOICE;
    lcd.clear();
    lcd.setCursor(3,1);
    lcd.print("<Settings>");
    encButton = false;
  }

  int menuState = userSettings.currentState;

  switch(menuState)
  {
    case STATE_IDLE:
      timeDisplay();
      dateDisplay();
      break;

    case MENU_CHOICE:
      menuSettingDisplay();
      break;

    case MENU_CONTRAST:
      contrastSetting();
      break;

    case MENU_TIME:
      timeSetting();
      break;

    case MENU_DATE:
      setDate();
      break;

    case TIME_DISPLAY:
      timeDisplayOnOff();
      break;

    case DATE_DISPLAY:
      dateDisplay();
      break;

    default:
      break;
  }
}

I digged in LiquidCrystal.cpp and found that there is DelayMicroseconds function, I'm thinking that it could be the cause. If it's not, what can be done otherwise ?

This question comes from the other question: https://arduino.stackexchange.com/questions/44847/redefining-delay-and-delaymicros-as-personal-function

@Jot Thanks for redirecting. The ram is not full and I am aware that Timer2 has nothing to do with the library. I assume it could be delay within the library.

You're getting interrupt every 16th CPU clock cycle. The ISR handler might be even longer than that and your code and lower priority ISRs suffers by "starvation" as MCU can't do anything else than processing ISR.
If you use prescaler value 8, then you have 1/2us resolution of TCNT2 and overflow interrupt (in normal mode) occurs every 128us, so there will be enough time to do something else. However, if you want atomic value of TCNT2 and counted value from ISR handler, you'll have to stop Timer2 for a while.

How to set timer2 for overflow interrupt at 1/2 us ?
I have not used TCNT2 before for ISR.


text:
char * variable - Handle correctly to avoid overflow
I'm trying to understand if a char * variable can be updated down the code (since it only stores a pointer) or over-flow can occur.
For example:
char *A="/file.txt";
char *B;
void print_filename(char *filename="/defname.txt"){
Serial.println(filename);

Is is the right way to use char* variable, so down the road I assing new values :
A="/anyOtherfile.txt";
B="This_is_not_empty";
print_filename("/logfile.txt");

No overflow can occur when using char pointers like you did in your question.
You use a number of different string literals (the strings enclosed by double quotes). These automatically get placed in RAM by the compiler, but they are not meant to be writable. When you do
char *A="/file.txt";

the compiler will place the literal in RAM (not in stack, but in the read-only section, even if the literal is used inside of a function (Thanks to Edgar Bonet for the comment)) and then set the pointer A to the address of that literal. Writing to that address is undefined in the C++ standard and should not be done.
When you then do something like this
A = "some other literal";

then you are not changing the literal. Instead you are just changing the pointer to a different literal placed in RAM. So no overflow can occur, since the compiler just takes all string literals, places them in RAM (immutable) and only handles their memory addresses. So there is no writable buffer in the first place.
With
void print_filename(char *filename="/defname.txt"){
Serial.println(filename);

you are setting the default value of the filename pointer to the address of that specific literal. Setting the parameter to an address of another literal or an existing char array will just change the pointer. If you at another pointer again set filenameto that exact literal, the literal still lies in RAM and the compiler will usage again its address (so multiple uses of the same literal will not result in higher memory use).
If you - at some point - want to write data to that pointer, you first need to set it to a char array, either the address of a static array or creating a new dynamically allocated array with the new keyword:
char my_static_array[10];
A = my_static_array;
// now you can write to the array my_static_array by using A
A = new char[15];
// now you can write to a newly created array by using A

Though for the dynamic allocation you need to keep in mind, that especially AVR based Arduinos (like the Uno/Nano/Mini) don't have much memory and often dynamically declaring and deleting memory can lead to memory fragmentation (essentially the delete operations free memory, but these holes with free memory are often too small for the next allocations, so they don't get used and your memory gets like swiss cheese). That is also the reason why using the Arduino String class in the wrong way is really bad.

So passing another string literal will not cause any overflow, since you are only passing the parameter, if I get it right ?

It cannot cause overflow, because you only pass the pointer to an already existing string in memory. It doesn't get copied to another place

+1, Nice answer! But note that the string literals are not stored on the stack: they are statically allocated in the .data section of the program (or .rodata, for “read-only data”, if available on the platform). This is the case even if, in the source code, they appear within a function body.

@EdgarBonet Ah, thanks. Thought it would be on the stack, now I learned otherwise. I will edit my answer to reflect that

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


text:
Convert Binary to char
I'm reading a text file saved on my ESP8266 device (using LittleFS).
while (myFile.available()) {
        Serial.write(myFile.read());
    }

My goal is to save file content ( each line ) to a String / char array.
myFile.read() returns a binary - and I'm looking for a quick and elegant way to do so ( as in Serial.write which converts it to text ).
Guy

It is unclear, what you are trying to do. Binary and characters are just different representations of the same data. Serial.write() just sends the data out as it is and the Serial monitor then interprets that data as ASCII. But the Arduino does not care about, what the data represents. For the Arduino, everything is just binary data. The character interpretation is only for us humans and is done in the Serial monitor, not on the Arduino. So, when you want to put the data into a char array, just do so array[position] = myFile.read().

@chrisl - I'm trying to exrract the text. When I did as you explained... I only got a bunch of numbers

You need to provide the full code, where you only got a bunch of numbers. Its all about, how you are writing or printing it to Serial. A character can also be interpreted as a number, so likely you are just outputting it to Serial the wrong way.

the point is, specially write does no conversion. print converts a number to text representation, by decomposing it to digits and mapping  every digit to ascii.. so from a byte with value 123 it prints string "123" consisting of characters '1', '2', '3'. but write sends 123 as t is and Serial Monitor prints the character with this value, which is '{'.

myFile.read() returns one character. That character can be represented as a number (such as 65 for 'A') or a character, or whatever you want. Everything is just a number.
Letters are just our personal representation of certain numbers as humans. You could think of it as the numbers represented in base 256, where each value between 0 and 255 is assigned a unique symbol.
Serial.write() just passes that number verbatim to the computer which then maps it in the serial monitor to the corresponding letter in the ASCII table.
Thanks to the object-oriented and polymorphic nature of the Arduino API (see C++ Polymorphism) there is no difference between reading from a file and reading from serial. They all inherit the same Stream class that gives you the same functions regardless of what you're reading.
So you could, like Serial, read each byte from the file one at a time until you reach the line ending character(s) (\n for a Unix file, or \r\n for a Windows file) and append each to the end of a string (either a String object, which is frowned upon, though less so on more capable MCUs like the ESP8266 and ESP32, or a char array).
Alternatively you could use one of the helper functions of the Stream class, such as readStringUntil(), which reads an entire string up to (and discarding) the specified terminating character and returns a String.
However both those have problems when it comes to building up an array of all the results, especially if you don't know beforehand how many lines there are in the file - since in C++ arrays have a fixed size.
A better solution, if you really do want it all in RAM (see below), might be instead to, at first, forget the idea of lines and just read the entire file into memory. Once it is in memory you can read through the entire block of data counting the number of \n bytes (and add one if it doesn't end with \n). That will give you the number of lines in the file.
You can then allocate an array of pointers with the same number of entries as there are lines.
From there you can use strtok() on the data to split it into chunks on the \n bytes and assign each chunk to one of the pointers in your array.  That array then becomes a kind of index to the data.
But one has to ask... why do you want to store this data in RAM anyway? You have it in flash, and that is quite fast to access (not as fast as internal flash in a traditional MCU, but still many times faster than an SD card for example). If ease of navigating the data is your goal, maybe you should be thinking of better ways of storing your data. Depending on what that data is maybe a fixed size record based file structure using a struct to manipulate the data would be a better solution - then you can just seek to multiples of the record (or struct) size to almost instantly get to different entries in the file.
If it's textual data then maybe reading through the file and recording the file offsets of the start of each line in an array (note: two passes - one to count the lines for allocating the array and one for recording the offsets into the array) similar to the indexing of the data block described above would be a better solution. That way you're only storing 4 bytes per entry in your array rather than all the data. Seeking is instant (just seek to the offset stored in the array for the line you want) and you're not having to store all the data in RAM.

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


text:
ESP32 using PubSub, creating an error when implemted inside a library
I wish to combine into a single library Wifi + MQTT, for a multi devices project.
right after boot, getting Wifi - I get an error the moment MQTT server is trying to connect:
mqttClient.connect(DEVICE_TOPIC, MQTT_USER, MQTT_PASS, MQTTavltopic, 0, true, "offline");
yields :
WiFi connected
IP address: 192.168.3.186
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x400d26bd  PS      : 0x00060630  A0      : 0x800d28e8  A1      : 0x3ffb1eb0
A2      : 0x3ffc116c  A3      : 0x3f4010ef  A4      : 0x3f40108c  A5      : 0x3f4010b7
A6      : 0x3ffc106c  A7      : 0x00000000  A8      : 0x800d26b6  A9      : 0x3ffb1e90
A10     : 0x00000000  A11     : 0x3ffc116c  A12     : 0x0000000e  A13     : 0x00000010
A14     : 0x0000000e  A15     : 0x3ffb1d94  SAR     : 0x0000000c  EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffffc

Backtrace: 0x400d26bd:0x3ffb1eb0 0x400d28e5:0x3ffb1ef0 0x400d0fa6:0x3ffb1f20 0x400d103b:0x3ffb1f50 0x400d0e59:0x3ffb1f90 0x400d3651:0x3ffb1fb0 0x40088b7d:0x3ffb1fd0

Rebooting...

I'm sharing both .h and .cpp files.  Library is at its begining - so don't pay attention for irrelevant/ immature parts.
TNX
this is .h file:
#ifndef myIOT32_h
#define myIOT32_h
#include "Arduino.h"

// #include <ESPmDNS.h>
// #include <WiFiUdp.h>
// #include <ArduinoOTA.h>
#include "time.h"
#include "WiFi.h"
#include "secrets.h"
#include <PubSubClient.h>

class myIOT32
{

#define DEVICE_TOPIC "ESP32_SLEEP"
#define MQTT_PREFIX "myHome"
#define MQTT_GROUP ""
private:
    char MQTTmsgtopic[50];
    char MQTTlogtopic[50];
    char MQTTavltopic[50];
    char MQTTdevtopic[50];
    char MQTTlastctopic[50];
    struct tm _timeinfo;
    time_t _epoch_time;
    bool _wifi_status = false;
    char *wifi_ssid; // = "WIFI_NETWORK_BY_USER";
    char *wifi_pass; // = "WIFI_PASSWORD_BY_USER";
    char *mqtt_server;
    char *user = "";
    char *passw = "";

    WiFiClient espClient;
    PubSubClient mqttClient;

public:
    myIOT32(char *devTopic = "no-name", char *ssid = SSID_ID, char *wifi_p = PASS_WIFI, char *mqtt_broker = MQTT_SERVER1, char *mqttU = MQTT_USER, char *mqttP = MQTT_PASS, int port = 1883);
    void looper();
    void start();
    void mqtt_pubmsg(char *msg);
     bool use_wifi = true;
     void startMQTT();

private:

    void MQTTloop();
    void startNTP(const int gmtOffset_sec, const int daylightOffset_sec, const char *ntpServer);
    bool startWifi();
    void getTime();
    void MQTTcallback(char *topic, byte *payload, unsigned int length);
    void createTopics();
    void connectMQTT();
    void subscribeMQTT();
};

endif
and my .cpp file
#include "myIOTesp32.h"

myIOT32::myIOT32(char *devTopic, char *ssid, char *wifi_p, char *mqtt_broker, char *mqttU, char *mqttP, int port)
{
  mqtt_server = mqtt_broker;
  user = mqttU;
  passw = mqttP;
  wifi_ssid = ssid;
  wifi_pass = wifi_p;
}
void myIOT32::start()
{
  if(startWifi()){
      getTime();
      startMQTT();
  }
}
void myIOT32::looper()
{
  MQTTloop();
}

void myIOT32::MQTTcallback(char *topic, byte *payload, unsigned int length)
{
  char incoming_msg[150];
  char msg[100];

  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");

  for (int i = 0; i < length; i++)
  {
    Serial.print((char)payload[i]);
    incoming_msg[i] = (char)payload[i];
  }
  incoming_msg[length] = 0;
  Serial.println();
}
void myIOT32::createTopics()
{
  sprintf(MQTTmsgtopic, "%s/%s", MQTT_PREFIX, "Messages");
  sprintf(MQTTlogtopic, "%s/%s", MQTT_PREFIX, "log");
  sprintf(MQTTdevtopic, "%s/%s", MQTT_PREFIX, DEVICE_TOPIC);
  sprintf(MQTTavltopic, "%s/%s", MQTTdevtopic, "Avail");
  sprintf(MQTTlastctopic, "%s/%s", MQTTdevtopic, "nexton_command");
}
void myIOT32::connectMQTT()
{
  if (!mqttClient.connected())
  {
    mqttClient.connect(DEVICE_TOPIC, MQTT_USER, MQTT_PASS, MQTTavltopic, 0, true, "offline");
  }
}
void myIOT32::subscribeMQTT()
{
  mqttClient.subscribe(MQTTdevtopic);
  mqttClient.subscribe(MQTTlastctopic);
}
void myIOT32::mqtt_pubmsg(char *msg)
{
  mqttClient.publish(MQTTmsgtopic, msg);
  Serial.print(MQTTmsgtopic);
  Serial.print("/");
  Serial.println(msg);
}
void myIOT32::startMQTT()
{
  mqttClient.setServer(mqtt_server, 1883);
  mqttClient.setCallback(std::bind(&myIOT32::MQTTcallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
  createTopics();
  connectMQTT();
  subscribeMQTT();
}
void myIOT32::MQTTloop()
{
  static long lastReconnectAttempt = 0;

  if (mqttClient.connected())
  {
    mqttClient.loop();
  }
  else
  {
    long now = millis();
    Serial.println("MQTT Server- NOT connected");
    if (now - lastReconnectAttempt > 5000)
    {
      lastReconnectAttempt = now;
      connectMQTT();
      subscribeMQTT();
    }
  }
}

void myIOT32::startNTP(const int gmtOffset_sec = 2 * 3600, const int daylightOffset_sec = 0, const char *ntpServer = "pool.ntp.org")
{
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
}
bool myIOT32::startWifi()
{
  long beginwifi = millis();
  WiFi.begin(wifi_ssid, wifi_pass);

  while (WiFi.status() != WL_CONNECTED && millis() - beginwifi < 30000)
  {
    delay(200);
    Serial.print(".");
  }

  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
    startNTP();
    return 1;
  }
  else
  {
    Serial.println("NO-WiFi");
    return 0;
  }
}
void myIOT32::getTime()
{
  int a = 0;
  while (a < 3)
  {
    if (getLocalTime(&_timeinfo))
    {
      delay(100);
      time(&_epoch_time);
    }
    a++;
  }
}

myIOT32::myIOT32(char *devTopic, char *ssid, char *wifi_p, char *mqtt_broker, char *mqttU, char *mqttP, int port)
    : mqttClient(espClient)  // <--- this part was missing *****
{


text:
Use MQTT to update internal clock
I write code to upload to ESP8266. I wish to use time stamp in order to log events. I found an NTP sketch, I can work with ( since it has a wifi connection ), but I wish to keep my code as simple as possible.
So I'm thinking to use my MQTT server to send time updates from time to time ( have a certain topic for that ), and in between updates, use millis() .
Since I'm new here, I want to know from experienced programmer if it makes sense ?
I would love to hear pros and cons ( before I start coding ).
Any help will be appreciated,
Guy

How important is it to you that the time is accurate?  NTP will do a more reliable job than getting the time via MQTT. NTP is designed to compensate for the time it takes to get an answer from the NTP server and to deal with clock drift.  With MQTT you won't be sure how long it's been since the MQTT server posted the time - which may be fine for your application, if you just need a timestamp that's roughly accurate.

@JohnRomkey -thank you for you answer. As I said, it is for a time stamp, meaning few minutes a day (say 2 ), will be acceptable. I'm sure that you are 100% correct but I wish to keep my code as lite as possible

Use the Time library a.k.a. TimeLib.h. It will keep time between calls to your source of time, if it is your MQTT call or NTP server.
In your code you will use the Time library to get time and the source of the current time is independent from the rest of the code.
The TimeLib has a function setTime to set the current time and then it keeps the time using millis(). You can update the time by calling setTime again. The timestamp value for setTime is 'Unix Epoch' - number of seconds from "1970-01-01 00:00:00".
If you decide to add NTP to your project, you can use NtpClientLib. It sets the time to TimeLib with one simple line of code in setup(). Example NTP.begin("pool.ntp.org", 1, false);.

down-voter, what is wrong?

Maybe he downvoted because the question was aimed at pros and cons of getting the time through MQTT in relation to other methods of time sync instead of how to manage this time in the program.

I was thinking the same- why the down vote ? I did asked for some guidance of assistance. I UP VOTE. thank you ( i'll be happy for more explain/ code if you have )

@Juraj - thank you, i'll try using NTP as well. GUY

@Juraj - there is another function to set time interval- should I need to use it? what is the default time if I don't define?

the time starts from 1970-01-01


text:
Arduino Uno - MQTT message using PUBSUB on ESP8266
I'm trying to write code involving MQTT messages to operate an ESP8266 relay ( a Sonoff device ), using PubSub library.
For some, unknown for me, reason - messages larger than 99 chars are not sent. It this a known limitation ? can it be changed ?
void pub_msg(char *inmsg){
        char tmpmsg[255];
        // sprintf(tmpmsg,"[Cl:oc:k] [%s] %s",deviceTopic, inmsg);   ---> wish to add a time stamp
        sprintf(tmpmsg,"[][%s] %s",deviceTopic, inmsg);  ---> using this line just to find that 99 chars sent OK
        Serial.print("published MSG:");
        Serial.println(tmpmsg);
        Serial.print("Total chars:");
        Serial.println(strlen(tmpmsg));
        client.publish(msgTopic, tmpmsg);

}

The maximum MQTT packet size in PubSubClient is 128 bytes. After all the MQTT header information that leaves only 99 bytes for a message.
You can change it by editing the PubSubClient.h file:
#ifndef MQTT_MAX_PACKET_SIZE
#define MQTT_MAX_PACKET_SIZE 128
#endif

As it says in the PubSubClient README.md:

The maximum message size, including header, is 128 bytes by default. This is configurable via MQTT_MAX_PACKET_SIZE in PubSubClient.h.

Can you please refer to its location ?

The location of the file, or the location within the file?

sorry- location of the file

It's wherever you installed it to.

Is it part of pubsub library ?

If it's the same library I know of, yes.

what is valid value ?

Anything that will fit into available memory really. Work out how big you will need.


text:
Arduino Nano- Programer not responding after upload WDT
I followed an example link for WDT. Code was copied as is, and uploaded to Nano successfully.
Now- when I wish to upload another code, I get an error message saying avrdude: stk500_recv(): programmer is not responding.
Is it possible to undo it ?
code:
#include <avr/wdt.h>

#define led 13 // pin 13 is connected to a led on Arduino Uno

void setup()
{
  pinMode(led, OUTPUT);      // set pin mode
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);                // wait for a tenth of a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(100);                // wait for a tenth of a second
}

void loop(){
  wdt_enable(WDTO_15MS);     // enable the watchdog
                             // will fire after 15 ms without reset

  while(1)
  {
//     wdt_reset();          // uncomment to avoid reboot
  }
}

change the bootloader in Nano to a new one, which doesn't have this problem. and you shuold enable wdt in setup and reset it in loop.

One of the things with the watchdog is that after a watchdog reset it remains active. It has to specifically be turned off - and the bootloader doesn't (IIRC) normally turn it off.
If the timeout is too short (shorter than the time taken to upload new code) the watchdog will reset the chip while you're uploading.
The only way to turn it off is to physically remove power from the chip, and make sure that the loaded sketch never runs.

Select the board / port etc ready to upload
Unplug the board
Hold the reset button in
Plug in the board
Press upload on the IDE
6 Just as avrdude is about to run (that's the program that does the actual uploading) - just as the compiling has finished, release the reset button

If you did it right you should be able to upload properly.  If not, you will have to try again from step 1.

If the WDT program is running when you try to upload a new one, it may be blocking the bootloader. Try holding the reset button while you click the the IDE's upload button, releasing the reset once you see avrdude launch. It may take a few tries to get the button-dance just right.
Update:

what is avrdude ?

It is the program on your PC that uploads the compiled image to the Arduino. You'll see it running in the lower pane of the Arduino IDE.

what is avrdude ?


text:
How can I reset servo position?
When I do
myServo.write(0)

It isn't straight, I want it to be straight but it is at about a 45 degree angle anyone know how to reset the position with arduino to make other positions 0 and making everything relative to where that zero is?

The easy way is to remove the servo arm, set the servo position with the Arduino, and then put the servo arm back on.

On Arduino, 0 is 90 degrees one way,  90 is centered, and 180 is 90 degrees in the other direction. Not all servos can do 180 degrees so the actual maximum rotation may be less.

What kind of servo? And reference angle ?


text:
Understanding WiFi.printDiag(Serial)
I am having difficulty with setting up websockets using the Arduino IDE with an ESP8266 ESP8266 Websockets problem and I have added WiFi.printDiag(Serial) to the main loop of my code. The Output I get (with my comments added) is
14:34:03.325 -> DIAGNOSTIC INFO   Debug Comment I added
14:34:03.325 ->
14:34:03.325 -> Mode: AP          Presume this means ESP is in AP mode
14:34:03.325 -> PHY mode:N        XXX
14:34:03.325 -> Channel: 1        Presume this means AP is on channel 1
14:34:03.325 -> AP id: 0          XXX
14:34:03.325 -> Status: 255       XXX
14:34:03.325 -> Auto connect: 1   XXX
14:34:03.325 -> SSID (0):         XXX
14:34:03.325 -> Passphrase (0):   XXX
14:34:03.325 -> BSSID set: 0      XXX

The AP is setup and I can see it in WiFI Analyser on my phone.
Is there a reference somewhere that explains the lines with XXX in them, or can
someone suggest meanings? Thanks

Mode: AP

In access point mode. Can also be STA or STA+AP for Station or dual role modes.

PHY mode:N

Physical interface mode. At the moment it's in 802.11n mode. Depends on the AP you are connecting to if any.

Channel: 1

Which WiFi channel you are communicating on
All the following are meaningless in AP mode. They only pertain to STA mode:

AP id: 0

Internal ID of the access point you are connecting to, if any.

Status: 255

Connection status

Auto connect: 1

Automatically connect to an access point.

SSID (0):

Name of the access point currently connected to.

Passphrase (0):

Password used to connect to the current access point

BSSID set: 0

BSSID (kind of like the MAC address) of the access point connected to.
As you can see, much of it is meaningless for access point mode, since it mostly is to do with connecting the ESP8266 to an existing network.  In AP mode there's not a lot of debugging information you can get - "is it running?" is really all there is.


text:
ESP8266 and Arduino, using i2s and the built in adc?
I've done some extensive googling but haven't found any kind of proper documentation. Is it possible to use i2s with the built-in ADC on an esp8266 to sample audio?
And if so: any sample code on how to do so?

What do you mean by using i2s with the ADC? Do you mean you want to turn the ESP8266 into an I2S audio ADC to sample audio and send it out to some other I2S device? Why waste an ESP8266 on this (especially as the ADC is utter rubbish)?

I want to use the built in adc and use i2s to get a constant sampling rate, as I'm going to just need it for beat detection. (if you have any other suggestion how to get a constant sampling rate, i'm really up for it. determining how many microseconds have passed (which was suggested to me before) is not really one of them :/

Just use a timer. I'm not that up on the internals of the ESP8266's peripherals, but most MCUs allow you to use a timer as the sample trigger to the ADC, then a "conversion complete" interrupt to get the data.

As far as I can tell, the ESP8266 Timer only uses Microseconds, that's not fast enough :/

No, the ESP8266 timers use the clock frequency. 80MHz by default, which is a resolution of 12ns

every code I have so far seen uses void os_timer_arm(ETSTimer  *ptimer,  uint32_t  milliseconds, bool repeat_flag); which means it uses an integer amount of milliseconds making the maximum timer speed = 1ms...

os_timer_arm is for a software timer. You want the hardware timer. But it's all a bit of a moot point because the ESP8266's ADC is utter crap.

how would i then use the hardware timer in software? and what makes the ADC crap? i only want to do some beat detection kind of frequency analysis so i don't entirely care if the stuff is 100% accurate.

The results from the ADC are pretty meaningless if you have WiFi turned on. The noise is horrendous. You can use system_adc_read_fast to read a block of samples quite quickly. The SDK doesn't seem to allow you any real control over the hardware though. TBH the ESP8266 would be the absolute last choice for anything like this. Fine for WiFI, pretty naff at everything else.

SDK manual: https://www.espressif.com/sites/default/files/documentation/2c-esp8266_non_os_sdk_api_reference_en.pdf


text:
Data Structures and Color Data Types in FastLED
So i'm doing something wrong but i don't exactly know what and hope somebody can give me a quick pointer:
I declared a starting color for my fastled animation:
CHSV startcolor(100, 255, 255);

and then a data structure
typedef struct {

int currentBrightness = 0;

int targetBrightness = 0;

int updown;

CHSV color = startcolor;

} blinkblink, *pblinkblink;

So basically my idea is to have every LED be represented with this data structure to control brightness within an anmation. However if i now set
CRGB leds[NUM_LEDS];

and do something like
for (int i = 0; i < sizeof(myLeds); i++) {

leds[i] = myLeds[i].color;

}

FastLED.show();

nothing happens. I'm pretty sure, that this is because i'm somehow not understanding the data type thing. What am i doing wrong?

you did not use the name of the struct blinkblink .... http://www.cplusplus.com/doc/tutorial/structures/

Where have you defined the myLeds array?

Your second mistake was not observing the complete and reproducible parts of Minimal Reproducible Example. Once you fix that error, others will have a chance to help you with your first error (i.e. why doesn't my code work?)


text:
Constant ADC sampling rate on ESP8266 or ESP32
I want to sample Sound input with either an ESP8266 (preferred) or ESP32. As I'm using a low pass filter anyway, a sample rate of 1000-2000hz would be totally ok. What is more important, is that it is constant. Can I use DMA for that? If so: how? Or should i go via Timer interrupts?
I know about the wifi issue on the ESP8266, but I intend to just turn Wifi off as I don't need it for this project.

You have several options for controlling the sampling rate.
Software only
This is the simplest, and the previous answer got it almost right. Here
is my take:
const SAMPLE_INTERVAL = 500;  // 500 microseconds

void loop() {
    static unsigned long last_sample_time;
    if (micros() - last_sample_time >= SAMPLE_INTERVAL) {  // note 1
         last_sample_time += SAMPLE_INTERVAL;  // note 2
         // Take your sample here.
    }
}

Note 1: On the AVR-based boards, millis() is not accurate to the
millisecond. It tends to get late, then compensate for this by jumping
by two milliseconds at once. For controlling a process that should
happen every 1 ms exactly, millis() is very clearly not
suitable. I do not know how good is the ESP8266's millis(). It may
well be better than the AVR version. However, even a perfect millis()
will not be good for anything faster than 1 kHz.
The solution to this problem is pretty trivial: just count the time in
microseconds instead of milliseconds. The only drawback of using
micros() is that you cannot measure durations longer than about
71.6 minutes, which in turn means you cannot use it for sampling at
any rate slower than 233 µHz. Obviously this is not something you
should be concerned about. Note that the micros() rollover is not an
issue as long as you are sampling faster than the rollover period.
Note 2: It is impossible to have a steady sampling rate if it is
controlled by software. The best you can hope for is a tight control on
the average sampling period. This is accomplished by updating
last_sample_time as
last_sample_time += SAMPLE_INTERVAL;

Note that this variable holds the time when the last sample was supposed
to be taken, not the time it was actually taken. The sample was probably
taken a little bit behind schedule, as anything the CPU does takes time.
Updating last_sample_time this way means that these timing errors are
not cumulative. They would be cumulative if you did it in the “Blink
without delay” style, namely
previousMillis = currentMillis;

The drawback of this software method is that it inherently has a
significant amount of jitter. The program tests the current time only
once per loop iteration, and it may have other things to do within that
loop that adds to its execution time.
Software triggered by interrupts
I have never programmer an ESP timer but, if you can, it should provide
you better timings than the software-only version. Have the timer
deliver an interrupt at the desired sampling period, and use the ISR for
triggering the ADC. You may wait for the result inside the ISR, store it
in RAM, and set a flag to tell the main loop that a new sample is
available, as in
volatile int analog_sample;
volatile bool analog_sample_valid;

ISR(whatever_timer_interrupt)
{
    analog_sample = analogRead(ANALOG_PIN);
    analog_sample_valid = true;
}

void loop()
{
    if (analog_sample_valid) {
        int analog_sample_copy = analog_sample;  // note 1
        analog_sample_valid = false;
        // handle analog_sample_copy here
    }
}

Note 1: On an 8 bit Arduino, you would have to do this with
interrupts disabled. You shouldn't need to disable interrupts on a
32 bit platform.
This method should significantly reduce the jitter compared to the
software-only version. Now the sampling doesn't have to wait for the
program to run through the loop and reach the point when the time is
tested. Instead, whatever the program is doing, it will be immediately
interrupted for doing the sampling. Well... almost. From time to time it
will happen that the interrupt fires when the program is running with
interrupts disabled. This may be the case if it is already servicing
another interrupt. When this happens, the sampling will have to wait
until interrupts are enabled again. You end up with a jitter that is
most of the time a small fraction of a microsecond, and then
occasionally a sample is late by several microseconds.
Hardware only
On an AVR, you can configure the ADC to be automatically triggered by a
timer, or even to automatically trigger itself in the so called “free
running mode”. I do not know the specifics of the ADC in the ESP8266.
You may want to read the datasheet and see if it offer similar
functionality. If you can enable ADC auto-triggering, then you will have
cycle-accurate timings. The steadiness of your sampling will be just
as good as the quartz crystal clocking your MCU. No software solution
can ever come close to this level of perfection. The only drawback of
this method is that you will have to study the datasheet of your ESP in
order to implement it.

Have you looked "BlinkWithoutDelay" sample on Arduino? The most valuable part of it is the following:
void loop() {

    unsigned long currentMillis = millis();   // NOTE: 1

    if (currentMillis - previousMillis >= interval) {  // NOTE: 2
         // save the last time you blinked the LED
         previousMillis = currentMillis;  //NOTE: 3
         .. do your thing here ..
    }
}

Take into account the places from NOTE 1 to NOTE 3 I have marked in comments:
NOTE 1:
First thing in the loop where you mainly go is taking current time in millis. Should not take a lot of effort from Arduino to achieve.
NOTE 2:
Second thing is a comparison: is there enough time gone to make your thing ( = to take the sample) or not? If it is false, you make another round. If true, make it! Again, no big effort from computer.
NOTE 3:
Here you reset the timer, BEFORE doing anything else. So, your "sample interval clock" is quite precise, it consists of three little steps inside the computer and it should work in fractions of seconds accuracy (time estimate = (1 / Arduino clock speed) * some machine commands).
The other commands: taking sample, storing or sending it, should happen inside the one millisecond left from these commands. Do make a note, 1000 samples gives you 1ms time and 2000 samples 0.5ms time. This example fits perfectly to the 1000 samples case, as the accuracy of your clock is 1ms. I would go with that, if possible.
The time left, 1ms is quite long as a machine's executing time, but you have to make sure that some other components like a WiFi connection you mentioned, may be harmful for this approach. The other part of code inside the loop cannot take more than 1ms, otherwise it affects to the constant rate. Anything less than 1ms is ok, this algorithm makes no difference between 0.1ms or 0.9ms hard work inside the if, the accuracy of 1-10 machine words always holds.
(I don't know exactly how long command if is, nor how long is function millis(). If you want to be very precise, you may take these in account, but IMHO you can omit their importance in calculations: whether they take some time or not, anyways the execution of these may be quite well taking the same on every round - in constant time!)
SOURCE:
https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay

and how exactly do you want to get above 1000hz with "millis"? :P this is a highly imprecise solution.

This is accurate only for 1000hz, you are right.


text:
Measuring the speed of an object moving fast through air
I am new to arduino and am confused about how I would go about doing this: I want to attach a device to a small ball, that will move through the air at speed. The purpose of this device would be to determine the speed of this object as it moves through the air. My ball will always move in the same path because it will be shot out of a tennis ball shooter. My initial intuition would be to use an accelerometer to determine the acceleration at quarter second intervals and then multiply those values by a quarter of a second to obtain the change in speed and then add it to the sum of all the previous change in speed values (starting at 0).
Would this work? Is my reasoning correct? Are there any better solutions?
Thank You!

some part of the fly path will be without measurable acceleration and deceleration. Mythbusters used a high speed camera

How so? What circumstances would lead to that?

When you get to max speed it will flatten out? What you are proposing is constant integration and is a best-guess scenario. Better is to get the time between two known positions and work it out from there.

But at max speed, I just need to add a 0 change in speed to my speed counter, and that would by default be the max speed right?

The problem is I don't have any two known positions.

How inaccurate should the estimate be? I am fine with a margin of inaccuracy....

It would drift over time. What distances and speeds are you considering?

Less than a meter and a around 2-3 kmph at best.

1m at 3kmph would give you 1.2s to get your samples. The more you take the better. Plus you have to factor in spin (and hence centrafugal & centrapetal force).

You are proposing calculating velocity based on sampled acceleration.  Essentially taking the integral of the acceleration.  This is the first step in a process call dead reckoning. This is discussed in this arduino.stackexchange.com answer.  In that answer there is a link to a web page which implements dead reckoning using an Arduino. You will find this equation on that web page:
velocity(i) = velocity(i-1) + acceleration (i)

You can probably get off hold if you re-phrase your question to something like: "Measuring the speed of an object using an Arduino".  Then using similar wording in the question.

While this is an interesting project - dead reckoning is usually difficult to get right.  For this reason I would recommend checking out what might be possible using a color video camera and OpenCV.  However, perusing this approach takes you out of the Arduino realm and into (at least) the Raspberry Pi realm.


text:
Trouble with Arduino -> PSOC4 communications over I2C! (Multi master/ slave config)
Hello Stack Exchangers!
I am currently working on a project which requires me to use PSOC4 - 049's to scan a series of inputs, and feed this data back to an arduino over I2C.
The arduino, or in this case a teensy 3.5, is the main unit which hosts a UI and retains key system variables. I wish to have the teensy send a few unsigned bytes to the arduino, and when user input is detected have the PSOC act as the master and send relevant information back to the arduino.
Unfortunately I've been trying for about a week now to no avail.
Currently I have 2 Teensy 3.5s sitting on my I2C bus and 1 PSOC4.
I send the first teensy a 'H' or 'L' character from a terminal over USB and it turns an LED high or low respectively,
This teensy then relays this character over the I2C Bus to the other teensy at address 0x10, which also toggles an LED.
The idea is that the first teensy then also forwards a value to the PSOC at address 0x11 but this simply isn't working for me!
I can't seem to get a single byte over to the PSOC let alone set up the full MMMS system I need!
Does anyone see what I'm doing wrong or have a good simple example of a PSOC project using Multi Master Multi Slave?
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=
ARDUINO MASTER CODE     (Might be doing something wrong)
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=
(Note that this function is part of a much larger project and is just being called from main at this time, much of the project is removed here but should not effect this code in any way)
#include <Wire.h>
void setup()
{
     Wire.begin();
     Serial.begin(9600);
}

void loop()
{checkCommand();}

byte I2CTargetAddr[8] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17}; //       Declares the addresses of the PSOCs

void checkCommand() // Reads Serial Commands H or L, sets an LED, then     relays the instruction (hopefully) to the PSOC to do the same thing.
{
  static int CCFR = 1;

  if (CCFR == 1)
  {
    pinMode(36, OUTPUT);  // Debug LED
    digitalWrite(36,HIGH);
    CCFR = 0;
  }

  char c;
  static char previousC = 'L';

  static byte low = 0;
  static byte high = 255;

  Wire.setClock(100000); // Set to 100kHz

  while(Serial.available())
  {
    c = Serial.read();

    if(c == 'H')
    {
      Wire.beginTransmission(I2CTargetAddr[0]);
      Wire.write('H');
      Wire.endTransmission();
      digitalWrite(36, HIGH);
    }

    else if(c == 'L')
    {
      Wire.beginTransmission(I2CTargetAddr[0]);
      Wire.write('L');
      Wire.endTransmission();
      digitalWrite(36, LOW);
    }
  }

if(c == 'H')
{
  Wire.beginTransmission(I2CTargetAddr[1]);
  Wire.write(high);
  Wire.endTransmission();
  //digitalWrite(high, HIGH);
}

else if(c == 'L')
{
  Wire.beginTransmission(I2CTargetAddr[1]);
  Wire.write(low);
  Wire.endTransmission();
  //digitalWrite(low, LOW);
}

  previousC = c;
}

=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=--=-=
ARDUINO TEST SLAVE CODE  (Seems to be totally fine)
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=--=-=
#include <Wire.h>
#define LED_1 23  // PWM Capable LED Pin

void setup()
{
  Wire.begin(0x10);
  Wire.onReceive(receiveEvent); // Calls the receiveEvent function when     something happens to the I2C bus
  pinMode(LED_1,OUTPUT);
  digitalWrite(LED_1, HIGH);
}

void loop()
{
}

void receiveEvent(int howMany)
{
  while(Wire.available())
  {
    char c = Wire.read();

    if (c == 'H'){digitalWrite(LED_1, HIGH);}
    if (c == 'L'){digitalWrite(LED_1, LOW) ;}
  }
}

=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=
PSOC 4 Code
=-=-=-=-=-=-==-=-=-=-=-=-==-=-=-=-=-=-=-=-=-==-=--==-=-=-=-=-=-=
The topdesign includes a bootloadable component, a pin for LED Extern and LED Local, and an i2c block set as multi slave/ multi master at 100kb/s
-------------------------------MAIN.C---------------------------------
#include <project.h>
#include <main.h>

extern uint8 I2CSlaveIn[BUFFER_SIZE];
extern uint8 I2CSlaveOut[BUFFER_SIZE];
extern uint8 I2CMasterIn[BUFFER_SIZE];
extern uint8 I2CMasterOut[BUFFER_SIZE];

/* Fast BootLoad ISR */
CY_ISR_PROTO(bootloadISR_Handler);

CY_ISR(bootloadISR_Handler)
{
    Bootloadable_1_Load();   // Forces a restart of the bootloader,     triggered by the onboard button.
}

int main(void)
{
    BootLoadSys_Start(); // Initialise easy bootloader tool
    bootloadISR_ClearPending();
    bootloadISR_StartEx(bootloadISR_Handler);

    initI2C(); // Initialised i2c

    CyGlobalIntEnable; /* Enable global interrupts. */

    uint8 transferredIn[BUFFER_SIZE];
    uint8 byteCount;
    uint8 lastVal = 0;

    LED_Local_Write(0);
    int i;

    for(;;)
    {
        if (0u != (MYI2C_I2CSlaveStatus() & MYI2C_I2C_SSTAT_WR_CMPLT)) //     Wait for master to complete Write
        {
            byteCount = MYI2C_I2CSlaveGetWriteBufSize();
            MYI2C_I2CSlaveClearWriteStatus();             // Take a wild guess

            for (i =0; i<byteCount; i++)
            {transferredIn[i] = I2CSlaveIn[i];} // Copy data from the buffer

            MYI2C_I2CSlaveClearWriteBuf();
        }

        if (transferredIn[0] != lastVal)
        {
            if (transferredIn[0] == 255u){LED_Local_Write(1);}
            if (transferredIn[0] == 0u  ){LED_Local_Write(0);}
        }

        lastVal = transferredIn[0];

    }
}

----------------------------------I2C.C------------------------------------
#include "project.h"
#include "i2c.h"
#include "main.h"

uint8 I2CSlaveIn[BUFFER_SIZE];
uint8 I2CSlaveOut[BUFFER_SIZE];
uint8 I2CMasterIn[BUFFER_SIZE];
uint8 I2CMasterOut[BUFFER_SIZE];

void initI2C()
{
    MYI2C_I2CSlaveSetAddress(MY_SLAVE_ADDR);

    MYI2C_I2CSlaveInitReadBuf( (uint8 *)I2CSlaveOut  , BUFFER_SIZE);
    MYI2C_I2CSlaveInitWriteBuf((uint8 *)I2CSlaveIn  , BUFFER_SIZE);

    MYI2C_Start();  // Calle after buffer setup
}

----------------------------------I2C.h----------------------------------
#define BUFFER_SIZE 1u // Sets Buffers size
#define MY_SLAVE_ADDR 0x11u

void initI2C();

You need to get your slaves communicating properly first. I would strongly suggest dropping multi-master and have the PSoC use a GPIO line to signal the Teensy master to read it, instead of swapping masters. Much simpler implementation.

So it turns out I'm an idiot.
At some point in the last day or so I must have accidentally changed the pins that the I2C component is assigned to.
This code (or at least code very similar to this, after a couple of minor changes) works perfectly for the slave side.
Feel free to make use of it if you need it!


text:
what is the max frequency of external interrupt for esp8266 arduino?
i am using esp7 with AttachInterrupt() (Arduino) to count incremental encoder. I need to know what is the maximum frequency of pulses that esp7 can acquire.
also, need to know what frequency atmega328 can go with interrupt handling for an incremental encoder. my encoder 1000ppr.

This largely depends on what you are doing in the interrupt handler. Are you asking for the maximum frequency without any code in the ISR?

my encoder 1000ppr. ... this information is not relevant to the question.

On the 328 you can use the pulses as in input for timer2 (sync timer input). In that case the maximum frequency is one-fourth the frequency of what the 328 is running at. So 4MHz for the UNO.


text:
PWM fans causing temp sensor erroneus values (interference?)
I am learning Arduino programming and my current project for real use is to connect 10-17 PC chassis PWM fans to be temperature controlled by the arduino.
So, I have connected the fans exactly as in the picture.
Taken from https://www.racedepartment.com/threads/easy-diy-wind-simulator-for-assetto-corsa.133999/

The temperature sensor is a TMP36 (included in the official Arduino beginner's kit). It is connected to +5V and GND on the Arduino Uno R3. Middle pin is the output and is connected to A0 on the Uno.
Temperature readings seem to work well up until the point the fans start spinning. When they do, the output pin on the TMP36 sensor outputs junk values. Such as 0V or 700mV and it fluctuates up and down if I try probing it with a multimeter. When fans some to a stop however, the output once again stabilizes to a fairly correct value.
I am no expert in electronics interference, but electric motors I suppose cause some electrical noise? I had hoped that PC Chassis fans would already have electric components inside the hub to prevent such though...
Currently I am trying to run 2 fans at the same time but I wish to use 10-17 later once this works.
The fans I am using are Arctic 92mm PWM Rev 02.
I have checked the datasheet (https://www.arduino.cc/en/uploads/Main/TemperatureSensor.pdf) for TMP36 (TO-92 package type) and tried adding a ceramic 0.1µF capacitor between +5V and GND and also add resistor of varying values to the output pin. I believe I got some stabilization out of it but not  enough. Especially when the fans start spinnig faster than 20% duty cycle on pwm it starts to flip out.
I have tried to disconnect power to fans to check if PWM signal may cause it too, but this is not the case as the TMP36 remain stable with PWM on but fans disconnected.
Can someone please help me with explaining what is probably going on and how I can mitigate the problem in a preferably easy way? Do I need to add diodes, capacitors, resistors? Where? Or should I change to a different temperature sensor (which)?
Thankful for help!

Quick thought:   It may be that trying to do both is causing problems.  That is, you may be using the same processor resource(s) for both features.  Like a timer or a serial port.  Just because an Arduino program compiles doesn't mean that the libraries you include will work with one another.

BTW, you are using a second power supply to power the Arduino, right?  I say this as I realize 2 things.  1) I assume you have copied a working project exactly.  So there is precedence that the included libraries work together.  -and- 2) There is no second power supply in the diagram.  I think the original author just assumed there would be one.

@st2000 Hmmm, I only use PWM (analogWrite) and AnalogRead to read the temperature value. It feels like a very "simple case" for it to collide? That would cause lots of problems in projects of all kinds then. I tried to use an LDR instead of a TMP36 and fetch analog values and that worked like a charm.
The Arduino is powered via USB (PC connection). The fans are powered via external wall adapter as in the picture. So power for fans is drawn from the power adapter.

The LDR would have needed a pull up or pull down resistor.  (Did you use one?) Where as, I assume, the TMP36 would not.  I didn't look at the TMP36 spec, my bad, I didn't realize it developed an analog output.  I thought it was one of the common temperature probes which communicated over an I2C bus. Double check that you have connected to the correct pins of the TMP36.  Note the TO92 case is a bottom view whereas the other case views are from the top.

@st2000 You are correct, yes I had a resistor in series with the LDR (10kOhm) while the TMP36 did not need one (although in the datasheet I then found a section towards the end regarding high inductive loads showing a capacitor of 01µF and a resistor of 750 Ohm). Maybe is stailized things a tiny bit but as soon as fans spin up above 20% or so the TMP36 starts acting up. The connections to the TMP36 should be correct because it works fine when fans are not spinning. I feel that there's something missing, like some capacitor or diode or something for the fans maybe?

This is turning into guess work.  The series resistance and cap are likely to mitigate noise by matching the impedance of a long cable between the ADC and the TMP36.  Just keep it short for now. A foot / decimeter would be fine.  I suspect the current draw of the fans at speed is dripping the voltage of the fan power supply and dragging the laptop's USB power source with it resulting in unexpected readings.  Check to see if the power supply your are using is double the sum of the expected fan currents.  Also, try connecting only 1 fan to see if it will run as expected.

I suspect you will point out that the LDR / resistor divider had no problems controlling the fans to the desired fast speed.  If this truly is the case, I might guess that the impedance of the LDR / resistor divider is lower than that of the TMP36.  That in such a case, a little noise can manifest its self as larger voltage swings and more erratic ADC samples.   If true, that is, if the noise is random and the average reading accurate enough for this project, consider solving this problem in software.  Take the average of the readings and use that to control the fans.

@st2000 It is correct that the voltage values I got from reading the LDR were consistent, so I could set a PWM duty cycle based on lighting conditions in a consistent manner. I can't really take an average of the TMP36 though because when the fans are spinning and it gets affected by some interference, the output pin gives 0V or anything inbetween that and say 700mV and with a multimeter I can see that the output pin voltage jumps around all the time. Until I stop the fans, that is. Can I use a resistive temperature sensor instead (like the LDR for Light)? in so, which one has linear response?

Did you check the fan power supply is 2 x the sum of the peak current demand of the fans?  (Fans rated at 0.8A so both are 1.6A so 2 x means should use a power supply that can supply 3.2A.)  Or experiment w/only 1 fan - but use a power supply that can supply 1.6A.

Currently I use a power bank which can supply 12V. But the fans are rated 0.16A (not 1.6A  that would be raally powerful fans :) ). So with both fans at max speed I get 0.32A @ 12V. But I get sensor problems for anything above 20% speed when the two fans only draw very little current. I don't think that the power supply is too weak but I will try with another PSU.
If I had an oscilloscope I would be able to see if I have some distortion of voltage on the input to the sensor

In case anyone has the same problem, I solved it. Turns out is was a bad PSU. Buying a new, higher quality one made everything work. So the issue was high ripple I suspect, or at least high enough when applying some load (which is why I noticed that things got worse after the fans started spinning at greater than 20% duty cycle) for the temperature sensor to flip out.


text:
Suitable long-term sensors for PM, Ozone and NO2
I am totally new to Arduino. I have a Arduino Mega 2560 and I would like to perform long-term observations of PM, Ozone and NO2 (for around a year, outdoors).
Do you have any ideas which sensors might be suitable for this? I have a few sensors in mind (SDS011, Plantower PMS 1003, Sharp GP2Y1010AU0F, Honeywell HPMA115S0...) but since this is my first time doing this kind of stuff, I dont have any experience.

This sounds like more of an electronics/sensors question than an Arduino question. I'd say first identify the sensor(s) that meet your needs, and then figure out how to interface them with your Arduino.

Thanks! Since I have no experience at all with this, I wanted to asked experienced users, which sensors may fit my needs. Where can I ask this, if not here?

The electronics stack exchange would be a good place to start.

Explain your needs (weatherproof, able to be interfaced with and Arduino microcontroller easily, will last > 1 year without adjustment, etc)


text:
I can't write or read data in an external eeprom
I've been trying to store data in an external I2C EEPROM but it doesn't seem to work, and i don't know why.
When i run the i2c scanner it founds my memory but i can't write in it, or at least it seems like i can´t
Please help me :(
(I'm using a 24C512 btw)
#include <SoftwareSerial.h>
SoftwareSerial BT1(3, 4); // RX | TX
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Max72xxPanel.h>
#include <EEPROM.h>

#define EEPROM_I2C_ADDRESS 0x50

//Vcc - Vcc
//Gnd - Gnd
//Din - Mosi (Pin 11)
//Cs  - SS (Pin 10)
//Clk - Sck (Pin 13)

String inicio="";
const int pinCS = 10;
const int numberOfHorizontalDisplays = 8;
const int numberOfVerticalDisplays = 1;
String bt;
//String cadena[]={"holamundooooooooo"};  //textos
int i=0;
Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays);

const int wait = 25; // Velocidad a la que realiza el scroll(Velocidad a la que se muestra la frase)

const int spacer = 1;
const int width = 5 + spacer; // Ancho de la fuente a 5 pixeles

void setup()
   {
       Serial.begin(9600);
       Serial.println("Enter AT commands:");
       BT1.begin(9600);

        matrix.setIntensity(15); // Ajustar el brillo entre 0 y 15

 // Ajustar segun las necesidades
 matrix.setPosition(0, 0, 0); // El primer display esta en <0, 0>
 matrix.setPosition(1, 1, 0); // El segundo display esta en <1, 0>
 matrix.setPosition(2, 2, 0); // El tercer display esta en <2, 0>
 matrix.setPosition(3, 3, 0); // El cuarto display esta en <3, 0>
 matrix.setPosition(4, 4, 0); // El quinto display esta en <4, 0>
 matrix.setPosition(5, 5, 0); // El sexto display esta en <5, 0>
 matrix.setPosition(6, 6, 0); // El séptimo display esta en <6, 0>
 matrix.setPosition(7, 7, 0); // El octavo display esta en <7, 0>
 matrix.setPosition(8, 8, 0); // El noveno display esta en <8, 0>

 matrix.setRotation(0, 1);    // Posición del display
 matrix.setRotation(1, 1);    // Posición del display
 matrix.setRotation(2, 1);    // Posición del display
 matrix.setRotation(3, 1);    // Posición del display
 matrix.setRotation(4, 1);    // Posición del display
 matrix.setRotation(5, 1);    // Posición del display
 matrix.setRotation(6, 1);    // Posición del display
 matrix.setRotation(7, 1);    // Posición del display
 matrix.setRotation(8, 1);    // Posición del display

 char bt[]={"prueba"} ;
   }

void loop()
   {
 //bluetooth recoger datos
 if(BT1.available()){
  bt="";
 }
 int i=0;
  while(BT1.available()){
       // Serial.write(BT1.read());
        char c=(char)BT1.read();
        if((c=='a')||(c=='b')||(c=='c')||(c=='d')||(c=='e')||(c=='f')||(c=='g')||(c=='h')||(c=='i')||(c=='j')||(c=='k')||(c=='l')||(c=='m')||(c=='n')||(c=='ñ')
        ||(c=='o')||(c=='p')||(c=='q')||(c=='r')||(c=='s')||(c=='t')||(c=='u')||(c=='v')||(c=='w')||(c=='x')||(c=='y')||(c=='z')||
          (c=='A')||(c=='B')||(c=='C')||(c=='D')||(c=='E')||(c=='F')||(c=='G')||(c=='H')||(c=='I')||(c=='J')||(c=='K')||(c=='L')||(c=='M')||(c=='N')||(c=='Ñ')
        ||(c=='O')||(c=='P')||(c=='Q')||(c=='R')||(c=='S')||(c=='T')||(c=='U')||(c=='V')||(c=='W')||(c=='X')||(c=='Y')||(c=='Z')||(c==' ')){
          bt=bt+char(c);

          writeByte(EEPROM_I2C_ADDRESS,i, (byte)c);

          i++;
          delay(50);

        }else{
          bt=bt;
        }
  }
  Serial.println(bt);

String palabrasacada;
for(int i=0; i<bt.length(); i++){
  byte z=readByte(EEPROM_I2C_ADDRESS,i);
  char a=char(z);
  palabrasacada=palabrasacada+String(a);
}

String cadena[]={palabrasacada};
int n = random(0,1);

 for (int i = 0; i < width * cadena[n].length() + matrix.width() - 1 - spacer; i++) {

 matrix.fillScreen(LOW);

 int letter = i / width;
 int x = (matrix.width() - 1) - i % width;
 int y = (matrix.height() - 8) / 2; // Centrar el texto

 while (x + width - spacer >= 0 && letter >= 0) {
 if (letter < cadena[n].length()) {
 matrix.drawChar(x, y, cadena[n][letter], HIGH, LOW, 1);
 }

 letter--;
 x -= width;
 }
 matrix.write(); // Muestra loscaracteres
 delay(wait);
 }
}

void writeByte(int device, unsigned int add, byte data)
{
  Wire.beginTransmission(device);
  Wire.write((int)(add >> 8)); // left-part of pointer address
  Wire.write((int)(add & 0xFF)); // and the right
  Wire.write(data);
  Wire.endTransmission();
  delay(5);//small delay for eeprom to save data
}

// reads a byte of data to the I2C address 'device', in memory location 'add'
byte readByte(int device, unsigned int add)
{
  Wire.beginTransmission(device); // I2C address
  Wire.write((int)(add >> 8)); // bit shift for high byte of pointer address
  Wire.write((int)(add & 0xFF)); // mask for the low byte
  Wire.endTransmission();
  Wire.requestFrom(device, 1);
  return Wire.read();
}

The led matrix and bluetooth receiving actually works, but i'm adding them anyways, just in case

I don't know the answer, but you can change the big if statement:  if((c=='a')||(c=='b')||(c=='c')||(c=='d')||(c=='e')||(c=='f')||(c=='g')||(c=='h')||(c=='i')||(c=='j')||(c=='k')||(c=='l')||(c=='m')||(c=='n')||(c=='ñ')  ||(c=='o')||(c=='p')||(c=='q')||(c=='r')||(c=='s')||(c=='t')||(c=='u')||(c=='v')||(c=='w')||(c=='x')||(c=='y')||(c=='z') .... == ' '))

by something like if (((c >= 'a') && (c <= 'z')) || (c=='ñ') || ((c >= 'A') && (c <= 'Z')) || (c=='Ñ') || (c == ' '))

@MichelKeijzers You overlooked 'ñ' which actually isn't an ASCII character anyway...

@Majenko I fixed it before reading your comment but you are absolutely right

You're right, thank you

Have you debugged your code to find the problem? For example you can  check the return value of endTransmission() for an error code, that would indicate a problem with I2C transmission

reduce your code to write a single byte, read it back and turn on an LED if the two match ... you can do it in setup() ... no code needed in loop()


text:
How can I pass multiple variables to a function?
Using the FastLED library, I want to light up multiple lights at once.
Currently I am passing in just one light to the function.
spell( int LEDNumber )
{
  FastLED.clear();
  leds[LEDNumber] = CRGB (255,255,255); //white
  FastLED.show();
  time = 500;
  delay(t);
}

I would like to pass in more than just 1 light at a time.

This is really a basic C/C++ programming question, not an Arduino question. In any case, I'm glad you were able to figure it out.

@DuncanC There is indeed a sort of no-man's land there, since Arduino does restrict how you can use C++, especially vis-a-vis memory restrictions.  I am not sure that I would be so strict with Joshua, or anyone for the matter.

Tony, yes, there are some gray areas, but this is a programming 101 question for C/C++.

You may create a struct with "x" elements, one for each LED:
struct ArrayOfBooleans {
   bool array[4];
};

ArrayOfBooleans myOutputArray;
myOutputArray.array[0] = true;
myOutputArray.array[1] = true;
myOutputArray.array[2] = false;
myOutputArray.array[3] = true;

lightEmUp(myOutputArray);

void lightEmUp(ArrayOfBooleans myOutputArray) {
   bool isFirstLightOn = myOutputArray.array[0];
   // etc
}

NoTE: If you run into Exception 9 issues (using this logic on another board), please check this answer to another post

Wonderful answer. Way better than what I found. Thanks!

I just recently ran into this issue and this was the solution that i implemented.  keeps things cleaner, as well as making upgrading (adding or removing parameters) easier..  tks for accepting.

Exception 9 on Uno?

why the struct? it is useless and will be copied as function parameter. you can pass the array as parameter

you could do that, but a struct may have other data as well - such as multiple arrays for multiple dimensions of parameters.  such as other parameters.  a struct as a class is far from useless, especially if your development is method oriented.

i find your spamming rude and abusive in abstract and have flagged you for it, @Juraj.  I am not hard of reading, there is no point in sequentially writing the same rude comment.

Easier than I thought. Found it while reading the docs. Imagine that. :)
To pass in multiple variables, just separate them with a comma.
Docs: https://www.arduino.cc/en/Reference/FunctionDeclaration
Relevant code:
int myMultiplyFunction(int x, int y){
  int result;
  result = x * y;
  return result;
}


text:
Connecting multiple led strips in parallel with arduino
I am making a led panel using led strips. Each of the two led strips are 5M long containing 300 LED SMD Striplights. I have cut each of the 2 strips into many small strips of lengths of about 38 cm and connected them in parallel i.e there is  a singe pair of terminals for all the strips.I have a 12V,5A power supply. I had tried to drive the panel using Arduino Mega in combination with a MOSFET as is it is commonly done for a single led strip but I am unable to make it work.
Can anybody please help me out?
Other components being used are - PIR sensor , RTC module

Not enough info. Did you cut these strips only at the cut points? Have you tested them separately? Are they meant to run on 12? Will the MOSFET drive a single, uncut strip? What's the total power requirement for all of your strips? (Add the current requirements of the individual strips together)

If you are using a mosfet like IRFZ44N you should change that to a logic level IRLZ44N. Arduino 5V isn't enough for a normal mosfet to allow enough current pass through.

One LED strip is lots of little LED strips in parallel. One LED strip cut into sections and wired in parallel is no different to one LED strip.

If you can wire up the power to work for a single string, you should be able to "star" wire from the output side to all the other LED strips and have it still work. Star wiring is to wire the strip directly to the PSU, instead of running a common power from one strip to the next. It handles current/heat and spikes better.

Post a schematic of your circuit. Post all the specifications of your LEDs.What do you mean you can't it to work, which part?


text:
power consumption of esp32
I'm currently working on an IOT project with my esp32, ill need it to run on batteries, I will only be needing "active mode" with wifi once per hour to upload some data to a database and then go back to deep sleep (need to save data cant use hibernation).
THIS website explain pretty well how much energy the esp needs, but it says e.g. 30mA - 60mA, but on batteries it says mAh, so is the mA just mAh or how do I calculate the power usage?
.
ps.
currently, I'm thinking of using 2 cr2032 batteries, good recommendations on batteries are welcome

Please read https://learn.adafruit.com/low-power-wifi-datalogging/battery-life-and-current-consumption and https://learn.adafruit.com/all-about-batteries/overview. mAh is milli-ampere hours, i.e. a coin cell with a capacity of 210mAh can theoretically provide 210 mA for 1 hour before it's empty (or 105mA for 2 hours). You need to calculate the total spent battery capacity over 1 hour (based on the current consumption in activate / inactive mode times the time they are in that mode). Also be aware that CR2032 are 3.0V batteries whose voltage drops as its energy depletes (also current dependent)

Also be aware that due to internal resistances in batteries and other stuff, batteries have a maximum output current capability, so a coin cell might not contiously provide that much current. You might need a big capacitor from which energy is sourced then.

@MaximilianGerhardt thanks, any recommendations on batteries?

Many come to mind, Li-Po, Li-Ion (like a 18650 cell),.. You should these videos for a better understanding and tests: https://www.youtube.com/watch?v=heD1zw3bMhw https://www.youtube.com/watch?v=-769_YIeGmI https://www.youtube.com/watch?v=gG82_fG4VM8 https://www.youtube.com/watch?v=3O_vrKAmshA

@MaximilianGerhardt esp32 can only handle up to 3.5 so the lipo 18650 would fry it, and i would loose to much power to a step down

also i need something flat, maximum hight of 4 milimeters, therefor aa and aaa is not an option

Of course directly applying a 18650 would be bad, that's why there should be a DC/DC converter (preferably switch-mode) there. You might want to look into battery managment ICs and voltage regulators. @"something flat": Maybe experiment with the coin cells and a big capacitors or DC/DC converts and see if the ESP32 can still connect to WiFi despite the high inrush current at WiFi transmissions.

There's a number of things to consider when choosing batteries.
First is the capacity. In broad terms, the capacity is, mAh, means "This battery can supply X mA for one hour". So a battery of 1000mAh could supply around 1A (1000mA) for one hour before it goes flat.  Simply divide the mAh by your device's mA and you get the time it will run for before it goes flat. So a 50mA device would run for about (1000 / 50) 20 hours before running flat.  That is only a "ball park" figure though, since the capacity is somewhat dependent on the amount of current you draw.
Then there is the question of the internal resistance of the battery. This determines the maximum current that you can draw from the battery before the voltage drops below a usable level.  Different battery chemistries have different internal resistances.
Small button cells like the CR2032 have a high internal resistance and a low capacity.  A typical cheap CR2032 has around 200mAh capacity. At 50mA that would last 4 hours. But drawing 50mA from a CR2032 is not really on.  Looking at the graphs in the datasheet linked to above you can infer that, with a nominal voltage of 3V, with a 1kΩ load the output drops to 2.6V. That means that 1kΩ is drawing (2.6/1000) 0.0026A (2.6mA).  The internal resistance is dropping (3 - 2.6) 0.4V, therefore the internal resistance must be (0.4 / 0.0026) 154Ω.
Drawing 50mA from the battery would mean the internal resistance would drop (154 * 0.05) 7V. Since you can't get below 3V, that means the battery simply can't support that kind of current drain.  Indeed, in the datasheet I link to the "Standard Current Drain" (the current it's rated for as "normal" usage) is a mere 0.1mA.
So to work out what battery you need, you want:

The average current draw over the period of an hour
The peak current draw the device will draw
The length of time you need the device to run for between battery changes / recharges

For the ESP32 the current can peak at hundreds of mA depending on what you are doing (WiFi uses a lot of power in short bursts). The average will be based on the ratio of the "running" time to the "sleeping" time, and the current draw for both those states.


text:
Antenna for ESP32-pico-d4
I am currently playing a bit around with the esp32-pico-4d, it does not have an onboard antenna, so an external antenna is needed, tho I don't know a lot about it so a little help would be appreciated.
I found this:
https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf
here one says that he literally just connected the antenna to ground and LNA_IN would that work?
and which antennas would you recommend? (as small as possible is only gonna be used for BLE and)
(datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf)

In my experience, an LNA connection typically implies that an antenna with a Low Noise Amplifier is required to meet the specifications - typically for signal strength. That's not to say it absolutely won't work without it, but rather it's typically used.
You'll need to select an antenna first, do some calculations and determine if you have enough signal to make your ESP32's receiver "happy". If your antenna doesn't deliver enough power, you'll have to add an LNA.
Wrt antennas, many boards are made today with the antennas etched from the copper. Some are quite good, and last I checked there were Gerber files available that could be used to replicate them on your PCB (assuming you use a board that meets the specs - dielectric constant is important). Another, maybe easier approach is to buy one of the miniature ceramic antennas - for example Johanson Technology makes them, and they're available from other mfrs through distributors - Mouser, for example. You may be able to wangle free samples - perhaps even some applications engineering support if they believe that will help them sell product!
Another source for antenna recommendations would be the Bluetooth Consortium website. They maintain a list of "prequalified" vendors - including some who make antennas. There may be other resources that would be useful. And don't overlook the usual open source repositories for help... there may be some out there who are hacking the same chip.
Anyway - got carried away - hope this helps.

here one says that he literally just connected the antenna to ground and LNA_IN would that work?

Yes. LNA_IN is the input to the Low Noise Amplifier - the input stage of the receiver / output stage of the transmitter.

and which antennas would you recommend? (as small as possible is only gonna be used for BLE and)

You want one tuned for 2.4GHz. The simplest is a quarter wave dipole at 3.125cm in length. Better would be a proper 2.4GHz antenna of the kind you get on a WiFi router or some USB WiFi dongles.

well i was thinking more around this size:
https://www.molex.com/molex/products/part-detail/antennas/0479480001
its 3mm * 4mm * 3mm

Sure, if there's somewhere to mount it.

what do you mean?

If you're designing the PCB then no problem. If you're trying to attach it to an existing board then soldering it by hand could be tricky.

Of course, if you're designing the board then you could just design in a PCB trace antenna. They're free.

meaning I could just make a wide cobber trace and use it as an antenna as kinda seen on the esp32? (I am designing the PCB myself) and how thick and long would it have to be?

That is really not a question for this site. You should be asking on electronics.stackexchange.com. You've gone too technical for this site now.

ok thanks for the help

@MariusWanscher There is an example schematic in the datasheet where they show a small Pi filter between the chip and the antenna. They don't give component values for it though, just "TBD". Such a filter would improve the SNR but probably isn't essential for basic operation. All balancing is done inside the chip.


text:
Esp32 heating slowly
I made a small little IoT device to control my light chains from my phone, I'm using a MOSFET to turn the power on or off, using an esp32 connected to the MOSFET, both esp32 and light chain is supplied from a standard 6v phone charger I just clipped the wires and used it,
I have a voltage regulator on the esp32 as seen on the image, when I run the system the esp32 slowly heats up to around 40-50 Celcius, and I can hear a small whinny sound from the chip, the esp32 is getting 3.3v as I should when I measure with a multimeter
what's wrong?
(btw it works with turning lights on and off, not sure if those was the resisters i used)

Is that a map of where the nearest starbucks is? If it's supposed to be a schematic it's completely meaningless and impossible to read.

lol, ye sorry I didn't really know any good side to make the schematic on, didn't think it was that important, just wanted to give a general idea of what the circuit was

The question editor also has the function to draw schematics in it. Just click at the "Schematics" button (the one with the little schematic diagram) in the question editor and then you can create a proper schematic, which will directly tie into your question.

There's a schematic editor available right from the editor with Ctrl-M.

Did you build the regulator circuit or is it a pre-built module?

What is connected to what? Are you running your light chain from the output of your voltage regulator? What is the output voltage of the regulator? How are you powering the ESP32? If the voltage regulator is putting out 5V and you're using that to power your light chain and as VIN to your ESP32,  the ESP's voltage regulator is still having to drop 5V down to 3.3. That shouldn't generate a lot of heat unless you are drawing significant current from the ESP's regulator.

My guess is that the phone charger is a bit crappy, and doesn't produce a very stable voltage. I'd try adding a large bulk capacitor between the 6V and GND, to try to lower the, so called, noise.

The esp module has no components on it that can produce sound continuously. Ceramic capacitors can do so when the get ac voltage, but in your case the only ac is the 3.3V line's ripple. Buck converters often make a sound (coil whine). Are you really sure the sound is coming from the esp? 40-50° is not uncommon for an esp when wifi is enabled

after further research I have found out the sound came from the phone charger, probably just the transformer in it, still a bit worried about the temperature since I have never experienced temperature going up because of wifi use


text:
serial port through Rx and Tx want work

my serial connection prints rubbish, but it systematic, so it's not just random as you see on image 1, any help would be appreciated
other info:
the first image of the serial monitor of COM6 is my own serial connection, image nr. 2 is the serial monitor of COM4 which already uses the onboard serial to USB
the last image shows how I made my own serial connection
the 2 black cables are providing around 4 volts, I know these are not necessary cause the USB already provides 5 volts and ground
and oh ye, normally the USB on the last image would be connected to my pc ofc

Is that a USB to RS232 adapter there? RS232 != UART. Also it risks killing your target device through incorrect voltages being applied.

You're using a USB to RS-232 adaptor. That is wrong.
RS-232 is not (electrically) the same as UART.  Not only is the logic inverted, but it uses ±10V NRZ signalling.
That means that when the UART expects a 3.3V HIGH signal the adapter is sending it a -10V signal. When it's expecting a 0V LOW signal it's being sent a +10V signal.
So yes, it's gibberish - it's getting the opposite of what it expects to see - and the excess and negative voltages risk damaging your ESP. Fortunately the currents involved are usually so low that it doesn't damage it straight away, but with prolonged use you can probably kiss your ESP goodbye.
Disconnect that dongle immediately and get a proper USB to UART adapter.

Or implement a RS232 to UART adapter by using the MAX232

@chrisl The MAX232 is probably what's inside there, so you'd be doubling it up and making a "double negative" scenario ;) Pretty wasteful on components and things. Best to do things properly.  But yes, you could do that if you are psychotic enough...

Just check the code by running on all different Baud-rates (in the serial monitor) ..It should normally work on the rate u have declared in the code.


text:
Pulsing 3v into a capacitor to create custom Voltages
I was wondering if it is possible to create diffrent voltages by just pulsing power into a capacitor,
Im using an esp32 which can only output 3v or nothing on its GPIO pins, and i need to make it possible for it to adjust the amount of voltage without anyone touching the device, so i thought maybe you could pulse 3v into a capacitor and the capacitor would only unload what ever the pulses would give in voltages combined, so e.g. 50% 3v 50% 0v, then it gives 1.5v, i have no idea how this would work or the physics behind it
all help would be appreciated

Yes. That's basically PWM through a Low Pass Filter.
Use PWM to set the "duty cycle", which is the percentage of voltage. Then ise a low-pass filter (an inductor + capacitor, or resistor + capacitor) tuned to filter out the carrier frequency (should be around 500Hz if it's the same as an Arduino) to give you a voltage that is proportional to the duty cycle.

simulate this circuit – Schematic created using CircuitLab
That should filter at about 150Hz. The bigger the capacitor the smoother your output will be, but the slower it will be to respond to changes in the specified voltage.  Note that this is not going to give you large currents, but is fine for using as a reference voltage. To boost the current you can feed it into a voltage follower:

simulate this circuit

Just a question: why the resistor is just 100 Ohm? I think having it around 10k is better; this way you can have a smaller capacitor and lower currents. According to your experience is having <1k resistor an advantage?

The smaller the resistor the lower the impedance and the higher the current it can supply. If you x10 the resistor you can /10 the capacitor and the frequency response will be the same, but current in and available current out is reduced. 100r is just the default value in the schematic editor and I sized the capacitor accordingly. The choice is entirely yours what values you use.

BTW, this is a very handy low-pass filter calculator.

ok thanks ;) yes, the output current is directly related to the resistor, but since you put an op-amp just after (so current is virtually 0) I did not understand it. Honestly I did not consider the first schematic, where the lower resistor makes more sense ;) Thank you


text:
3v to 3.5v step up?
I would like to run my esp32 on coin cell batteries, tho it needs at minimum 3v, that means if there just is too much resistance in the vires or anything else, stuff like Bluetooth will make it brownout,
So what is the best way to step up 3v to 3.5v?

To be honest you are better off stepping down rather than stepping up. Simply because step down converters tend to be a higher efficiency and can deliver more current than a step up converter.
With step up converters you effectively convert current into voltage. With step down it's the other way around - voltage into current.  Since button cells have very very little current capacity stepping up will reduce it even more and starve the ESP32 of power. By stepping down you increase the current.
Two 3V button cells in series will provide nominal 6V and about 40mA current. By adding a step down converter to 3.3V you are almost halving the voltage, but at the same time almost doubling the current.  Adding a third cell in series will give you even more current output.
It is possible to get some incredibly tiny and high efficiency step-down modules. I myself make and sell one based around the TPS82130SILT which has the ability to run at as low as 3.7V with a 3.3V output (it has a "pass through" mode which allows a zero dropout voltage, but I include a protection diode with 0.4v drop). That means you get the entire 6V to 3.7V range out of your batteries before the voltage starts to droop (assuming the batteries still operate at 1.85V).

Why not use three button cells and a buck converter to lower the voltage from 4.5V down to 3V?

haven't read on buck converters, is it just a kind of step down?

I want to only use 2 coin cell batteries, for the size, it wouldn't be the biggest disaster to make it a bit bigger to fit 1 more battery, but the buck converters I found online looked pretty big, Too big

@MariusWanscher in general, both buck and boost converters consist of the same components and they both exist in very small dimensions

@MariusWanscher I make a really really really tiny buck converter. You can't get smaller. It will run from 2x 3V cells in series (or 3x if you can) and down to 3.3V on the input for 3.3V output. https://www.ebay.co.uk/itm/183933078163 - however I can't guarantee that the ESP8266 will like the low current output of button cells.

Generally, to step up voltages you can use a boost converter.
But I doubt that using coin cells to supply an esp32 is a good idea, because they probably won't last very long and are relatively expensive. Even if you use sleep modes, the voltage margin will be small (of course, that depends on the boost converter).

well the esp will only be active 4-6 times a day, and only in a few seconds for sending information to a database, the rest of the time it will be in deep sleep

it's going to run on 2 3v 260mah coin cell batteries, I calculated it to be about 5 months of run time

i could be wrong tho

Alright, I personally just don't like using coin cells and till now I always had enough space for a bigger LiPo. The converter will have some losses, but maybe that's fine...

well i want the final to be as slim as possible, since there already needs to be place for pcb and chip, 2 coin cell batteries on the back of the pcb would be perfect

well, i asked for a good converter, do you have any recormendations?

Well, we don't do product recommandations. Simply go to your prefered distributor's website and search for "switching voltage regulators". Go for a high switching frequency, this will allow you to use small capacitors and inductors


text:
Connect 5v 30a relay with Arduino Uno
I have previously connected 5V 10A relay switches to my Arduino.
But for my new project I need to use a 5V 30A relay switch with my Arduino.
In 10A relay switches, we make connection with Arduino using GND, VCC and IN.
But for 30A switches, there are DC+, DC-, IN.
My question is that, how do I connect my Arduino to the relay using these pins?

DC+ = VCC. Dc- = gnd. In = in.

@Majenko Thank you! That answered my question. So, how do I close it?

You can mark Hobbes' answer as accepted. (Majenko was faster, but he does not seek the merits, obviously)

Plus I was in bed and using my phone, so it's easier to just drop a comment so the OP has the answer they need then later, if it's still needed, craft a proper answer. :)

From the Amazon page you linked to:

1 dc+ : Dc power supply positive pole
  2 dc- :Dc power supply negative pole (i.e. ground)

Arduino:
VCC: positive DC power supply
GND: ground
technically, VCC = the voltage at the collector of a transistor, these days it's used as shorthand for the positive output pin of an IC.


text:
RFM69 Sending Failure
Hi I'm trying to get the RFM69 rf module to work on an arduino uno.
Here is my code:
#include <SPI.h>
// Addresses for this node. CHANGE THESE FOR EACH NODE!
#define NETWORKID     0   // Must be the same for all nodes (0 to 255)
#define MYNODEID      2   // My node ID (0 to 255)
#define TONODEID      1   // Destination node ID (0 to 254, 255 = broadcast)
// RFM69 frequency, uncomment the frequency of your module:
//#define FREQUENCY   RF69_433MHZ
#define FREQUENCY     RF69_915MHZ

// Create a library object for our RFM69HCW module:
RFM69 radio;

void setup()
{
  // Open a serial port so we can send keystrokes to the module:
  Serial.begin(9600);
  Serial.print("Node ");
  Serial.print(MYNODEID,DEC);
  Serial.println(" ready");

   if(radio.initialize(FREQUENCY, MYNODEID, NETWORKID))
     Serial.println("Initialized Successful");

  radio.setHighPower(); // Always use this for RFM69HCW
}

void loop()
{
     bool test = radio.sendWithRetry(TONODEID, "Hi", 2);
    Serial.println(test);
}

which outputs
Node 2 Ready
Initialization Successful
Node 2 Ready
Initialization Successful

which means that the sendWithRetry function is not returning a bool as expected, but I can't figure out why.
I am using the code given in the github
https://github.com/sparkfun/RFM69HCW_Breakout/blob/master/Libraries/Arduino/RFM69/RFM69.cpp which shows the nitty gritty of the RF69 Module and its arduino code.
I hooked up the hardware according to
https://learn.sparkfun.com/tutorials/rfm69hcw-hookup-guide/all
and checked all the wiring, so the I concluded that the problem was software based.
Any ideas why this isn't working?


text:
How to enable auto reset in Arduino Leonardo?
I am  trying to program an ATMega32u4 microcontroller through arduino IDE. I have added external oscillator(16Mhz) and capacitors and few other connections according to the Schematic. I had put a sparkfun bootloader onto it(caterina) using Avr Pocket Programmer. A usb 2.0 is connected to the microcontroller. Arduino IDE recognizes microcontroller as Arduino Leonardo with the help of this usb. Bootloader file.
I was able to upload codes into the microcontroller but the issue is, I have to put the reset pin to ground momentarily each time when the IDE goes to uploading stage.
If i do not reset it, the COM Port for leonardo disappears but it never comes back until I reset it manually and therefore the uploading bar just gets stuck. I have also added the circuit connected to the Reset Pin according to the schematic but even if i remove all of it and just connect a switch, no difference can be observed. No power on reset is working.
Since one can upload codes without having to manually reset each time in Arduino Leonardo, I was wondering what could be the issue here.
Is there a way to auto reset this? Or perhaps fix the auto reset issue in this case?

how is it done on rhe Leonardo?

did you look at the Leonardo schematic?

The leonardo should reset if you open the serial port at 1200 baud then close it again. If there is no serial port showing then your sketch isn't creating one, or your sketch isn't running properly.

Yes, I did try that and it works. However, I would need to do that while uploading the code quickly, else the code won't upload. Again, it's not exactly an automated thing.