text:
analogRead() doesn't read more than 500Hz
I connected a wave generator to the analog pins to read the frequencies of the waves generated. I used different frequencies of sine waves with a minimum of 0V and maximum of 5V.
Whenever the voltage is greater than 2.5V, I made one of the digital pins HIGH, and LOW when less than 2.5V. Now by measuring the square wave from the digital pin, it always has the same frequency as the sine waves until 500Hz.
After 500Hz, the square wave's frequency doesn't agree with the sine wave, which made me think that the problem is in the analogRead(). Is there a way to have higher frequency?
Code:
const int sensorPin1 = A0;
const int sensorPin2 = A1;
const float maximumPower = 2.5;
int calibration = 1;

void setup() {
  Serial.begin(57600);
  pinMode(6, OUTPUT);
  digitalWrite(6, LOW);
}

void loop() {
  int voltage2 = 3;
  int voltage1 = 3;
  int sensorVal = abs(analogRead(sensorPin1) - analogRead(sensorPin2));
  float ratio = abs(analogRead(sensorPin2) / analogRead(sensorPin1));
  float voltageDifference = (sensorVal / 1024.0) * 5.0;
  float power = calibration * voltageDifference;
  if (power >= maximumPower || voltage1 <= 1 || voltage2 <= 1) {
    digitalWrite(6, LOW);
  }
  else {
    digitalWrite(6, HIGH);
  }
}

Have you googled for this? When using terms like "analogread higher sample frequency" or similar, you can find solutions for this (basically just changing the prescaler of the ADCs clock). Have you read some of these results?

500 Hz seems a bit low. I would have expected something like 4 kHz. Do you realize that you need at least two samples per cycle? What Arduino are you using? Can you show us your code? Why are you using analogRead() instead of digitalRead()? What sampling rate would you need for your application? What analog resolution? What are you trying to achieve?

analogRead() is slow. digitalWrite() is slow. Combine the two together and it's slowly slow. Throw floating point maths into the mix (you mention 2.5V not 512) and it crawls to a snail's pace. Why are you using an Arduino at all for this? The same can be done with a simple comparator (op-amp).

@Majenko: Even using floats and digitalWrite(), I still get more than 7200 iterations per second on an Uno.

@EdgarBonet Halve that for nyquist-shannon, so 3600. No mention of what he's running on - it could be a breadboard Arduino off the 1MHz internal (div-8) clock. So divide that by 16, and you're down to a mere 225Hz...

May be relevant: https://arduino.stackexchange.com/q/67295/38721

sorry for late reply. I added the code. Thank you all

You have 4 calls to analogRead() in your loop. At about 112 µs per
call, that's already taking 448 µs. Add to that the time taken by the
floating point calculations, and you are likely to end up with something
in the order of 500 µs per loop iteration. This should give you a
sampling rate close to 2 kHz, which should allow you to detect the highs
and lows of an input signal up to 1 kHz, provided the duty cycle is
close to 50%.
There are a couple of easy optimizations that could be done here. Two of
the calls to analogRead() serve no purpose, as the results are never
used. And the floating point calculations are also pointless. The whole
loop can be simplified to this:
void loop() {
    if (abs(analogRead(A0) - analogRead(A1)) >= 512) {
        digitalWrite(6, LOW);
    } else {
        digitalWrite(6, HIGH);
    }
}

This should take about 224 µs per iteration. If you need to go faster,
you will have to increase the working frequency of the ADC. This can
cost some accuracy, but if accuracy is not critical to your application,
it can be a good trade-off. See Nick Gammon's page on the Arduino
ADC for details. If that's not enough, you will have to use
external components, e.g. an analog subtractor made from an op-amp, and
a couple of comparators.


text:
WifiClientSecure connect returns 0 ( fail ) except for www.google.com which connects
So to wile away the long lockdown and curfew hours I decided to get out a stack of Wemos D1 mini ESP8266 boards and build simple indoor temperature and humidity sensors ( using an SHT30 and feeding the data into Graphite or Influx ). I'm using the WifiClientSecure library but its connect() function returns 0 ( false/fail ) every time I try this except when I connect to www.google.com. I've tried connecting to various other servers, both port 80 and 443 but they all fail. I can connect to all of these server absolutely fine from my network so it's not a firewalling issue. The D1 does get an IP and has DNS ( in fact, in my full sketch I'm using NTP with pool.ntp.org and that works fine ).
I've created a simple test ( https://gist.github.com/mkraats/1d1b11691c179793c799fcbb21e5debe ) with just the connect to WiFi and connect() but I still get the same results.
This code:

    char servername[]="www.google.com";

    int connectval;
    connectval = client.connect(servername, 443 );
    Serial.println("...");
    Serial.println(connectval);
    Serial.println("...");
    delay(12000);

}

Works fine while this:
void loop() {

    char servername[]="graphite-us-central1.grafana.net";

    int connectval;
    connectval = client.connect(servername, 443 );
    Serial.println("...");
    Serial.println(connectval);
    Serial.println("...");
    delay(12000);

}

Does not. What stupid mistake am I making that I am not seeing? :-)

graphite-us-central1.grafana.net does not seem to listen on https port 443

@SimSon I checked on my PC with curl https://graphite-us-central1.grafana.net:443 . That worked. So I guess, it does serve https on port 443

No, https://downforeveryoneorjustme.com/graphite-us-central1.grafana.net works, so it definitely does listen.

do you have All SSL ciphers (most compatible) selected in Tools menu?

Yes, that is selected. It also wouldn't explain why plain old HTTP port 80 doesn't work.

does the site allow unsecure connection?

source: Stack Exchange

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

sort: votes


text:
Can I run 3 motion sensors with a voltage regulator?
I want to power 3 hc-sr501 PIR motion sensors with a voltage regulator that can output 5v-1A.
If I make such a system, will there be a noise?

You need to add up the current demand of each of the 3 PIRs.  Usually a power supply is chosen which can supply at least double the expected current demand.  What is the part number of the PIR?  Also, do not forget to add the current demands for all other components such as the Arduino board.  Which Arduino board are you using?  Noise is a complex problem.  Not only is a clean power source needed to mitigate noise, but short cables and a electrically clean environment just to name a few possibilities.

i am using only atmega 328p.  to sensors is hc-sr501.

Many internet sources like this one claim the HC-SR501 requires less than 50uA (or 0.00005 Amps).  Likely this is only in a quiet or quiescent state and current demand may increase initially when power is applied and when motion is detected.  Regardless, this is an insignificant fraction of a 2 Amp power supply.
Likely the Atmel 328p will require several times the total current of the 3 PIR sensors added together.  Still, the over all current of the described project (1 processor and 3 PIRs) is expected to be far less than half the capacity of a 2 Amp power supply.
It is suggested to keep the PIR to Arduino wires as short as possible to avoid noise.  It would be preferable they only be several inches (10s of centimeters).  And certainly not as long as several feet (a meter).

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


text:
Efficient workflow/tools for converting color images to hex arrays
I would like to display 65k color animated gifs on my oled. I'm using the adafruit library for https://learn.adafruit.com/096-mini-color-oled
Now I need to convert a significant number of images to hex arrays. I found a couple of tools that can deal with monochrome images and I found this: https://www.digole.com/tools/PicturetoC_Hex_converter.php which might work for individual images, but is impractical for batch processing. I also found this, but it appears to also be intended for individual images and doesn't simply work in wine. So isn't there some linux commandline magic to do that?

You could have a look at ImageMagick. I think you want to export the image as RGB565 format. This will give you raw bytes. So you can use, for example, xxd to convert this to hex. Not sure what you mean with hex array.

your question is not about the arduino, so it does not belong here .... it may be a better fit at https://softwarerecs.stackexchange.com/

@jsotola "Arduino Stack Exchange is a question and answer site for developers of open-source hardware and software that is compatible with Arduino." - my question is about how to convert graphics to an arduino compatible format to use in programming it. IMO it's covered under questions regarding "software that is compatible with Arduino". WIth that being said, I already got my answer.

I found this plugin to be satisfactory: https://khalim19.github.io/gimp-plugin-export-layers/
It's not a single elegant command, but is quite fast and maybe can be optimized with some scripting.


text:
Storing data in Arduino Portenta H7's SDRAM
I am working on storing data from Portenta H7's ADC through a high sample rate (>100kSa/sec) per channel. I am using 2 ADC channel for my work.  Through the forum, I learned that the serial. print command reduces the sampling rate. Therefore one of the suggestions was to use the onboard available Portenta H7's 8MB SDRAM to store the sample values and then retrieving them after the sampling period. My sampling time is between 3-5 seconds so it is well within the storage limit of this SDRAM.
However, since I have no previous experience with microcontrollers, I am struggling to find a starting point for accessing this SDRAM for saving my data?  Any suggestions from your side are most welcomed.
Please do recommend If you have any other ideas about managing the data for faster sampling.
You can find the Portenta H7 information here. https://store.arduino.cc/usa/portenta-h7. Portenta has STM32H747 dual-core processor.
Thank you all.

The Portenta has 8 MB (megabytes, not gigabytes) of SDRAM. 2. You shouldn't have to do anything special for accessing the RAM. Just create a couple of arrays (one per channel) large enough to hold your data burst. The compiler should allocate RAM space for them.

#include <SDRAM.h>

SDRAMClass ram;
uint8_t *b;
void setup() {
  ram.begin();
  b = (uint8_t *)ram.malloc(320 * 240 * sizeof(uint8_t));
}

The way to do it is to use the SDRAM library for the portenta. Above you see an example for a uint8 array.


text:
How to change ArduinoOTA upload timeout?
I'm using ESP8266WiFiMulti, ESP8266WebServer and ArduinoOTA to communicate with my device and perform over-the-air-updates. Everything was working perfectly until I moved the ESP8266 further from the WiFi router. The OTA upload slowed down, which caused upload timeouts after 5 seconds. It fails at a different point each time, usually between 30% and 60%.
How do I increase the OTA timeout to 30 seconds?
Here is the setup code, let me know if you need more:
void startWiFi() {
    ESP8266WiFiMulti wifiMulti;
    wifiMulti.addAP(ssid, password);
    wifiMulti.run();
}

void startOTA() {
    ArduinoOTA.setHostname(_hostname);
    ArduinoOTA.setPassword(_password);

    ArduinoOTA.onStart([]() {
        Serial.println("Start OTA");
    });
    ArduinoOTA.onEnd([]() {
        Serial.println("\nEnd OTA");
    });
    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
        Serial.printf("OTA Progress: %u%%\r", (progress / (total / 100)));
    });
    ArduinoOTA.onError([](ota_error_t error) {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
        else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
        else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
        else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
        else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });
    ArduinoOTA.begin();
}

The only timeout I can find is in the espota.py script itself. That is riddled with such lines as:
sock.settimeout(10)

You would need to scour that program and change them all.
However
ArduinoOTA uses UDP for communication. Because of that it is unreliable (yes, that's a technical term). It doesn't have any form of retransmit / retry, so if a packet is lost it's lost for good. No amount of increasing of timeouts will make that packet reappear.
So increasing your timeouts most likely will just make it wait longer before failing.
You should consider switching to a more reliable update system which uses TCP instead of UDP - such as downloading an update from a website using ESP8266httpUpdate.
Update:
ArduinoOTA uses a combination of both UDP (to initialise and authenticate the connection) and TCP (to make a "back channel" connection back to your computer) to download the actual binary.
The same still applies: you will need to alter the espota.py program to change its timeouts (sock2 is the back-channel object), but there is also one line in ArduinoOTA.cpp that will need to be altered to increase timeouts.  Line 294:
int waited = 1000;

This is not strictly the number of milliseconds to wait for incoming data, but it's not far off - it's a 1 millisecond delay in a loop while looking for incoming data.  Increasing that will allow more time for the ESP8266 to wait for data to arrive.
But of course, with an unstable WiFi connection YMMV...

Thanks for the reply! What's the point of using UDP for firmware upgrades, a critical function? I'm using LittleFS file system, so I can also upload the file, then find a library to do the program switch.

It's fast, easy to implement packets, light weight and reliable enough for most uses. You're a corner case.

I meant why does ArduinoOTA use UDP instead of TCP? That seems like a bad design decision. Firmware updates should be lossless.

For the reasons I just stated. It's considerably easier and lighter weight and faster to write a packet based protocol using UDP compared to TCP.

No! It's not unreliable software. UDP is an unreliable protocol. Not that is flakey or badly written. It is unreliable. It's the official term for that kind of protocol. A protocol with no built in retransmit facility is called unreliable. ArduinoOTA is very well written and is itself very reliable and secure. The fact that it doesn't work on your network is down to your network losing packets. Get a better wi-fi signal or don't use ArduinoOTA. It's intended for development, not production. No one in their right mind would use ArduinoOTA for production, they'd use an HTTP server based.

You're right, I just chose the wrong library for my needs. I should have designed for being able to change rooms. I will find a more reliable solution. Thanks for your answer!

@Majenko The official term is connectionless which simply means the UDP protocol has no provisions for the receiver of a packet of sending an Acknowledgement to let the sender know each packet has been received. That does not mean you can't build reliable protocols using UDP. Reliability has to come from higher level protocols built on top of UDP.

@Majenko, espota.py and the ArduinoOTA library uses TCP to transfer the binary

@Juraj So it does. It initiates the connection with UDP first then the ESP8266 makes a reverse connection to the computer running espota.py to pull down the binary. Serves me right for trying to decipher Python at 2 in the morning. It's bad enough at the best of times when I'm full of coffee...

@StarCat Back when I was at university it was called Unreliable vs Reliable transmission. Transmission that doesn't retry vs transmission that retries. Maybe it's a regional thing.

@Majenko, it seems you are also correct, although there is a difference between the definition of an unreliable protocol and a connectionless protocol (had to look it up). For UDP both are true.

@StarCat Connectionless is about state, reliability is about re-sending packets. The two are usually used or not used in tandem. I guess you could have a stateless (connectionless) reliable protocol, or a stateful (connectionful?) unreliable protocol...


text:
Can't make Quadratic Programming Library (EigenQP) library work in NodeMCU
I have been trying to use find a Quadratic problem solver library which is compatible with Eigen library for my NodeMCU board (In my code I have to deal with a lot of matrix operations, that's why I chose Eigen)
I found the following one by jarredbarber : [https://github.com/jarredbarber/eigen-QP][1]
For some reason, I'm not being able to use the QP library in my nodemcu. Here is one very simple demonstration I've been trying to establish. But it throws away some errors, I can't figure why :
In my sketch for the NodeMCU:
#include <Arduino.h>
#include <EEPROM.h>
#include <Wire.h>

#include <iostream>
//#include<ctime>        //srand()
#include<cstdlib>

#define _USE_MATH_DEFINES
#include <cmath>        // for using M_PI, Trig. functions (sin/cos/tan)
using namespace std;

//#include <ArduinoSTL.h>
#include "Eigen313.h"
using namespace Eigen;

#include "eigen-qp.hpp"
using namespace EigenQP;

//#define PI 3.1416

void setup() {
  // put your setup code here, to run once:
  Serial.println("Lets start!!");
int N=4;
float gamma =10000;
float safety_radius=0.1200;
  Eigen::Matrix<float,Dynamic,Dynamic> Q(2*N,2*N); Q.setIdentity();
  cout<<Q<<endl;
  Eigen::Matrix<float,Dynamic,1> c(2*N,1);
      c<<0,
         0,
    0.0086,
    0.0847,
   -0.1499,
    0.0687,
    0.0083,
   -0.0867;

    Eigen::Matrix<float,Dynamic,Dynamic> A(6,2*N);
  A<<0.0655,0.6483,-0.0655,-0.6483,0,0,0,0,
    -0.5839,0.6251,0,0,0.5839,-0.6251,0,0,
    -0.5587,-0.0275,0,0,0,0,0.5587,0.0275,
     0,0,-0.6494,-0.0232,0.6494,0.0232,0,0,
     0,0,-0.6242,-0.6758,0,0,0.6242,0.6758,
     0,0,0,0,0.0252,-0.6526,-0.0252,0.6526;
std::cout<<"A:\n"<<A<<endl;
    Eigen::Matrix<float,Dynamic,1> b(6,1);
b <<7.7197,
   47.8600,
    2.6007,
    7.5770,
   76.6646,
    7.8461;

    A=-A;
    b=-b;
Eigen::Matrix<float,Dynamic,1> x(2*N,1);
yield();
delay(2000);
        //boost::timer::auto_cpu_timer t;
        //for (int ii=0; ii < 8; ii++)
        //QPIneqSolver::solve(&H,&f,&A,&b,&x);
EigenQP::quadprog<float,Dynamic,Dynamic>(Q,c,A,b,x);
std::cout<<x<<endl;

}

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

}

It compiles fine, but in the serial monitor, these show up :
 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 3584, room 16
tail 0
chksum 0xb0
csum 0xb0
v2843a5ac
~ld

I tried to run the same code in codeblocks software in my computer, it works fine though.
PS: This is the first time I've ever posted any topic in this forum, please inform me if I've violated any guideline for the post..
Thanks in advance.
[1]: https://github.com/jarredbarber/eigen-QP

what prints in the serial monitor if you compile and upload a simple LED blink sketch?

Serial.begin is missing

FYI: Don't use all uppercase in the title, it's the same like SHOUTING to the audience. Not very polite ;-). In addition to what was already commented: How do you upload the sketch? Please add the output from the upload to the question. -- Why did you tag the Question with "reset"?  -- You have std::cout calls in the code. What's their meaning for an ESP? (I don't know that, it's an open question, not a rhetoric one). Try if the sketch works without the cout. Just use Serial.prinl("cout debug 1"), Serial.prinl("cout debug 2")  (and so on) instead out the std::couts.


text:
Whats wrong with my POST request?
Ive been trying to get POST working on my ESP8266. I followed this tutorial https://techtutorialsx.com/2016/07/21/esp8266-post-requests/ which works, but once i change the request URL to anything else i get -1 response from http.POST() which the library returns when "no info".
I have no clue what the "no info" means and what im doing wrong. Does anyone have any suggestions? Below is the code im using.
if (WiFi.status() == WL_CONNECTED) { //Check WiFi connection status

    HTTPClient http;    //Declare object of class HTTPClient

    //http.begin("http://192.168.1.88:8085/hello"); //Works fine
    //http.begin("https://httpbin.org:8080/post"); //Causes -1 as httpCode
    //http.begin("https://httpbin.org/post"); //Causes -1 as httpCode
    http.begin("https://XXXXX.execute-api.eu-west-2.amazonaws.com/XXXXX/XXXXX");
    http.addHeader("Content-Type", "application/json");  //Specify content-type header

    int httpCode = http.POST("{\"key\":\"1\",\"id\": \"ESPXXX2\",\"action\": \"rbg\",\"value\": \"255255000\"}");   //Send the request
    String payload = http.getString(); //Get the response payload

    Serial.println(httpCode);   //Print HTTP return code
    Serial.println(payload);    //Print request response payload

    http.end();  //Close connection

  } else {

    Serial.println("Error in WiFi connection");

  }

  delay(10000);  //Send a request every 10 seconds

Only serial output im getting is "-1" for httpCode and empty line for payload.

Have you noticed the one thing that differs between all the URLs that fail and the one that works?

so try again http.begin("https://httpbin.org/post"); with http.POST

@Majenko, ESP8266HTTPClient library supports https

@Juraj Yes. if you set it up right...

@Majenko its the https thats causing the problem? I tried following another guide (https://circuits4you.com/2019/02/08/esp8266-nodemcu-https-secured-post-request/) but still no luck, cant seem get past connect. Had no trouble doing this in postman, js and python.

I never used it, but now I see begin(url) is deprecated. Client object should be supplied. @Slurba, see the examples

@Juraj Thanks for the tip, using the nondeprecated functions i got error 400 from begin(WiFiClient &client, const String& url) and -1 again from begin(WiFiClient &client, const String& host, uint16_t port, const String& uri = "/", bool https = false). I dont see a function that helps me set the port or fingerprint (if thats needed) so im not sure which function is correct

see BasicHttpsClient example

I ended up ditching HTTPS since it doesnt seem to be implemented all that well (Requires hardcoding of fingerprint).
Changed the architecture of my system so that HTTPS is handled by Python which doesnt require jumping through hoops.


text:
Recommend an Arduino Uno shield to monitor the state of 5 DPDT electrical switches
I have a project where I need to monitor the state of 5 DPDT electrical switches with Arduino Uno. Also, the Arduino board will be measuring the output from 3 thermocouples on 3 of the analogue pins as input and sending signals to open and close 3 relays for heaters on the 3 of the digital pins as output. The data with the state of the microswitches and the measurements from the thermocouples will be send over a serial connection to a PC.
I think I need a shield with at least 20 inputs for monitoring the 5 DPDT electrical switches (5 x 2 x 2). The common of the switches will be connected to a common rail. Can I use an I2C extension shield for this purpose? Is this going to create an issue with the serial connection? Any specific shield recommendations?

It is unclear what you are asking. Do you have 5 switches that you want to wire to an Arduino, or do you have some existing system which has 5 switches and you need to monitor the state of those switches?

Hi, the system is not yet built it is something that is being planned. I will have 5 DPDT switches that I want to wire to an Arduino. My question is on monitoring the state of the switches, because there are not enough pins on the Arduino Uno, and I do not have much experience with extensions shields. I wrote about the TC and the relays, so that it is clear that I will be using also 3 analogue and 3 digital pins on the board for another purpose.

Unless they are on-off-on switches you only need one input per switch - so 5 inputs.

1 DPDT switch has 2 NC, 2 NO and 2 COM pins, I think I need 4 pins for the 2 NC and 2 NO, the 2 COM are going to be connected to a common rail.

Just because there are two switches ganged together it doesn't mean you have to read them both. If you know the switch is in one position you also know it isn't in the other. Thus you only need one input. Common to ground, one side of the switch to input. Input to Vcc through resistor (or internal pullup). Just like any other switch. You're over-complicating it. Ignore 4 of the 6 connections - they are completely meaningless.

Have you found a way to make the two Poles of a DPDT switch be in different states? Or have you found a way for the direction that a DPDT switch to be Thrown in to be more than two choices?

Hi, I want to check the state on the 2 NC and 2 NO, I know that if DPDT switch is turned this changes the state for both circuits from one to another. However the reallity is that sometimes DPDT get a faulty circuit, the DPDT turns but only one of the circuits switches, because the other is faulty. Also there are cases of open circuit in switch connections, so if a i.e. NC is turned to NO, the NC circuits opens, but the NO is not closed and the other way around. I want to get the state of all contacts, so that I am sure the switches turned and that they do not have faulty circuits.

Those kind of failures only really happen from contact arcing - something you will never see with an Arduino.

what will the relays switch? (voltage, current, ac/dc)

The relays are SRD-05VDC-SL-C and will switch 230 AC voltage. They are on a board with other components. The board is powered by 12 V adapter and has input pins for the Arduino. The DPDT switches will switch low current signal.

If you're really set on measuring the state of every single connection of every single switch (though I still don't see the need) then yes, you'll need 20 IO connections.
You could create those with IO expanders (MCP23017 for example), or you could use multiplexing.
Instead of 4x5 (20) IO pins you'd instead need 2+10 (12) IO pins.
Treat all the "Common" connections as the rows of a keypad and all the NC and NO connections as the columns of a keypad. Add a smattering of diodes to isolate everything, and you can then scan through the switches one at a time checking each of the two switch states.
You can read more about keypad matrices here.

Thank you, I will try with MCP23017.

@Iliya They provide 16 IO, so you will need two of them. They can be chained together though.

Consider posting your schematic, not a frizzy thing showing all connections. On the switches just show a few of them so we understand what is happening.


text:
How to use this confing function
For INA3221 current sensor, I found this library, however, I don't understand how to use the INA3221SetConfig() function as defined in the .cpp file link.
void SDL_Arduino_INA3221::INA3221SetConfig(void)
{

      // Set Config register to take into account the settings above
      uint16_t config =
          INA3221_CONFIG_ENABLE_CHAN1 |
          // INA3221_CONFIG_ENABLE_CHAN2 |
          // INA3221_CONFIG_ENABLE_CHAN3 |
          INA3221_CONFIG_RESET |
          INA3221_CONFIG_AVG1 |
          INA3221_CONFIG_VBUS_CT2 |
          INA3221_CONFIG_VSH_CT2 |
          INA3221_CONFIG_MODE_2 |
          INA3221_CONFIG_MODE_1 |
          INA3221_CONFIG_MODE_0;
      wireWriteRegister(INA3221_REG_CONFIG, config);
    }

It seems like the function is called automatically when the .begin() function is called and whatever is defined in the config function is written to the register. The use of | operator confuses me. I tried to comment out the some settings to see if it works but it makes no difference. There isn't any documentation so I am in a fix. Could you please tell how can I change the configuration settings e.g. instead of all the three channels or change the config_mode?

this is not an arduino related question ... it is a general programming question that may be a better fit at https://stackoverflow.com/questions

Without looking at the library, you can check yourself if this method (INA3221SetConfig) is called from the begin method (of the same class). Just trace back the methods manually until you find a call to this method.
About the | or 'bit-wise-or' operator (see https://en.wikipedia.org/wiki/Bitwise_operations_in_C), these are used to set bits in a byte/word/long.
Most registers have 8, 16 or 32 bits and with the | operator you can easily set multiple bits at the same time. Each value (e.g. INA3221_CONFIG_ENABLE_CHAN) has a value that is a power of 2 (mostly defined in the form 1 << ..something.. you can add them (with +) or | them together, but | is more clear what the purpose is and repeatedly calling | the same bit twice is not a problem (it still gives the same result).

I had to learn about bit -wise operations and manipulations and it becomes understandable :) Thanks for pointing me in the right direction

You're welcome, good luck with your project


text:
How to know if a tof VL53L0x sensor is dead or not
I bought a bunch of VL530X time-of-flight sensors on Aliexpress. They seemed to work fine. Then I connected two of them on the same Arduino Uno board to test with the Adafruit example "dual". During rewiring I may have used the 5v power pin of the Arduino instead of the 3.3v (I can't remember).
Now the sensors won't boot. They fail during setup with error -6 which is documented as "RANGE ERROR".
Yet, scanning for either of them does find a sensor at the default address 0x29.
How can one know if they're dead or if they can somehow be revived?
The Uno works fine with any other VL53L0x, just not those two. I could certainly just trash the ones that won't boot but I would be interested in a procedure to know for sure; it would be very useful when going into production.
The last answer on this thread an ST forum points to the I2C bus, but I don't understand what is being recommended.

If others work and these don't, and the wiring and code is the same then yes, they are dead. What about them has died? Impossible to tell. It's basically one chip on a board. Maybe the laser diode has burned out. You could try inspecting it with your mobile phone camera which may be able to see the infra-red light - try it with a good one first and compare it. Not much else you can do beside that.

Thank you. What is confusing to me is that they respond to scanning. I was hoping there would exist some probing software that would be able to diagnose the problem further...


text:
ESP8266: #include <Keyboard.h> causes fatal error: HID.h: No such file or directory
OS: Mac
Arduino: 1.8.13
Keyboard Library: 1.0.2

I have a generic ESP8266 board, and I have the following code
void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BUILTIN, OUTPUT);
  Keyboard.begin();
}

void loop() {}

However I get the following ouput:

In file included from /Users/quba/Sandbox/sketch_feb07a/sketch_feb07a.ino:1:0:
/Applications/Arduino.app/Contents/Java/libraries/Keyboard/src/Keyboard.h:25:17: fatal error: HID.h: No such file or directory
#include "HID.h"
                          ^
compilation terminated.
exit status 1
Error compiling for board Generic ESP8266 Module.
Could not find boards.txt in /Users/quba/Library/Arduino15/packages/arduino/hardware/megaavr/1.8.7. Is it pre-1.5?

The Keyboard library is for Arduino ATMega32U4 based Arduinos (and other similar ones with USB) only. The ESP8266 does not have USB, so how can it possibly use the Keyboard library?

I have added a picture so you can see the TX and RX pins, as well as the USB

The keyboard library is meant for devices that can talk DIRECTLY to the USB bus, like the AVR ATMega32u4. The ESP8266 on the NodeMCU you show in your picture does not have that capability but it has a separate Serial-to-USB chip that's able to talk to a PC via USB. Even then, it can only act as a peripheral to a PC and not as a USB "Master" that's able to control its own USB peripherals (like a keyboard).


text:
RFM95 digital io to control mute on PAM8403 to get rid of hiss while receiving
I am building a solution with an ESP32, a PAM8403 amp, a parallel TFT display, and a RFM95 LoRa module. All works great but I want to get rid of the noise that is generated when Lora is in receive mode.
I can do this by pulling pin 12 low on the PAM8403, which mutes all sound. However I have ran out of output pins on my ESP32, and it's too late to use a IO expander as the PCB has been built.
My initial idea was to use the RX/TX pins on the ESP32 when the unit was out of diagnostics mode. However if I can avoid this then that would be great. In my code when I issue Lora.sleep() / Lora.idle() the hissing goes away.
So I started to wonder if I could just trigger the mute function through another logic state that goes low when LoRa is idle and high when sleeping (allowing the mute to deactivate).
I am using the LoRa library by Sandeep Mistry, and I was wondering if I could use DIO1, DIO2, etc. as an IO PIN to control mute. If not, is it possible to use any of the already connected pins to behave in the desired way?
Thanks all in advance!

It looks like not. The DIO pins can be set to indicate specific events, none of which are sleep / idle.

Thanks @Majenko - would there be any events that can be spoofed from the user side (ESP32 / programatically) that would hold one of the pins Low? During the mute period I do not want to use the lora board, just use it to change states...

Actually what if I disconnect the reset pin and connect it to the ESP32, would this not free as PIN up? or are there issues down the road in not having a dedicated reset pin for the RFM95..

Yes, it looks like you could re-purpose reset. The library only uses that in begin() and there is a special case checking to see if the reset pin has been set to -1 in which case it ignores it. So you could tie nRESET to +3.3V and use your reset GPIO pin for another purpose if you use the setPins() function to change nRESET to -1.

Thanks @Majenko I knew there would be a way somewhere.... so I have my TFT Reset and capacitive touch Reset connected together. Should I connect the Reset for rfm to these or is there actually no need to have a reset connection? Or even the esp32 reset...

Reset can put things into a known good state, so it's handy to have. Sure, one big master reset to reset all your peripherals at startup is good. I'd avoid the ESP32's reset though as that is fiddled with when uploading code.

No, there is no way you can use the DIO pins to indicate sleep mode. They can only be set to indicate certain events, and sleep/idle is not one of them.
However the nRESET pin is optional, and you can use the setPins() function in the LoRa library to change which pin it's connected to - and one option is to set it to -1 in which case the library ignores it (this must be run before .begin() is called) as it's only used during begin() to initially reset the LoRa module.
You could either tie nRESET HIGH (to 3.3V) to never reset it, or couple it with the reset signal of another peripheral so it gets reset at the same time - just be careful with your initialisation order in this case so you don't reset the module after configuring it...

Ah good to know that’s what reset actually does. I have since implemented ad sound effects are now sound much better without the surrounding hiss.


text:
SD card initialize and fails when date changed
i am making a project using Arduino Uno that display data on 7 seg display which stored in SD card as day by day. when i make power ON to device then SD card initialization done & data shows correct as per date. Then after when i change the date SD card failed i.e. "show error opening database.txt" .
How can i overcome with this?
" When debugging my SD Card I had a software error that would put the
card into a state that required the microSD card to be powered down and then
powered up to work. It would work until the software error and then not
work again until the power was cycled. "

what software error?


text:
can't connect paj7620 (gesture detector module) to nodemcu
I'm trying to connect paj7620 to nodemcu micro-controller. I have implemented the following code and it worked perfect on arduino uno. The problem is that I was made to migrate to nodemcu.
Here is my code:
/*
 * Copyright (c) 2015 seeed technology inc.
 * Website    : www.seeed.cc
 * Author     : Wuruibin
 * Modified Time: June 2015
 * Description: This demo can recognize 15 gestures and output the result.
 *              You can adjust the reaction time according to the actual circumstance
 *              by modifying "#define GES_REACTION_TIME  500".
 *
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include <ESP8266WiFi.h>
#include <Wire.h>
#include "paj7620.h"

/*
Notice: When you want to recognize the Forward/Backward gesture or other continuous gestures, your gestures' reaction time must less than GES_REACTION_TIME(0.8s).
        You also can adjust the reaction time according to the actual circumstance.
*/
#define GES_REACTION_TIME       800
#define GES_QUIT_TIME           1000

void setup()
{
    uint8_t error = 0;

    Serial.begin(9600);
    Serial.println("\nPAJ7620U2 TEST DEMO: Recognize 15 gestures.");

    error = paj7620Init();          // initialize Paj7620 registers
    if (error)
    {
        Serial.print("INIT ERROR,CODE:");
        Serial.println(error);
    }
    else
    {
        Serial.println("INIT OK");
    }
    Serial.println("Please input your gestures:");
    Serial.begin(115200);
  Serial.println();

  // Serial.print("Setting soft-AP configuration ... ");
  // Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");

  Serial.print("Setting soft-AP ... ");
  Serial.println(WiFi.softAP("NODEMCU") ? "Ready" : "Failed!");

  Serial.print("Soft-AP IP address = ");
  Serial.println(WiFi.softAPIP());
}

void loop()
{
    uint8_t data = 0, data1 = 0, error;

    error = paj7620ReadReg(0x43, 1, &data);             // Read Bank_0_Reg_0x43/0x44 for gesture result.
    if (!error)
    {
        switch (data)                                   // When different gestures be detected, the variable 'data' will be set to different values by paj7620ReadReg(0x43, 1, &data).
        {
            case GES_RIGHT_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_LEFT_FLAG)
                {
                    Serial.println("Right-Left");
                }
                else if(data == GES_FORWARD_FLAG)
                {
                    Serial.println("Forward");
                    delay(GES_QUIT_TIME);
                }
                else if(data == GES_BACKWARD_FLAG)
                {
                    Serial.println("Backward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Right");
                }
                break;
            case GES_LEFT_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_RIGHT_FLAG)
                {
                    Serial.println("Left-Right");
                }
                else if(data == GES_FORWARD_FLAG)
                {
                    Serial.println("Forward");
                    delay(GES_QUIT_TIME);
                }
                else if(data == GES_BACKWARD_FLAG)
                {
                    Serial.println("Backward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Left");
                }
                break;
                break;
            case GES_UP_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_DOWN_FLAG)
                {
                    Serial.println("Up-Down");
                }
                else if(data == GES_FORWARD_FLAG)
                {
                    Serial.println("Forward");
                    delay(GES_QUIT_TIME);
                }
                else if(data == GES_BACKWARD_FLAG)
                {
                    Serial.println("Backward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Up");
                }
                break;
            case GES_DOWN_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_UP_FLAG)
                {
                    Serial.println("Down-Up");
                }
                else if(data == GES_FORWARD_FLAG)
                {
                    Serial.println("Forward");
                    delay(GES_QUIT_TIME);
                }
                else if(data == GES_BACKWARD_FLAG)
                {
                    Serial.println("Backward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Down");
                }
                break;
            case GES_FORWARD_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_BACKWARD_FLAG)
                {
                    Serial.println("Forward-Backward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Forward");
                    delay(GES_QUIT_TIME);
                }
                break;
            case GES_BACKWARD_FLAG:
                delay(GES_REACTION_TIME);
                paj7620ReadReg(0x43, 1, &data);
                if(data == GES_FORWARD_FLAG)
                {
                    Serial.println("Backward-Forward");
                    delay(GES_QUIT_TIME);
                }
                else
                {
                    Serial.println("Backward");
                    delay(GES_QUIT_TIME);
                }
                break;
            case GES_CLOCKWISE_FLAG:
                Serial.println("Clockwise");
                break;
            case GES_COUNT_CLOCKWISE_FLAG:
                Serial.println("anti-clockwise");
                break;
            default:
                paj7620ReadReg(0x44, 1, &data1);
                if (data1 == GES_WAVE_FLAG)
                {
                    Serial.println("wave");
                }
                break;
        }
    }
    delay(100);
}

------------------------
|paj7620    | nodemcu  |
------------------------
| VCC       | 3.3v     |
------------------------
| GND       | GND      |
------------------------
| SCL       | D1       |
------------------------
| SDA       | D2       |
------------------------

After connecting the ports like the above table, I get the following error when I am trying to upload the code on nodemcu.
Would someone help me how to resolve this error?

Wiring

PS I have also tried I2C Scanner as @timemage mentioned in comments.

PS 2 It works properly when I connect the paj7620 to arduino compiling the above code.

output:

Do you have external pull-up resistors on the I2C bus?  What else, if anything, do you have connected to the board?

@timemage Sorry I am newbie in this field. can't understand what you have said. would you please give me more details?

If you haven't already, run the I2C scanner and make sure your sensor is showing up in it.

@timemage I got the following error:
/packages/esp8266/hardware/esp8266/2.7.4/tools/esptool/esptool.py", line 672, in flash_defl_block self.ESP_FLASH_DEFL_DATA, struct.pack('<IIII', len(data), seq, 0, 0) + data, self.checksum(data), timeout=timeout)  check_command raise FatalError("Failed to %s. Only got %d byte status response." % (op_description, len(data))) esptool.FatalError: Failed to write compressed data to flash after seq 12. Only got 1 byte status response. esptool.FatalError: Failed to write compressed data to flash after seq 12. Only got 1 byte status response.

You need to close the serial monitor before uploading a new sketch, that looks like an upload error.

There's nothing particularly special about the I2C Scanner code with respect to uploading.  So, it sounds like like your talking about separate and distinct problem that should be fixed before continuing on this question.  What I can tell for you now is that until your device shows up in the scanner, it is not worth troubleshooting the device-specific code (sketch or library), because the problem is lower level than that.  Something like having been miswired.

@timemage it was compiled and uploaded on the board successfully. but the output in serial was empty! :(

@MaximilianGerhardt Yeah you are right. after running that code, the output was empty!

Perhaps if you add a clear image of your wiring to your question something will stand out.

@timemage done!

Well the CJMCU board seems to have I2C pull-ups of reasonable size. So, that answers that.  Your purple(ish) wires on center of the left appear to be serving no functional purpose, although they're harmless.  This breadboard appears to only have one set of rails there.  I'm not sure what to suggest except to reduce the wiring, if possible go directly from the 3.3v and GND to the sensor board.

On closer inspection, your SCL pin soldering on the CJMCU module seems not-so-good.  Can you get a closeup picture of that?

It is possible that the three-pin device on your sensor board is a 3.3v regulator and that the intention is to power the board from 5V.  I haven't been able to find any schematics for or proper specs for it though.  So, I'm leery of telling you to try that.  I suppose if you've already been doing that on the UNO and it hasn't killed it, it makes sense to try.  I would fix the soldering first though.

Special thanks to @timemage for his support. After struggling with the board for more than 6 hours it works properly. I will describe and give more details about how the problem was solved later on.
Arduino Uno has 5 Analog inputs, while there isn't any of them on nodemcu. To connect paj7620 to nodemcu, it is noticable that as @timemage said:

"The A4 and A5 on the UNO are where the ATMega328P's I2C bus signals happen to be. Earlier versions of the Arduino UNO and related boards didn't have dedicated SDA and SCL headers as they do now. On those UNO that have SDA and SCL pins on the upper digital header, they are the same exact signal as those found on A4 and A5."

So the first schema was correct.
As it is implied from the fifth page of this link there isn't any difference among 3.3v inputs on nodemcu. But I have changed wiring like the following image and it works!

#COLOR MAPPING
RED: VCC - 3.3v
BLACK: GND
ORANGE: SCL - D1
GREEN: SDA - D2

I hope it helps, cause there isn't any way to trace the problem. :)

When you get a chance, try the load test on your "bad" 3.3v pin.  Just put something on the order of 50 ohms there.  It should draw about 66 mA and pin should stay near 3.3v  If the voltage drops off to nothing, maybe mark the pin somehow so you don't try to use it in the future.  And you know, fix the soldering when you can. =)

You've gotten rather quiet over there since I suggested zooming in on your sensor board.  Just so this question doesn't circulate around in the system for years, here's an answer:

Your soldering should closer to this.  Hopefully better, as these are ones I did:

The solder short of sort web-up the sides of the pins. The use the term "fillet" for that.  Where your pads around the through-hole looks broader than the ones that are on the board above, it should probably look a bit better.  There shouldn't be unfilled parts of the through-hole, in any case.  At least not on the side you're soldering.
I expect it will at least show in the I2C scanner when you fix that.  It may show a different address from what is default in the library, in which case you may need to tell it to use the address that shows in the scanner.

you are right, but it works properly when I run the above code on arduino. The problem is with connection to nodemcu.

The connection may be so weak that it doesn't take much to affect whether or not it "works".

I have connected it to the arduino like this picture. scl to a5 and sda to a4. How can I change the above code that works the same? I think the problem is with the connection of pins to paj and nodemcu. But I didn't find any resource about connecting paj to nodemcu and I have added my code to see whether it has solution or not.

I don't believe there's anything wrong with the I2C scanner running on the esp8266.  And I don't believe that it's worth dealing with your original code until it shows in the scanner.  As I said, I'm sure the problem is something more fundamental.

I don't know where the problem is. I have edited the post again. would you please take a look at that?

I have look at arduino again. I have connected the scl to analog input, while nodemcu doesn't have any analog input, what should I do?

The A4 and A5 on the UNO are where the ATMega328P's I2C bus signals happen to be.  Earlier versions of the Arduino UNO and related boards didn't have dedicated SDA and SCL headers as they do now.  On those UNO that have SDA and SCL pins on the upper digital header, they are the same exact signal as those found on A4 and A5.

Let us continue this discussion in chat.


text:
Black screen when using higher SPI-speed for RA8857 LCD-controller
I'm using an Arduino Due that talks via SPI to an LCD (800x480) with the RA8875 controller chip.
The most recent datasheet I could find is: RA8875 datasheet.
Everything works as expected when using the Adafruit library. But, for my project, I want to maximize the communication speed between the LCD and the Arduino DUE.
Page 60 of the datasheet tells me that the maximum SPI speed to perform a SPIread is

system clock / 6.

Page 39 gives the formula for the system clock:

SYS_CLK = FIN * ( PLLDIVN [4:0] +1 ) / (( PLLDIVM+1 ) * ( 2^PLLDIVK [2:0] ))

There are some constraints:

From page 39:
FPLL = FIN * ( PLLDIVN [4:0] +1 ) must be equal to or greater
than 110 MHz

From page 91:
For an LCD of dim 800x480 2 layers 8bit color depth 60Hz framerate the pixel clock should be between  30 and 33MHz. (Registers are set to have 2 layers and 8 bit color depth).

A crystal of 20Mhz is soldered on the LCD ( FIN = 20 Mhz)
I have set the registers as follows:

Register
Value

PLLC1[88h]
24

PLLC1[89h]
1

PCSR[04h]
3

So, I expect:

SYS_CLK  = 20 Mhz * ( 24 +1 ) / (( 0+1 ) * ( 2^1 )) = 250 Mhz
Pixel clock = SYS_CLK / ( 2^3 ) = 31.25 Mhz
Max. spi speed = 250 Mhz / 6 = 41.66 Mhz.

I think to obey every given constraint.
But when I use an spi-speed of 30 Mhz, which is below 41.66 Mhz, I get a black screen.
I've put the Arduino sketch and the modified Adafruit library (Sven_RA8875) on google drive:
Arduino sketch + modified library.
The same data but on a pastebin:
Image: Working LCD at 20 Mhz
Example code RA8875
Modified library .cpp
Modified library .h
Edit by PPK:
I add the pictures from paste pics to this post after I scaled and croped them.

You computed the max speed of the display, but what about the Due. Can it handle 30 MHz SPI speed? Source from the internet claim that more than 20 MHz is not possible. Another thought: Even if the Due manages the 30 MHz, the endpoints need a fairly good shaped clock signal. If you use unshielded wires to connect the devices, that could disturb the signal form and makes the communication unreliable. I fear you need an osci the check that. And, does the display uses PWM to dim the backlights of the LCD? Then, did you configured the PWM signal bright enough?

Thanks @PeterPaulKiefer for your ideas! The Due seems to be able to have an spispeed of 84Mhz (https://www.arduino.cc/en/Reference/SPISetClockDivider). I attached a scope to the SPI clock signal once with and once without my changes for the spispeed. I've added them to the Google drive link above. The 30 Mhz spi clock seems okay. For the backlight, that is indeed pwm and it is bright enough (I dont change it between the example code and the modified code)

Sorry, I have no access to google drive and prefer not to log in. It would be better if you add the code and pictures direct to the question, in order to keep it if your google account would be deleted. --- The function you use is deprecated. --- Even if you set the clock speed to 84MHz, the send register must be filled with the picture data. That normally involves index computation and so on. After 8 Cycles the send register is empty, can you fill it within 8 CPU cycles? Or do you use DMA? I have some more ideas, but I'm busy at the moment. I'll come back.

I have added the code and images using pastebin links so no account is required. I tried to attach them directly but the size is to big. Okay it makes sense that I have actually a 30 Mhz clock but the data doesnt have enough time to load into the registers. I am not using DMA. Thanks for this, I did not think about it!

When I saw the pictures, my first thought was: The 30 MHz signal is useless. The slope is not steep enough.  But then I saw the blue wires (soldered?) to the board. Do you use them to connect the probes of the osci? That's not a good idea, as this long wires disturb reshape the signal at these frequencies; the wire acts as a low pass filter.

Try to put the probe direct to the clock pin and GND on the board if my assumption is correct, and you used the blue wires for the scope. If that does not change the signal form, then I would say the connection between the Due and the LCD is not sufficient for this frequency.

I thought about what you try to do: You had to configure the display to a clock frequencies of 250 MHz to achieve the refresh rate of 60 Hz with the given resolution. Then you try to deliver 60 frames per second over the SPI bus. That means the Due must be capable of generating or reading 60 frames with 768 kBytes per second and send it over the bus. I doubt the Due can handle this with its 84 MHz. So the demand of delivering 60 frames per second seems undoable to me.

The LCD has a 768 kB RAM to hold a picture frame. I asume it is possible to display it with 60 Hz but transfer only 25 frm/sec.  But I'm not really sure if the RAM can be filled asynchrounously.

Thanks @PeterPaulKiefer ! Indeed it wil probably not be possible, thanks for having a look at it. I remeasured the clock pin with my probe directly and changed the images for 30Mhz in here.


text:
LF: flexible scheduler/timer library
I'm working on a few arduino projects where I've needed a flexible scheduler and/or timer library and was wondering if anyone has a library they recommend?
Case 1:
I have a sensor that needs to collect observations every hour, but it has a specific  measurement sequence:

Power up/boot (takes about 15 seconds)
Warm-up for 60 seconds.
Observe (2 min), collect raw data, generate stats
Cool-down for 5 min.
Power off

In this case have a single micro-controller acting as a data-logger that is controlling multiple sensors and writing to an SD card.
Case 2:
I have an oven that needs to be controlled to a user-specified temperature profile (up say to 6 points of change), i.e.:

Turn on heater
Set temperature, 100C and hold for 2 min
Set temperature, 160C and hold for 15 min
Set temperature, 250C and hold for 1 hr
....
Set temperature, 100C and hold for 1 hr
Turn off heater

I'm familiar with non-blocking timers and (in the past) have cobbled together a few simple timers with millis() and some ulong variables. Alas, the complexity and debugging time rapidly grows with the number of dependent timers. Before I sit down and sketch out a class definition, I figured I'd ask what others are using.

You could use a RTC for more accurate timing.

You might want to take a look at Arduion_FreeRTOS which implement an FreeRTOS kernel under the Arduino environement.

Some libraries I find good (opinion-based):

TaskManagerIO: https://github.com/davetcc/TaskManagerIO

does a good job at managing events / scheduling things for a certain (system) time, or even repetitively.
with that you could e.g. use a scheduleFixedRate() API to call a function every 60 minutes. Then starts the power up (I assume asynchronously, by setting a pin or something), and just primes the scheduler with the scheduleOnce() API to call another function in 15 seconds. That target function then starts the warmup and schedules the next function / step for 60 seconds into the future, et cetera. It would express the flow very naturally.

If accurate timekeeping is needed so that it's really every hour, you might want to  use an external RTC module. Also depends on the microcontroller you're using, many have a builtin one that you can feed with a 32.768 kHz crystal and thus you don't need an external chip

library for the DS3231 / DS3232 RTC lets you set an alarm in the RTC: https://github.com/JChristensen/DS3232RTC/blob/master/alarm-primer.md
with that you can e.g. set an alarm for every 60 minutes and then execute your task.


text:
Problem communicating Using Nrf24l01+pa+lna, I am receiving 00 Hex
I am trying to build a wireless switch. At one end, I have Arduino Uno connected to Nrf24l01+pa+lna module. While at the other end there is Arduino Nano connected to Nrf24l01+pa+lna and a relay. I send char '1' or '0' through Nrf24l01 attached to Arduino Uno. Nrf24l01 attached to  Arduino Nano  receives this char and turns on or off the relay connected to Pin D3 of Arduino Nano. The my Arduino Nano replies back as '1' or '0'. Uno receives it and displays it on serial monitor.
At start the communication sometimes worked and sometimes didn't. Then I connected a 10uF capacitor to the both Nrf24l01 modules. Now I am receiving 00 Hex and relay is also not responding. Can any one help. Code is attached.
// Arduino Uno Code
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};

char serialChar;
char motorChar;

void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(addresses[1]); // 00002
  radio.openReadingPipe(1, addresses[0]); // 00001
  radio.setPALevel(RF24_PA_MIN);
}

void loop() {
    radio.stopListening();
    if (Serial.available() > 0) {
      serialChar = Serial.read();
      radio.write(&serialChar, sizeof(serialChar));

      delay(5);
      radio.startListening();
      while (!radio.available());
      radio.read(&motorChar, sizeof(motorChar));
      Serial.print(motorChar);
    }
}

//Arduino Nano Code
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
char command;
int relayPin = 3;

void setup() {
  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_LOW);

  pinMode(relayPin,OUTPUT);
  digitalWrite(relayPin, HIGH); // Relay is Now Off
}

void loop() {
    delay(5);
    char state = '0'; // switch is off
    radio.startListening();

    if (radio.available()) {
      radio.read(&command, sizeof(command));
      if(command == '1'){
        digitalWrite(relayPin,LOW); // Relay is Now On
        state = command;
        delay(5);
        radio.stopListening();
        radio.write(&state, sizeof(state));
      }
      else if (command == '0'){
        digitalWrite(relayPin, HIGH); // Relay is Now Off
        state = command;
        delay(5);
        radio.stopListening();
        radio.write(&state, sizeof(state));
      }
      else{
        delay(5);
        radio.stopListening();
        radio.write(&state, sizeof(state));
      }

    }
}

00 hex and 0 are the same number

Your radio receiver is not listening most of the time due to radio.stopListening();

Today i turned my Project on again. Now i am receiving nothing . That's too frustrating. I have working on this project since a month :(


text:
Help with NodeMCU based smart switch
The project I'm planning is to use a NodeMCU at each electrical board in house to control lights and fans via relays. Each MCU will communicate via MQTT over WiFi to a Raspberry Pi 4 from where I can control all lights and fans in the house. My doubt is:
Can the 3.3V NodeMCU drive a 5V relay like this 1 Channel 5V Relay Module with Optocoupler since I can't find any 3.3 V relays in India. Or must I use a logic level shifter? Or just use an ESP32 board (double price).

not drive, which means that the NodeMCU would supply power to the relay solenoid , but control, which means that the NodeMCU would operate a relay driver circuit

in my experience, 3.3v compat with those types of relay modules (i've tried 4 or 5 styles) will vary; some will be fine, some won't like it at all, and some will be spotty. For lower wattage loads like lighting, you can actually just use a triac-based optocoupler, some of which handle a few 100ma.

You don't need the typical level shifter. A.simple little transistor in combination is totally sufficient for the signal line of the relay module. Then you only need to provide 5V power (with which you can power the relay and the NodeMCU)

The relay I linked to couldn't be operated with 3v3 from the NodeMCU board. I was powering the NodeMCU via a breadboard power supply that had both 3v3 and 5v output (https://www.electronicscomp.com/mb102-breadboard-power-supply-module). I connected the Vcc and GND of relay to 5V supply on that module. the IO pin relay was connected to NoddeMCU. It worked fine and NodeMCU could switch it on and off.


text:
Any explanation for this behavior?
For the below code snippet
const char* fr_fbdb(char tag[30]) // fn for retrieving data
{
  char full_path[120];
  const char *_dt ;
  strcpy(full_path , base_path);
  strcat(full_path , tag);
  Serial.print( "retrieving from " );
  Serial.println(full_path) ;
  Firebase.get(firebaseData, full_path);
  _dt = firebaseData.cstrData();
//  Serial.print("while ext: ");
//  Serial.println(_dt);
  return _dt ;
}

void retreive_sch()
{
  int no_tag = strlen(*tag) ;
  //Serial.print("no. of tags in the DB: ");
  //Serial.println(no_tag);
  const char *_data[no_tag];

  Firebase.get(firebaseData, "/SCHEDULE DETAILS/SELECTED");
  sch_no = firebaseData.cstrData();

  Serial.print("extracting schedule");
  Serial.println(sch_no);

  strcat(base_path , sch_no); // base path w/ sch no.

  for (int i = 0 ; i < 6 ; i++)
  {
    _data[i] = fr_fbdb(tag[i]);
    Serial.print("while ext: ");
    Serial.println(_data[i]);

  }

  for(int i=0 ; i<6 ; i++)
  {
    Serial.print("after extraction:");
    Serial.println(_data[i]) ;
  }
}

This is the output:
retrieving  schedule changes -- setup
extracting schedule3
retrieving from /SCHEDULE DETAILS/SCHEDULE3/DATE
while ext: [1609612200000,\"inf\"]
retrieving from /SCHEDULE DETAILS/SCHEDULE3/FREQ FR
while ext: \"-2\"
retrieving from /SCHEDULE DETAILS/SCHEDULE3/FREQ TO
while ext: \"-2\"
retrieving from /SCHEDULE DETAILS/SCHEDULE3/WEIGHT
while ext: 29
retrieving from /SCHEDULE DETAILS/SCHEDULE3/TIME
while ext: \"6:30\"
retrieving from /SCHEDULE DETAILS/SCHEDULE3/frequency
while ext: \"-1\"
after extraction:"root":[]
after extraction:\"-1\"
after extraction:keep-alive
after extraction:\"-1\"
after extraction:"root":[]
after extraction:\"-1\"

As you can see, the output of the same variable _data[] inside that particular function changes.
Any idea why?

I would suggest you pick up a book about C++ and understand how to use const and what happen and the scope of a locally declare variable within a function.

_data is a global var & both set of print statements are within the same Fn. I hv used const char* fr_fbdb bcos firebaseData.cstrData() returns a c-string. Here's how I thought the flow was going to be: I call retrieve_sch() in the setup() . Then I get no. of tags from strlen(*tag) (tag holds strings such as DATE , WEIGHT, etc.). Then using a for loop that calls fr_fbdb() n no. of times get the req. tags. I also print the value that was retrieved here and in the for loop below. Pls point out where there might be flaws.

_dt is a locally declared variable, its scope remain local and when a call is return from the function, whatever stored in the _dt could be free up and the memory could be override.

"_data" has the value that is returned by the function fr_fbdb() which is confirmed by the print statements in the 1st for loop of retreive_sch() . In the second for loop of retreive_sch() the same var, _data gives different values. My claim is, if there was a pblm (bcos of scope of variables), then it should have been shown in the first print statement. (In case you haven't noticed, I've commented the print statements in fr_fbdb())

The problem is these lines of code in your function fr_fddb():
  Firebase.get(firebaseData, full_path);
  _dt = firebaseData.cstrData();

You didn't share enough code to make this clear, but firebaseData appears to be a global which you reuse. When you call its .cstrData() method you're getting a pointer to the same buffer each time, and that buffer is overwritten each time you call Firebase.get().
You can verify this by printing the pointer value each time through, like so in your retrieve_sch() function:
  for (int i = 0 ; i < 6 ; i++)
  {
    _data[i] = fr_fbdb(tag[i]);
    Serial.print("while ext: ");
    Serial.println(_data[i]);
    Serial.printf("_data[i] pointer %p\n", _data[i]);
  }

You'll likely see that the 6 pointers are identical. The value is changing because you keep reusing the same string.
The easy fix is:
  Firebase.get(firebaseData, full_path);
  _dt = strdup(firebaseData.cstrData());

This allocates memory and stores in it a duplicate of the string that was fetched from Firebase. Your function will now return that and firebaseData can safely be reused.
This solution will require you to free that memory at some point when you're doing using it by calling free(_dt); or whatever you're holding the pointer in when you're done. I leave that as an exercise for you.


text:
[SOLVED]Normalization not working on input buffer. How to solve this?
I wrote a piece of code that takes input from a sensor which is called the World Famous Pulse Sensor from Analogue Pin 1 and stores it in an Array with 127 elements then finds the largest in it, divides the rest by the largest, multiplies by 64 which is the maximum y length on my OLED and prints it onto the OLED.
It still gives me pre-normalized and scaled values on Serial Plotter.
What am I doing wrong?
Here is my code.
#include <U8glib.h>
U8GLIB_SSD1306_128X64 u8g(12, 11, 8, 9, 10);
int x, y;int Buffer2[128];
void pageBP();
const int pageCount = 1;
int p;
void (*pages[pageCount])() = {pageBP};
int duration [pageCount] = {1000};
void setup() {

  u8g.setFont(u8g_font_unifont);
  u8g.setColorIndex(1);
  p = 0;
  Serial.begin(9600);

}

void loop() {

u8g.firstPage();
  do {
    (*pages[p])();
  } while( u8g.nextPage() );
  delay(duration[p]);
  p = p+1;
  if (p == pageCount)
    p=0;
}

void pageBP() {
  for(x = 0;x < 128;x++) {
Buffer2[x] =(analogRead(A1)>>2);//IP for PPG
Serial.println(Buffer2[x]);
delay(5);
}
for(int i = 1;i < 128; i++)
    {
       if(Buffer2[0] < Buffer2[i])
           Buffer2[0] = Buffer2[i];
    }
    for(int i = 1;i < 128; i++)
    {
       64*(Buffer2[i]/Buffer2[0]);
    }
  for(x = 0;x < 127;x++) {

u8g.drawLine(x, Buffer2[x], x, Buffer2[x+1]); //OP to OLED for ECG

u8g.drawLine(64, 0, 64, 63);
u8g.drawLine(0, 32, 128, 32);}
for(x=0;x<128;x+=8)
u8g.drawLine(x, 31, x, 33);
for(x=0;x<64;x+=8)
u8g.drawLine(63, x, 65, x);
u8g.drawFrame(0, 0, 128, 64);
}

Here is Garbage Graph.

64*(Buffer2[i]/Buffer2[0]); : this line does absolutely nothing. You're not storing the result of that computation anywhere.

I will point out some problems with your code:

Look at this line:
  64*(Buffer2[i]/Buffer2[0]);

It doesn't do anything. You calculate a scaled value, but you are not saving it anywhere. You need to assign that value to a variable (like an element in a new array).

With this code
  for(int i = 1;i < 128; i++)
  {
      if(Buffer2[0] < Buffer2[i])
          Buffer2[0] = Buffer2[i];
  }

You are overwriting the first value in your buffer to find the highest value. That might not be a problem for you, but to be clean here, you should just use a new variable, that holds the highest value outside of the buffer.

I'm not sure what you are trying to do with this line:
  u8g.drawLine(x, Buffer2[x], x, Buffer2[x+1]);

Normally, you would want to draw a line from one point in the graph to the next. So the second x parameter would need to be the x value for the next point. Currently you are just drawing a vertical line. I would instead write
  u8g.drawLine(x, Buffer2[x], x+1, Buffer2[x+1]);

since you already are only counting to 127 instead of 128.

Even if you get the above right, the Serial Monitor would still show the unscaled values, since you are printing to Serial directly after measuring. So to display the scaled values in the Serial Monitor, you need to move the line
  Serial.println(Buffer2[x]);

down to after the scaling, for example in the same for loop as the OLED display code.

And finally you should really fix your indentation. That will make your code way more readable and thus better understandable. The Arduino IDE even has an autoformat feature, that you could use for that.


text:
Arduino IDE - scope of the pre-processor "#define"
I'm creating an Arduino library and have 3 files - a "test.ino" program, and two library/class files: "testLibrary.h" and a "testLibrary.cpp".
The library makes use of some hardware-specific resources such as registers and ISRs that depend upon which I/O pin is used, and this should be done at compile time.
I would like to #define a pin number in the main program which, at compile time, is used in the library to determine which code sections are activated. Since this will be a standard Arduino library for use by others, it should compile and run without users having to change their compiler or #include path to make it work.
But it seems that the scope of #define in the main program/sketch does not extend to the library.
test.ino
#define PIN_NUMBER 3
#include "testLibrary.h"
void setup() {}
void loop() {}

testLibrary.h
#ifndef _TESTLIBRARY_h
#define _TESTLIBRARY_h
#ifndef PIN_NUMBER
#error PIN is not defined
#endif
class test {
public:
  test();
  ~test();
};
#endif

testLibrary.cpp
#include "testLibrary.h"
test::test(){}*
test::~test(){}

Compiling the above branches to "#error" using the Arduino IDE 1.8.13 and also using Visual Studio with Visual Micro.
Is there a way for me to have an Arduino library use a "#define" from the main sketch?

You actually didn't define PIN_NUMBER in your code. Or is that a copy&paste error?

You have two #endif but only one #if in testLibrary.h. This will cause a compilation error if you define PIN_NUMBER in your main code (test.ino) when it skips the #error in testLibrary.h. Maybe you did not notice the #endif without #if error? You can fix it by inserting #define _TESTLIBRARY_h as the first line of testLibrary.h. I.o.w. the scope of PIN_NUMBER will be global if you define it in test.ino. Try it.

It was indeed a copy-and-paste error, I put the first line of my code on the same line as the code-tags which meants that for each of my code snippets the first lines were missing. I've corrected that (@chrisl & StarCat)

You can use a library header file in more than one other libraries or applications. So the library header files should not be dependend on where they were used. Even if the preprocessor would allow defined local macros in included (header) files, it would be a very bad design. How can you know what the main app will do? That leads to horror errors for people using your lib.  If you need the value in the class, just add a property to the class and set it in the main code by your constant. The SoftwareSerial library does that to define the tx and rx pins for example.

Is there a special reason, why you want to use a define? The convention is to let the user provide such information as parameters for either the class constructor or the begin() method.

Since any pin on the Arduino can be used, I would need to define each and every INT or PCINT "ISR" in the library even though only one is needed, and that would preclude them being used elsewhere. Hence my wish of using a precompiler statement; if this value is passed as a parameter at runtime for this application it is too late.

does it work if you get rid of the cpp file (rename to .cpp.old)? I had to put a full library's code in the H file to get it recognizing defines before #including it. Works fine since the header file is just literally inserted into the ino at the point of the #include statement. Normally, code in the header is frowned up because it's easy to insert it more than once, but ino files are all concat'd together anyway, so there's no chance of that. Used in this way, it's just like pasting an extra ino file atop your sketch and works quite intuitively.

put another way: the error stems from testLibrary.cpp, not the header file, because as a different translation unit, the ino's macro isn't defined; it has to work as though the ino doesn't exist and the cpp and h file have all they need. afaik, there's simply no way to "pass" a value from an ino to a lib's cpp file.

Thanks for all the replies. I had feared as much, as the c++ documentation did lead me to  see that the scope of a "#define" is limited. @dandavis. In the end I am going to use the "BADISR_vect" as a catch-all and assume that the only undefined interrupt is the INTx or PCINTx for the pin, which will be passed to the library  as part of a "begin()" call at runtime. And instead of a compact series of "#define" statements that are computed at compile-time I'll have to use a more lengthy "switch(pin)" statement at runtime.

The scope of a #DEFINE macro is the translation unit. That is the current .c or .cpp file that is currently being compiled.
In you code PIN_NUMBER is defined in test.ino. The #include macro literaly copies the content of testLibrary.h into test.ino. So for the compiler this is working perfectly fine as PIN_NUMBER is defined.
Your testLibrary.cpp however is not happy with that. Including testLibrary.h for compilation lacks the definition of PIN_NUMBER.
The Arduino IDE is very limited and does not offer you a way to define PIN_NUMBER globally. This is usually done with the compiler argument -DPIN_NUMBER=3. All translation units will get this argument and thus the compilation would succeed. No need to define PIN_NUMBER in code.

Unfortunately adding a compiler argument is not a solution - the whole problem setting was due to attempting to make a standard library which any Arduino IDE user could simply download and include without having to make any subsequent changes.

In the answer to a similar question it’s suggested to put the #define in a header file that is then included into all the translation units (i.e., ino, c or cpp files) https://arduino.stackexchange.com/questions/23681/visibility-of-define-between-sketch-and-library


text:
How to change avrdude parameter in Arduino status log when uploading a program? avrdude.conf
Recently I custom bootloader optiboot for Arduino Uno to my custom board called Ardunesia xst X1-02, with Cortex M3 processor. I set avrdude as bootloader upload tool = "X1-02_bootloader.upload.tool=avrdude" in board.txt. It work normal which my board pretends to be Arduino UNO. But I want to change this log status:
 Using Port                    : COM6
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
         AVR Part                      : ATmega328P
         Chip Erase delay              : 9000 us
         PAGEL                         : PD7
         BS2                           : PC2
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

I want the status log to contain my custom board instead displaying atmega328. I changed and edit file in avrdude.conf which it seems the root of this problem. I added an inheritance in Atmega328 for my custom board, but It didn't work (still displaying atmega328). I know avrdude.conf is made for avr MCU, but I wonder there is a way to add our custom/non-avr mcu to display this status log? Thank You.
Edit: To make it clear I want to customing avrdude.config C:\Users\yourPC\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17\etc which its contain board ID for AVR device and I want to insert y device ID here, I inserted it on Atmega328 part parent like this:
part parent "m328"
    id          = "m328p";
    desc        = "ATmega328P";
    signature       = 0x1e 0x95 0x0F;

    ocdrev              = 1;
;

part parent "m328"
    id          = "m328pb";
    desc        = "ATmega328PB";     //another m328 version
    signature       = 0x1e 0x95 0x16;

    ocdrev              = 1;
;

part parent "m328"
    id          = "XST";
    desc        = "XST_X1_02";         //my board XST X1-02
    signature       = 0x1e 0x95 0x0F;

    ocdrev              = 1;
;

I set the signature so the bootloader recognize my board as Arduino UNO and its work well. But it keep reading as Atmega328P and not displaying XST X1-02. Should I create my own signature? any advice? Thank you
Problem Solved! I need to changes compile patterns in platform.txt from -DAtmega328_{build.board} to -DXST_{build.board} which XST is my MCU name. Thanks everyone!

why would you make an ARM MCU pretend to be an Uno?

Arduino Uno is running on ArduinoCore-avr while Microchip's ARM MCUs are using ArduinoCore-samd, ST's STM32 or PIC's 32 bits MCUs all have there own different Arduino Core. Are you sure you know what you are doing? Why you are trying to use an 8-bit AVR core for 32-bit ARM chip?

@juraj Thanks for asking, because I want to make 'optiboot' bootloader work on my ARM MCU. Optiboot by default design for AVR device. Next I modified my MCU's buffer and boot sector address to make the optiboot main program work. Its work fine, but I just wondering how to change the status log above to contain my Device ID.

@hcheung Yess I know that, I just assigned to make a bootloader for the new MCU. I found it easier to port a bootloader program from Optiboot which designed for AVR and used AVRdude as upload tool than using Bossac for ARM devices like arduino Due. Its works since I just porting the size of buffer and bootloader section address for it. Now it just likes the last step to display my Device ID in arduino verbose output. Or can you tell me how to make an arduino bootloader for arm devices? Because I found it more complicated than a bootloader from Optiboot

Arduino M0 uses avrdude for upload

@juraj Interesting, but I dont find ATSAMD21G18 was mentioned in avrdude.conf C:\Users\yourPC\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17\etc. This file contain all device ID that using avrdude for upload

I think it reports as ATmega2560

@juraj Just checked it, it's not. But since I don't have Arduino M0 so I can't  figure it out. Thanks for your response


text:
How to make my sensor reads when i pressed the button
Hi I'm making a digital fare meter, I have a problem in how my sensor reads when I'd pressed the button(single tap). I need the sensor to read once I pressed the button because when I press the button the reading starts from the beginning of the program(when the device starts) not when I pressed it. and the display is not changing if I not pressed the button i need the display in lcd to change even if i only press the button once. ( Sorry for my grammar )
#define sw 5 //pin at push sw is connected
#include <LiquidCrystal_I2C.h>
int irPin=A0;
int count=0;
int counter=0;
boolean state = true;
float distance1; float distance2; float distance3; float distance4;
float wait1;float wait2;float wait3;float wait4;
float fare1;float fare2;float fare3;float fare4;
float hitObject = false;

LiquidCrystal_I2C lcd1(0x26,20,4);
LiquidCrystal_I2C lcd(0x27,20,4);
int lastButtonState = HIGH;   // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
bool buttonState = HIGH; //saving state of the switch
byte tapCounter; //for saving no. of times the switch is pressed
int timediff; //for saving the time in between each press and release of the switch
bool flag1, flag2; //just two variables
long double presstime, releasetime; //for saving millis at press and millis at release
void setup() {

lcd.init();
lcd.backlight();
lcd1.init();
lcd1.backlight();
pinMode(irPin, INPUT);
lcd.setCursor(0,0); lcd.print("Seater 1  D=");
  lcd.setCursor(0,1); lcd.print("Seater 2  D=0.00");
  lcd.setCursor(0,2); lcd.print("Seater 3  D=0.00");
  lcd.setCursor(0,3); lcd.print("Seater 4  D=0.00");
  lcd1.setCursor(0,0); lcd1.print("W=       F=Php0.00");
  lcd1.setCursor(0,1); lcd1.print("W=       F=Php0.00");
  lcd1.setCursor(0,2); lcd1.print("W=       F=Php0.00");
  lcd1.setCursor(0,3); lcd1.print("W=       F=Php0.00");

  Serial.begin(9600); //for serial monitor
  pinMode(sw, INPUT_PULLUP); //setting pin 5 as input with internal pull up resistor

}

void kount()
    {
  { if (!digitalRead(irPin) && state){
 count++;
 state = false;

 }
 if (digitalRead(irPin)){
 state = true;}}}
 void compute()

{
   distance1 = count*1.73;
   fare1 = count*1.73/100+wait1;
 }
 void printlcd()

 {
 lcd.setCursor(12,0); lcd.println(distance1);lcd.println("m");

 }

void loop() {
  kount();
  compute();
  int reading = digitalRead(sw);

  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
    }
  }
  //Serial.println(buttonState);

  //when switch is pressed
  if (buttonState == 0 && flag2 == 0)
  {
    presstime = millis(); //time from millis fn will save to presstime variable
    flag1 = 0;
    flag2 = 1;

    tapCounter++; //tap counter will increase by 1
    //delay(10); //for avoiding debouncing of the switch
  }
  //when sw is released
  if (buttonState == 1 && flag1 == 0)
  {
    releasetime = millis(); //time from millis fn will be saved to releasetime var
    flag1 = 1;
    flag2 = 0;

    timediff = releasetime - presstime; //here we find the time gap between press and release and stored  to timediff var
    //Serial.println(timediff);
    //delay(10);
  }

  if ((millis() - presstime) > 400 && buttonState == 1) //wait for some time and if sw is in release   position
  {
    if (tapCounter == 1) //if tap counter is 1
    {
      if (timediff >= 400) //if time diff is larger than 400 then its a hold
      {
        Serial.println("Hold");
        hold(); //fn to call when the button is hold
        ;
      }
      else //if timediff is less than 400 then its a single tap
      {

        Serial.print(count);
        Serial.println("single tap");
        singleTap();

        //fn to call when the button is single taped
      }
    }
    else if (tapCounter == 2 ) //if tapcounter is 2
    {
      if (timediff >= 400) // if timediff is greater than  400 then its single tap and hold
      {
        Serial.println("single tap and hold");
        tapAndHold(); //fn to call when the button is single tap and hold
      }
      else // if timediff is less than 400 then its just double tap
      {
        Serial.println("double tap");
        doubleTap(); //fn to call when doubletap
      }
    }
    else if (tapCounter == 3) //if tapcounter is 3 //then its triple tap
    {
      Serial.println("triple tap");
      tripleTap(); //fn to call when triple tap
    }
    else if (tapCounter == 4) //if tapcounter is 4 then its 4 tap
    {
      Serial.println("four tap");
      fourTap();//fn to call when four tap
    }
    tapCounter = 0;
  }
  lastButtonState = reading;
}

void singleTap()
{
compute();
printlcd();
}
void doubleTap()
{

}
void tripleTap()
{

}
void fourTap()
{

}
void hold()
{

}
void tapAndHold()
{

}


text:
confirming this will blink LED at given frequency
I want to blink an LED at an specific frequency, ie: 7Hz
here what Im doing
int ledPin = 4;
float freq = 7;

void setup() {
  pinMode(ledPin, OUTPUT);
}

float periodo() {
  float peri = 1/freq;
  float halfer = peri/2;
  float millisec = halfer*1000;
  return millisec;
  //return ((1/freq)/2)*1000;
}

void loop() {
  digitalWrite(ledPin, HIGH);
  delay(periodo());
  digitalWrite(ledPin, LOW);
  delay(periodo());
}

Is this correct? is that the best way to do it?
thanks in advance!

In addition to the answer: I would not call  periodo in the loop if the freq does not change. Use a global int actPeriod variable and only initialize it in the setup function with  actPeriod=periodo(freq); and every time the preq variable might change (in comming revisions ;-)). Then use the new variable in the delay. With the actual code there would be no problems, but you asked for optimal code and if you add time criutial functionallity, it could matter.

You can check if it is correct by timing it for one minute and check if it is (approximately) ok.
However, I see a few improvements:

First is that you always return 1/7/2*1000 = 71.429, which is rounded down to 71. 71 * 14 = 994 ms so you get a bit faster speed than 7 Hz. if this is a problem you have to compensate for this.
Another small problem is that you delay, but the digitalWrite commands also take some time which is not included for the delays. So you need also to take this into account when using a precise delay.
When using floats I always use float constant numbers, like 1.0 and 7.0 instead of 1 and 7. This can especially be useful when you divide two integers (e.g. 1/7), which results in 0.14 this is rounded down to 0 as it is an int.

The best you can do is using the millis command. You keep a timer and compare it to the current millis value. If it is too high, do a state change. This will take into account every other method you do meanwhile the digitalWrites.
Something like: (code fixed due to EdgarBonet's remarks)
const float FREQ = 7.0; // Hz
const int PIN_NR = 4;

unsigned long _startTime;
unsigned long _counter;

int _currentState = LOW;

void setup()
{
  _startTime = millis();
  _counter = 0;
  _currentState = LOW;
  digitalWrite(PIN_NR, _currentState);
}

void loop()
{
  if (_startTime + _counter * 1000.0 / FREQ / 2.0 >= millis())
  {
    _counter++;
    _currentState = ~_currentState;
    digitalWrite(PIN_NR, _currentState);
  }
}

Some small notes:

_currentState is the current state of the LED, with ~ you can flip it (it's called the not operator).
_startTime is the (close to zero) value of the millis value at startup.
Take in mind there is a limit how long this app can run or precise. millis works with ms, meaning you cannot get beyond 500 Hz, and you get 'approximations' with frequencies below in some cases. E.g. when Freq = 80 Hz, you get 1000 * 1 / 80 / 2 = 1000 / 160 = 6.25 => 6, which is actually 1000/6/2=83.3 Hz.
Also the counter is added once per state change, and because of 1000 * _counter ... an overflow exists when _counter >= 256 * 256 * 256 * 256 / 1000 = about 4 million. With 1000 state changes per second, this happens after 4000 seconds, which is 66 minutes. For 7 Hz it will not occur fast.

This will make each interval 71 ms longer than the previous one, which means the frequency is modulated down towards zero. 2. This is prone to a rollover bug. Avoiding the bug is as easy as following the Blink Without Delay tutorial, so there is no good reason to keep the bug. 3. If you call millis() twice in a single loop iteration, you could very well get different results, in which case your timing calculations are off. Call millis() once and record the value if you need it twice. 4. Why these irritating underscores in front of every single variable name?

@EdgarBonet Thanks for your comments. 1 was indeed a stupid bug. 2. The Blink without delay tutorial is not exactly precise as the interval is a fixed value. It could be improved with some compensation though without having my 1000 multiplication resulting in a rollover. 3. Good point, I changed it in my code. 4 Not in every variable name, only 'global/class' variables, to make clear these are not local variables.


text:
Can't upload programme on arduino uno
Arduino: 1.8.3 (Windows 7), Board: "Arduino/Genuino Uno"
Sketch uses 1094 bytes (3%) of program storage space. Maximum is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude -CC:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM14 -b115200 -D -Uflash:w:C:\Users\Admin\AppData\Local\Temp\arduino_build_360380/FINALROTARO.ino.hex:i

avrdude: Version 6.3, compiled on Jan 17 2017 at 12:00:53
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : COM14
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x1f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x1f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x1f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x1f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x1f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x1f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x1f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x1f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x1f
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x1f

avrdude done.  Thank you.

Problem uploading to board.  See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.


text:
Power down NRF24 to conserve battery life using MOSFET
I'm using a Pro-Micro to send messages using NRF24 module from a remote location, using batteries (later on, will be recharged using solar panel).
To conserve power, Pro-Micro wakes up every 30 minutes, sends its data. My goal is to power up NRF24 module only when needed, in order to conserve power as much as possible.
For that I tried 3 ways:

Using a Relay to cut off 5V input to the NRF24 module.

Using a MOSFET FQP30N06 , connected to GND of NRF24 module.

Using NRF24's powerDown() function reduce consumption.

These are the current draw results:
a) During sleep, power consumption of Pro-Micro only is 3.4 mA ( due to LED remains ON ).
b) Pro-Micro + NRF24 module, both normal operation ~70mA.
c) Using a relay + entering Pro-Micro to Sleep mode: 6mA.
d) Using powerDown() + entering Pro-Micro to Sleep mode: 30mA.
e) Using a MOSFET + entering Pro-Micro to Sleep mode: 180mA. (yes, MOSFET turns off power to NRF24 ).
Questions:
** I have to say that my first go was for using a MOSFET, but I was amazed by the result! What is the reason for that? Can it be the when MOSFET in its OFF state consumes so much power ?
** I would like to hear from other's experience for better ways to do such.
Guy

No, MOSFET does not power off the whole NRF when it only switches the GND. There are other connections like e.g. the SPI pins that can act as grounds when they are low.

For switching the power for such a device, you should use a high side switch, meaning a P channel MOSFET for switching Vcc.

Those 70mA and 30mA look way too high to high to me. I was able to run my setup on an average of around 0.5mA, with the MCU waking up every 250µs to do a measurement and occasionally sending data via the NRF24. Putting the NRF24 in power-down mode should be sufficient bring it's power usage to almost nothing. It might be a counterfeit NRF24L01. Is the chip on your module a QFN chip, or is it under a blob of epoxy?

@PeterPaulKiefer, Yes - it was understood eventually. I also tried to put all SPI pins LOW on power off procedure, but change was not that big. Thank you!\

@chrisl - After using a relay, I was thinking just abput what you wrote, but since I've never practiced such MOSFET, I was not sure. Thank you.

@Gerben - I'm using a NRF24 ( the one with antenna. -for longer range ) and a power adapter ( example: https://www.ebay.com/itm/2Pcs-NRF24L01-Transceiver-External-Antenna-PA-LNA-Arduino-5V-Breakout-Adapter/292424165202?epid=13013735675&hash=item4415d6a752:g:fIoAAOSw8i9aamZK ).. So it is not only the NRF24 module. Does it more reasonable ?

In that case, those values sound a lot more plausible. Those have an additional amplifier, so they will probably use more power. The power adapter boards have a linear regulator, which has around 5mA of quiescent current.

@Guy.D you can't set SPI pins to LOW. You have to disable SPI first, before you can change them.

Setting the SPI pins to LOW should increase the current when only GND is off. Perhaps setting them to high could help or (much better) use it as an input to set it into a high impedance state. -- Switching off only the VCC did help in your case. But, a connected pin could also act as a fake VCC. E.g. You set it to high or an input with the internal Pull UP active. So the best way is to switch off VCC or GND or both and set all connected data and clock pins as inputs. The quality of the module does not matter. If you stop current flow with the Arduino, the module can not waste power. ;-)


text:
How to wire and control a 16mm button with 2 legs using arduino?
I can't find any tutorials online explaining how to wire and control a 16mm push button like the one in the picture:

Do  you have any suggestions as to how use it with an arduino or a raspberry pi?

Just look up any tutorial on a button. For the arduino, it doesn't make a difference whether they're 1mm or 100mm wide.

https://www.arduino.cc/en/Tutorial/BuiltInExamples/InputPullupSerial

it's just a switch ... pressing the button connects the two wires together electrically

One might suggest that a button is not controlled by an arduino. The button is an input device to control the action of the board's programming. It is to be used on digital inputs (on/off) and usually with a debounce routine.

@fred_dot_u One could argue that it is controlled digitally though....

I had forgotten the proctologist option

I suggest you look at the Bounce2 library, which can handle debouncing for you.

A pushbutton is a pushbutton. It is a momentary switch. Since it has flexible wires, and needs a place to mount, you should probably wire it using a breadboard.
That pushbutton looks like a panel mount pushbutton. You might want to mount it in a pice of plastic or sheet metal. (Unscrew that nut up by the red part that you press. Measure the outside diameter of the threaded part. Drill a hole ≈1/64" (≈0.4MM) bigger than the switch diameter into the plastic/metal. Insert the pushbutton from underneath the panel. screw the nut back on to secure it. Tighten moderately tight with needle-nose pliers, being careful not to round off the corners of the nut.
To wire it:
Get a breadboard. Run wires from your Arduino to the breadboard.
Wire the pushbutton into the breadboard as well.
There are various libraries that offer switch debouncing, or you can write your own fairly easily.
I suggest using INPUT_PULLUP mode, and wiring your switch between an Arduino digital input and ground. When the switch is open, the input will read HIGH. When you press the the switch, the input will drop to LOW.
If you want to debounce the switch input yourself: When the switch changes state, note the value of millis(), and ignore any new changes for a brief period (try 20-100 mS).