Debouncing a button with interrupt I tried to follow the answer here:
https://arduino.stackexchange.com/a/18545/51302

Unfortunately I can only get the interrupt to go once (on serial monitor is the time of that first interrupt), then nothing.
I know this has already been answered but I don't understand the mistake and would appreciate help.

What I'm trying to do:
get a button to set an interrupt to trigger foo and thus write the steps on the monitor.

I've left remarks to try and explain what I try to do, so it would be easier to understand what I left out or used incorrectly.
Thanks.

#define IRF520 A2
#define BUTTON 3
static unsigned long last_press = 0;
static bool button_state = HIGH;             //pull up resistor
volatile bool interrupt_flag = 0;            //when the interrupt fires, button press or noise
bool is_pressed = false;                     //after checking that the button was really pressed
bool was_pressed = false;                    //last state of the button
unsigned long button_pause_duration = 20;        //pause required to accept press in ms
unsigned long interrupt_time=0;

void button_interrupt() {
  interrupt_flag = true;                      //can be a false alarm
  Serial.print("interrupt time: ");         //this is the onlt step that works
  Serial.print(millis());
  Serial.print("\n");
}

void setup() {
  Serial.begin(9600);
  pinMode(IRF520, OUTPUT); //A2 controls IRF520
  pinMode(BUTTON, INPUT_PULLUP);  //pin D2 and D3 are sutible for interrupts
  attachInterrupt(digitalPinToInterrupt(BUTTON), button_interrupt, FALLING);
}

void debounce_button() {
  if (digitalRead(BUTTON) != button_state) {
    button_state = digitalRead(BUTTON);         //if button changed state remember the new state
    interrupt_time=millis();
  }
  if (button_state == LOW) {
    last_press = millis();
    Serial.print("last_press was updated to: ");
    Serial.print(last_press);
    Serial.print("\n");
  } else {
    last_press = 0;
    interrupt_flag = false;
  }
  if ( last_press && (millis() - last_press) > button_pause_duration) {
    last_press = 0;     //set to 0 for the next check
    is_pressed = true;   //button was really pressed
    Serial.print("last_press was set to 0 and is_pressed to true - BUTTON WAS PRESSED at: ");
    Serial.print(millis());
    Serial.print("\n");
  }
}

unsigned int foo(bool is_pressed) {
  if (is_pressed) {
    Serial.print("foo is active, MOSFET does its thing");
    Serial.print("\n");
    }
  }
}

void loop() {
 if(interrupt_flag){
    Serial.print("the button is now being pressed: ");
    Serial.print(millis());
    Serial.print("\n");
 }
 debounce_button();
 foo(is_pressed);
}

I think the problem is that you only trigger the interrupt when the button is pressed (interrupt FALLING)

Therefore, there is no opportunity to call debounce when the button is released.

Therefore, there is no way to change the button state variable back to HIGH (I.e. when the button is released).

To verify the hypothesis or gain some other insights, I suggest trying to put a debug statement in your loop similar to the following

  If (millis () >= debugTime) {
       DebugTime = millis() + 1000:   // output every second...
       Serial.print("value of button state is: ");
        Serial.println(button_state);
      // and a few other variables.
  }

I will leave it to you to properly declare debugTime (unsigned long) and choose a few other key variables (maybe interrupt flag) to print in the debug message block.

And i think you already have done so,  but also delete the print statements in your ISR.


Why when I press the reset button Why when I press the reset button it takes 2 second before I see my sketch start?
The model of Arduino is UNO, and the text in serial communication.

Because first the bootloader is executed and takes 2 seconds (or more on a Leonardo) to time out when it doesn't receive a proper response from the computer.


How can I stop my Arduino UNO rev 3 from briefly turning on digital output pins on startup or reset? I am using my Arduino UNO rev 3 to control other devices via the digital output pins. On startup or reset, I find that these pins are all briefly turned on (perhaps as part of a self test). This interferes with my application. How can I suppress this?

Digital pin 13 will be turned on briefly as part of the bootloading process (it flashes a few times). Thus this is not a good choice of pin for a device like a motor to be connected to. Also if you are uploading a new sketch the Tx pin (digital pin 1) will be turned on and off.

You can change the processor fuses to not use the bootloader, which would avoid these issues, however then you have to change them back to upload a new sketch - unless you upload using ICSP instead of the bootloader.

As Gerben and Majenko have pointed out, any other issues could be from "floating" pins which some devices might interpret as having a HIGH on them, possibly. Pull-down resistors could help there (or pull-up if that is more appropriate).

The ideal thing could be to structure your system in such a way that the two pins (1 and 13) which come on during the bootloading process are connected to something "harmless" (eg. an LED) rather than "harmful" (eg. a motor).


How does Arduino digital input pin measure its input voltage? Just starting with my first Arduino project.
In order to measure voltage in a circuit I connected my multimeter to two points in the circuit (for example before and after a resistor).

I am interested to know how an input pin can measure its voltage (for example 5v or 0v).

Assuming you are asking about digital input pins on an Arduino:

Digital logic operates at the saturation and cut off regions of the transistor logic used.  Most modern day processors use CMOS transistors.  The logic levels are Low: 0 V to 1/3 VDD and High:2/3 VDD where VDD is the supply voltage.  This information can be found here.

So, if your processor is designed to operate at 5 volts and is likely made of CMOS logic gates, the low level voltage is from 0 to 1.67 volts and the high level voltage is from 3.33 to 5 volts.

But to address your question specifically:  Digital input pins do not measure the voltage.  Not like an ADC input.  Instead, it is agreed that nothing operating normally that is to interface with a digital pin will produce (linger at) a voltage other than those designed to force the transistors into cut-off or saturation.

So do be careful not to do this.  It could result in unexpected behavior.

Now, if you can not avoid voltage between the designated upper limit of the low logic signal and the lower limit of the high logic signal you man need to buffer your signal with a device called a Schmitt Trigger.  This device adds hysteresis to your signal and converts it into either a low or high logic state.  Examples of hysteresis include the thermostat control for your furnace.

A final word, do not exceed the voltage at a digital input to that which is supplied at the power pin of that digital circuit. This can cause all kinds of problems.  Usually this is not a problem as most devices / projects are powered off of one power source.  But in case multiple power supplies are used, keep this in mind.


Arduino Due custom platform for school and library installation I have made a custom-development hardware for our school, where you can plug in an Arduino Due. It is mainly for driving all kind of motors and reading sensor signals. Therefore I added a custom SAM board into board.h based on a copy of the Arduino Due. Furthermore I need a global PWM frequency on all PWM Channels of 20 kHz. So I also changed the variants.h file.

(I have not found a solution that is setting all the underling Timer/Counters for PWM on the Due Pins 2, 3, 4, 5, 6, 7, 8, 13 to 20 kHz by user code, I think this is only possible with the variants.h file - because some timers can not be reset after they where set within the Arduino IDE once)

The Question now:
Today all students have to find and modify their variants.h file, which can be located almost anywhere! (Sometimes it is located in the support packages of Matlab...).

Is there an easy solution to give the students one .zip containing the Arduino IDE already with the custom Board included?
There is the Arduino IDE working without installation for download on the Arduino website. But how can I add my custom SAM board to it?

Exit the Arduino IDE.
Create a folder in the Arduino IDE installation folder named portable. This will cause the Arduino IDE to run in portable mode.
Start the Arduino IDE.
Tools > Board > Boards Manager
Wait for the download to finish.
Click on "Arduino SAM Boards".
Click "Install".
Wait for installation to finish.
Make your modifications to the Arduino SAM Boards hardware package installed at {Arduino IDE installation folder}/portable/packages/arduino/hardware/sam.
If necessary, configure File > Preferences to your liking.
Exit the Arduino IDE.
Zip the Arduino IDE installation folder.

When you run the Arduino IDE in portable mode it causes hardware packages installed via Boards Manager to be installed to the portable folder, rather than a folder outside the Arduino IDE installation folder. It also stores preferences.txt in the portable folder. This means you can supply a .zip file that contains a copy of the Arduino IDE with the customized Arduino SAM Boards package already installed.

By default it will also set the sketchbook folder to be there but that can be changed via File > Preferences > Sketchbook location if you like.


Advice on cabling, packaging and connectors for 12v light project My project is to have a 12V solar LED strip lighting system throughout my apartment. This has 6 individual lights, with 5 white and 1 RGB = 8 channels.

I've got the whole setup working on my breadboard. Now it's time to transfer it to a "live" setup. Since it's my first such project, I'm looking for any and all recommendations on cabling and connectors to deal with reliability, isolation, modularity, aesthetics and of course safety.

Schematically, it all looks something like this

solar panel------\
                  charge controller--5v regulator--arduino--mosfets x 8--\__lights
12v battery_fuse_/                  \____________________________________/

So I have questions such as:-

should I use a prototype shield, or a discrete pcb?
do the MOSFETs (RFP30N06LE) need a heatsink, and any recommended unit?
what connectors are recommended?
any suggestions on box/packaging for the above?
wire gauge? Maximum run is 4m to the furthest light.

And any other hints, tips and suggestions greatly appreciated. Bonus appreciation for amazon links to the parts :-)

update
The breadboard is simply the mosfets, each with a current limiting resistor on the gate. The lights range from 8W to 40W. I will generally have them dimmed using PWM.

generic DC connector advice:

avoid the use of connectors which connect serially, like headphone jacks. you make strange combinations while plugging in

avoid connectors which do not latch, like headphone jacks

in a system like yours, with stages and signal processing in between, use different connectors for each phase, so you can not get it wrong

use connectors that can not be connected backwards for DC. I prefer:

Hopkins 47965 2-Pole Flat Extension for raw solar power.Not because    it's a great connector, but because it's common in low power solar

Anderson Power Poles for regulated DC power. you can secure them
together with a tie wrap; you can't connect them backwards without
doing things that are obviously counter intuitive.
Fuel injection    connectors from Autozone for signal wires. they got
a million of    them, they are made for DC at useful current levels
Trailer    connectors for multiple lead serious power.
XLR connectors can be    found from 3 to 6 pins, and you can't jam a
5 pin into a 6 pin, so    you can't cross connnect

keep things dummy proof.


Utilizing two different serial ports simultaneously on a due I am trying to understand how the serial ports are configured on the due board. Please correct me if i'm wrong, but to my understanding, the due has:

Four separate serial ports ("serial", and "serial 1-3"), each with SX and TX pin functions
A USB port paired with serial, simultaneously sending and receiving data from the serial function via USB protocol

I'm currently sending MIDI data over serial1 with the required baud rate of 31250. I want to configure another serial function (assumingly with a different baud rate to match the IDE serial monitor) in order to monitor Serial.print messages simultaneously for debugging.

In setup():

Serial1.begin(31250);  //MIDI baud rate
Serial.begin(115200);

and then, in a for loop i want to monitor each value i in the array loop1[i]):

Serial.print(String(loop1[i]) + " ");

However, i can't seem to make it work... My question is, is it possible to transmit the MIDI data via serial, in parallel with serial.print data with a separate serial function?

You can't use MIDI on Serial and use Serial.print at the same time. You can though use MIDI on Serial1 and use Serial.print at the same time (or Serial2 etc).


Sending a double message for action to occur I'm currently designing a system for my GCSE coursework. For the coursework, I am making a bollard system, controlled by the internet / traffic lights.

I've been experimenting with an Arduino Uno and Ethernet shield, in order to fulfill the control by the internet.

When I telnet into my Arduino, and send it the command "S#UP", the red LED comes on, and stays on for 30 seconds. If I send the command again, the Arduino does not turn on the LED, unless the command was send twice, consecutively. Also, if I were to send a different command, for example "S#DOWN", the LED does not even turn on, no matter how many times I send it.

Does anyone have any ideas for my? Anything I've blatantly missed or got myself confused on?

#include <SPI.h>
#include <Ethernet.h>
String authcode, newstatus, command;
bool UP, DOWN, EMERGANCY;
long UPTime, DOWNTime, EMERGANCYTime, LastFlash;
bool NextFlash;

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

IPAddress ip(192, 168, 1, 177);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

EthernetServer server(1265);

char serverHost[] = "LambdaLaptop";
EthernetClient phpClient;

int R = 8;
int G = 9;

void setup() {
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.begin(9600);
  Serial.println("=----------------------=");
  Serial.println("=- Traffic Management -=");
  Serial.println("=-    System Loaded   -=");
  Serial.println("=----------------------=");

  Serial.println("");

  authcode = String("4b4fec50eaa13b98934c36863293b5cf");
  LastFlash = millis();
  NextFlash = HIGH;

  pinMode(R, OUTPUT);
  pinMode(G, OUTPUT);
}

void loop() {
  EthernetClient client = server.available();
  if (client) {
    if (client.available() > 0) {
      char thisChar = client.read();
      command += thisChar;
      ProcessCMD( command );
    }else{
     if(command.length() > 0 ){
       command = String("");
     }
    }
  }
  if( UP ){
    if( UPTime > millis() ){
      digitalWrite(G, HIGH);
    }else{
      UP = false;
      digitalWrite(G, LOW);
    }
  }else if( DOWN ){
    if( DOWNTime > millis() ){
      digitalWrite(R, HIGH);
    }else{
      DOWN = false;
      digitalWrite(R, LOW);
    }
  }else if( EMERGANCY ){
   if( EMERGANCYTime > millis() ){
     if( LastFlash + 100 < millis() ){
       digitalWrite(R, NextFlash);
       if(NextFlash == LOW){
         NextFlash = HIGH;
       }else{
         NextFlash = LOW;
       }
     }
    }else{
      EMERGANCY = false;
      NextFlash = HIGH;
      digitalWrite(R, LOW);
    }
  }
}

void ProcessCMD( String CMD ){
  if(CMD == "S#UP"){
    UP = true;
    UPTime = millis() + 30000;
    if(CMD.length() > 11){
      command = String("");
    }
  }else if(CMD == "S#DOWN"){
    // Make the thing go DOWN.
    // GREEN LIGHT
    DOWN = true;
    DOWNTime = millis() + 30000;
    if(CMD.length() > 11){
      command = String("");
    }
  }else if(CMD == "S#EMERGANCY"){
    // Make the thing go DOWN.
    // Flash RED beacon.
    EMERGANCY = true;
    EMERGANCYTime = millis() + 15000;
    if(CMD.length() > 11){
      command = String("");
    }
  }else if(CMD == "TEST"){
    UP = true;
  }else if(CMD == "TEST2"){
    UPTime = millis() + 30000;
  }else{
    if(CMD.length() > 11){
      command = String("");
    }
  }
}

void SetStatus( String newstatus ){
  if (phpClient.connect(IPAddress(192,168,1,10), 80)) {
    phpClient.println(String("GET /setstatus.php?authcode=") + authcode + String("&status=") + newstatus + String(" HTTP/1.1"));
    phpClient.println("Host: LambdaLaptop");
    phpClient.println("User-Agent: arduino-ethernet");
    phpClient.println("Connection: close");
    phpClient.println();
    phpClient.stop();
  }
  else {
    Serial.println("Couldn't connect to the system!");
    phpClient.stop();
  }
}

I do not have and ethernet shield at this moment to test on it your code but hopefully the next observations will help to solve your issue.

  If I send the command again, the Arduino does not turn on the LED,
  unless the command was send twice, consecutively.

It seems that your string is not correctly processed, probably caused by "garbage" from previous received string or incomplete string. I think is from this part of the code

 if (client.available() > 0) {
  char thisChar = client.read();
  command += thisChar;
  ProcessCMD( command );

You are trying to append a char (one byte) to your command string; by doing this you are not getting the received string necessarily because the "+=" is for retrieve char by char (for example, inside a while loop). First try to print thisChar variable to ensure what are you getting and also you can print client.available() to see how many bytes you got.

Second, for your ProcessCMD function it could be better to use pointers to handle the command variable, meanwhile you must clean command variable always (and not only when CMD.lenght > 11 ), i.e,

if(CMD.length() > 11){
  command = String("");
}

must be at the end of the ProcessCMD function

  command = String("");

Also you can ensure that when you set UP=true, also set DOWN=false and so on. I prefer the Switch-Case structure to handle commands.

Try to follow arduino examples to better understand.

Cheers.


It is possible to run an entire script on the Linux side? If so, how, what and where to do that? I am new to using Arduino Yun and I would like to know if it is possible to run an entire script on the Linux side. In my case the script should execute a HTTP request to a remote server, parse the subsequent HTTP response and return some value that then can be used in the Arduino sketch.

If it is possible, what I have to do? For example, how should I write and run script files? what programming language should I use? where I should put those script files on the Linux side?

Arduino Yun ships with python pre installed. You can copy python scripts from your pc to the yun with scp (or WinSCP or putty, if you're on windows). Once copied, just run it using Process from your sketch. As they are scripts, program name is python and the path to your script is its first argument (you can do that in a different way, but that would require some linux magic, which I suggest to postpone if you're new to it).

Other pre installed options include lua and bash. Other languages such as ruby, erlang and php are available as optional packages.


Arduino Uno + Adafruit Ultimate GPS Shield Serial issue I've had an Arduino Uno for a couple of months-making basic sketches-and recently purchased an Adafruit ultimate GPS shield and attached with soldered headers. This shield has 2 options for reading data, direct and soft serial.

I can sit near a window in my house and receive data using the direct method. This is just due to uploading a blank sketch and reading the serial window. Next, I tried to use one of the examples included in the Adafruit_GPS library and the serial window shows a bunch of nonsense updating.

Has anyone else seen this problem? I'm wondering if its the digital pins on the Arduino that I may have damaged since the example code has a simple phrase to display at the start, and I don't even get this.

Code eg: Serial.println("Get version!").

Just to verify, both boards have power and the direct method was giving me good GPS readings, the serial method gave me junk (not even a simple printed phrase to start), and I verified the Soft Serial switch was flipped and the baud rates matched in code and serial window.

I've attached pictures of the direct method results from that in the serial window, and then the junk results using an unaltered sample serial code. Any help with this would be appreciated.

It looks like you are using the wrong baud rate somewhere.

You mentioned that you had checked your baud rates but check again because the second terminal window looked as if the baud rate was wrong.

In your terminal window. Go to bottom right hand corner where it says 9600 and change it to match the serial speed set in your arduino code.

Or it could be that you are receiving too much data as per the bottom of this article:  https://learn.adafruit.com/adafruit-ultimate-gps-logger-shield/soft-serial-connect


NRF24L01 only receiving zeros I'm attempting to transmit very simple data across some NRF24l01 modules for testing purposes, and I've been following a YouTube guide.

Here is my code:

Trasmitter:

#include "RF24.h"
#include <SPI.h>

RF24 Radio (7, 8);
byte address[][6] = {"0"};
struct package{
   int on = 1;
};

typedef struct package Package;
Package data;

void setup() {
  Serial.begin(9600);
  delay(1000);
  Radio.begin();
  Radio.setChannel(118);
  Radio.setPALevel(RF24_PA_LOW);
  Radio.setDataRate(RF24_250KBPS);
  Radio.openWritingPipe(address[0]);
  delay(1000);
}

void loop() {
  Radio.write(&data, sizeof(data));

  Serial.println("Data sent:");
  Serial.println(data.on);
  delay(1000);
  }
}

Receiver:

 #include "RF24.h"
 #include <SPI.h>

 RF24 Radio (7, 8);
 byte address[][6] = {"0"};
 struct package{
    int on = 1;
 };

 typedef struct package Package;
 Package data;

 void setup() {
   Serial.begin(9600);
   pinMode(2, OUTPUT);
   delay(1000);
   Radio.begin();
   Radio.setChannel(118);
   Radio.setPALevel(RF24_PA_LOW);
   Radio.setDataRate(RF24_250KBPS);
   Radio.openReadingPipe(1, address[0]);
   Radio.startListening();
   delay(1000);
 }

 void loop() {
   while(Radio.available()){
     Radio.read(&data, sizeof(data));
     if(data.on == 1){
       digitalWrite(2, HIGH);
     }
     else if(data.on == 0){
       digitalWrite(2, HIGH);
     }
     else{
       digitalWrite(2, LOW);
     }
     Serial.println(data.on);
   }
   while(!Radio.available()){
     Serial.println("Error");
   }
   delay(1000);
 }

When I run the code on each respective unit, I receive only zeros on the receiver. Since I don't see where data.on could get set to zero in my code, I'm assuming there is a communication issue somehow between the two modules, even though Radio.available() is functioning properly.

Am I missing something obvious?

The OP wrote:

The issue turned out to be that the SPI pins on the MEGA are assigned differently than the UNO, and the code was actually working the whole time. I cant thank you enough for helping me, even if it turned out to be in vain.


Arduino Wire.h library: how to communicate with an LCD? I am having an Arduino Uno and a C2042A LCD with I2C shield on it. Because the VirtualWire library does not work for me. I tried only the wire library but it's still not working:

My code:

#include <Wire.h>

void setup() {
  Wire.begin(0x63);
}

void loop() {
  Wire.write(4);
}

I just read on this website which commands you have to use but it doesn't do anything. What is my fault, how to solve it?

SOLVED!

I forgot to write beginTransmission(). Here's my code:

#include <Wire.h>

void setup() {
  Wire.begin(0x63);
}

void loop() {
  Wire.beginTransmission(0x63);
  Wire.write(byte(0x00));
  Wire.write("Temperatur:");
  Wire.endTransmission();
}


Large values are changed by Arduino when viewing with `Serial.print()` Why are (big) values being changed?

I tried out printing some values and noticed bigger values are changed more, they seem to be rounded to quarters and then to halves when the value gets bigger.

MWE

void setup() {
  Serial.begin(9600);
  Serial.print("12457591.51 is changed into ");
  Serial.println(12457591.51);
  Serial.print("2457591.80 is changed into ");
  Serial.println(2457591.80);
  Serial.print("1234567.89 is changed into ");
  Serial.println(1234567.89);
}

void loop() {}

gives me

12457591.51 is changed into 12457592.00
2457591.80 is changed into 2457591.75
1234567.89 is changed into 1234567.87

I'm working with an Arduino Nano ATMega328.

Background
I need the calculation (2457591.33 + 0.5 - 2440588)  * 60 * 60 * 24 to be precise to within preferably a hundred, but currently it's off by about 7000.

Floating point numbers doesn't have infinite precision. But you can always change your equation to use smaller numbers (preferably integers or longs as floating point is extremely slow)

For example on AVR Freaks they mentioned precision about 6 or 7 digits. It makes sense as 24bits signed number range is from -8388608 to 8388607


WiFi Connection With a Enterprise WLAN I have an ESP32 and want to connect it to the WLAN at my office. Based on my current knowledge of the Arduino, we use the WiFiClass to connect to a WLAN and then use a WiFiClient to use the WiFi for data transfer.

In order to connect to the WLAN at my office, a certificate is needed. I have asked the network guys to issue a x.509 certificate and plan to use the WiFiSecureClient class.

The problem is that my WiFi.begin(ssid) method never leaves the following while loop:

Wifi.begin(ssid); // my office needs a certificate to connect to the wifi at the first place
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}

Note that to connect to my office network, no password is needed. The x.509 certificate is enough for the connection to establish.

Only after a WiFi connection is established, I can set the WiFiSecureClient parameters of the CA. But to connect to the WiFi, I need the certificate.

This is very confusing. Could someone please clarify a way our for me in this situation.

The Arduino API for ESP32 does not support your desired configuration.

The ESP32 is capable, but there is no easy "Arduino" interface to configure it.

Instead you will have to directly interface with the ESP32 SDK and configure things manually.  That won't be easy.

This example code shows you how it can be done - however that code is not designed to run in the Arduino environment, so you will first need to understand exactly what it is doing and then adapt it to suit.


Arduino Due ( Atmel Microcontroller) IC Heat up and led goes off I was connecting L293d Motor Driver IC with an Arduino Due Board. May be due to wrong connections, but when I made the grounds common, the Arduino LED goes off and Atmel IC heats up. When I reconnect my Due board with my PC anytime, the LED turns on and slowly dims to off and Atmel IC fries up.

I wanted to repair it. What should I do?

I have checked the input voltage of the AMS1117 3.3V regular IC as 3.8 V, while the output is 2.2 V. If I externally give 5 volt at input again, the input voltages drops. The regulator is loading.

I thought of replacing the regular IC?
Will that work?

Also I externally powered the Board with 3.3V by its pin labeled "3.3V" . The LEDs glow on and did not go off. But the Atmel Microcontroller IC becomes very hot.

What should I do?

Motor driver boards exist to allow an MCU to control a motor without having to supply its power. If you try to power motors from the Arduino as well, they draw too much current and things get hot or damaged.

The 3.3v pin is only for supplying modest amounts of current at 3.3v from a 5v Arduino. You can not back-power the board with it. I don't know what happens if you try, but I bet it isn't good...


Sizes of the original ESP32-DevKitC-32U Wifi board I know that this topic does not apply to Arduino, but for me it is important to find a solution to the problem. I know the consequences.

I'm creating a pcb board into which the original ESP32-DevKitC-32U module will be inserted. I can not find the original dimensions of the board, in particular the distance between the contact rails. The site espressif has a small description.

27.9mm is indicated here. It is not clear to me, is this the full width of the board or the distance between the contacts?

What I want to do:

It is very important for me to find out the correct dimensions of the original board. Maybe someone has such a board and can measure this size?

The distance of the headers is breadboard and perfboard compatible for 0.1" (2.54 mm) pin standard. 25.4 mm is 10 rows.


Measure the duration a pin is in a HIGH state I'm struggling with getting the button configuration. Simply, I have a LED controlling setup for a button to increase its brightness when pressed. However, I would like to have it setup like this:

When button is pressed.
change the value by 1,
wait for 500ms,
Then go fast (with the usual void loop time).

Is it something to do with interrupts? If I just write it like below, it actually (obviously) goes by +1 by itself, even when button is not pressed.

void loop() {
  if(digitalRead(button_pressed) == HIGH) {
    current_state = current_state+1;
    delay(500);
    current_state = current_state+1;
  }
}

Non-blocking version.

bool old_button_state = LOW;
void loop()
{
    if(digitalRead(button_pressed) == HIGH)
    {
        current_state = current_state+1

        if( old_button_state==LOW )
            delay(500); // long delay
        else
            delay(100); // short delay

        old_button_state = HIGH;
    }
    else
    {
        old_button_state = LOW;
    }
}

Simplistic version.

void loop()
{
    if(digitalRead(button_pressed) == HIGH)
    {
        current_state = current_state+1
        delay(500);// long delay

        // repeat while the button is being pressed
        while(digitalRead(button_pressed) == HIGH)
        {
            current_state = current_state+1
            delay(100); //short delay
        }
    }
}

Ideally you wouldn't just wait for 500ms, but 'break out' of this delay as soon as the button is released.


ESP8266EX along with Arduino Due rev3 to check wifi status Hi i am using ESP8266EX along with Arduino Due rev3 to check wifi status. when i compile my following sketch compiler give me error
User\Awais\Document\Arduino\liberaries\espsoftserialmaster\softserial.cpp:27:18: fatal error: gpio.h: no file or directory found
any one help me solve this problem

    #include <SoftwareSerial.h>
    SoftwareSerial ESPserial (15,14); //RX|TX

     void setup() {
  // put your setup code here, to run once:

  Serial.begin(115200);
  ESPserial.begin(115200);
  Serial.println("NL & CR");
}

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

  if (ESPserial.available()){
   Serial.write(ESPserial.read());
  }

if (Serial.available()){
ESPserial.write(Serial.read());
}
  }

And where did you get that SoftwareSerial library? SoftwareSerial libraries are architecture dependent. You can't use AVR ore esp8266 SoftwareSerial library with ARM.

Due has no need for SoftwareSerial, it has 4 Serial ports configured.


esp32 voltage divider readings off Trying to read from a voltage divider circuit using two 240 Ohm resistors.  Getting a reading of 6.0, when it should be 1.65.  Circuit is powered by a bench 3.3V and both the Huzzah32 and circuit are grounded.  Using USB for the Huzzah32. Any thoughts?
  void setup()
{
  Serial.begin(9600);
}
void loop()
{
  int sensorValue = analogRead(A9);
  float voltage = sensorValue * (3.3 / 1023.0);
  Serial.println(voltage);
  delay(1000);
}

First, ESP32 ADC is 12-bit, not 10-bit. therefore the formula should be:
float voltage = sensorValue * (3.3 / 4096.0);

Secondly, ESP32 ADC is not really linear, and tend to have lower reading than the actual value. You will need to do some calibration if you want to get a more accurate reading. You can take a look at my github on esp32-adc-calibrate.


Help with a function that accepts different parameter types I'm trying to create a function that prints out an XML tag with a value. I have the code below, but kind of stuck. I'd like to be able to call the function, and pass a value that could be a float, int, string or char. Appreciate any help.

char PingTime[6] = "3ms";
char PingText[60] = "ping reply blah blah";
float humidity = "40.56";
int DigialPin = 0;

PrintXMLTag(cl,"pingtime",PingTime);
PrintXMLTag(cl,"PingText",PingText);
PrintXMLTag(cl,"humidity",humidity);
PrintXMLTag(cl,"DigialPin",DigialPin);

void PrintXMLTag_DEC(EthernetClient cl, const char* tag, NotSure?? val)
{
  char tmp [100];
  StrClear(tmp,100);

  // If val type is float ----------------------
  int d1 = val; // Get the integer part
  float f2 = val - d1; // Get fractional part
  int d2 = trunc(f2 * 10000);// Turn into integer
  sprintf(tmp,"<%s>%d.%02d</%s>\n",tag,d1,d2,tag);
  // end float

  // If val type is string ----------------------

  // If val type is int ----------------------

  // If val type is char ----------------------

  cl.print(tmp);
}

Update, now converting the type to char before calling the PrintXML function resolves my initial issue. If I use the code below it seems to chew up a lot of memory, is there something obviously wrong? As a workaround I'm just printing the XML tags using cl.print and the memory usage is stable.

void PrintXMLTag(EthernetClient cl, char* tag,  char* val)
{
  char tmp [100];
  sprintf(tmp,"<%s>%s</%s>\n",tag,val,tag);
  cl.print(tmp);
  StrClear(tmp,100);
}

take a look at: http://www.cplusplus.com/doc/tutorial/functions2/

template <typename SomeType>
SomeType sum (SomeType a, SomeType b)
{
  return a+b;
}

This appears to be what you want.


Arduino Serial Port. COM1 does not exist Hello everyone I'am new to this site so please bear with me.

I have an Arduino Uno that I'm using in my simple project using VS 2008. I got this error says The Port COM1 does not exist. The flow of my project is after inserting a coin into the coin slot the arduino will pass the data into my project and it will display into a Label or Textbox the value of the inserted coin.

Never used Visual Basic but:

There is no such thing as Serial1 on Arduino Uno. There is only Serial. (Serial1, 2, 3 are available on ArduinoMega) Reference: Arduino
For COM port you should check your device manager. Often it appears at COM3 so probably you should check this issue.

Just for curiosity: Why VB? Is it only your choice or it use less ram or memory, works faster or anything?


How to multiplex multiple displays? I want to use 2 "displays" with 4 digits. The displays are common cathodes with cathode transistors connected to the digits, as the figure:

The segments of both displays are connected together on the digital pins.
The problem is that I tried to use some libraries for 7 segment displays and they worked with only one 4 digit display, but when I connected the second display, did not display the numbers correctly. The numbers that will be written are integers and I'm using mega 2560 R3.

Here are my attempts:

#include "SevSeg.h"
byte digitPins_1[] = {29, 30, 31, 33};//Digits pins
byte digitPins_2[] = {25, 26, 27, 28};
byte segmentPins[] = {38, 39, 40, 41, 42, 43, 44, 46}; //segment pins
SevSeg disp1;
SevSeg disp2;

void setup() {
disp1.begin(P_TRANSISTORS, 4, digitPins_1, segmentPins);
disp2.begin(P_TRANSISTORS, 4, digitPins_2, segmentPins);
disp1.setBrightness(20);
disp2.setBrightness(20);
}

void loop() {
disp1.setNumber(8888, 0);
disp1.refreshDisplay();
disp2.setNumber(1111, 0);
disp2.refreshDisplay();
}

or using another lib:

#include <SevenSeg.h>
SevenSeg disp1(38,39,40,41,42,43,44);//segment pins
SevenSeg disp2(38,39,40,41,42,43,44);
int digitPins1[4]={29,30,31,33};//digitpins
int digitPins2[4]={25,26,27,28};

void setup() {
disp1.setDigitPins(4,digitPins1);
disp2.setDigitPins(4,digitPins2);
disp1.setDigitDelay(1600);//time delay
disp2.setDigitDelay(1600);
disp2.setActivePinState(HIGH,HIGH);//seg active HIGH, digit active HIGH
disp1.setActivePinState(HIGH,HIGH);
}

void loop() {
disp1.write(8888);
disp1.clearDisp();
disp2.write(1111);
disp2.clearDisp();
}

The code instantiates two instances of the SevSeg class.  This may or may not work.  Really depends on if the class uses any resources are not meant to be shared between multiple instances of that class.  For instance, it is unlikely that one hardware timer can be used for more than one purpose at a time.

But the code continues on to use the same (anode) pin resources for both instances of the class. This is likely not going to work.

Apologies for being vague using qualifier like "unlikely" instead of simply stating that it will not work.  Truth is, one might be able to write a class that can deal with multiple instances of its self.  But it would be very difficult and a far more complex programming task than to simply use one instance for all 8 digits.

In case there is a question as to the maximum number of digits supported for one instance of the SevSeg class, this line is in the one of the SevSeg header files:

#define MAXNUMDIGITS 8 // Can be increased, but the max number is 2^31


Issues with I2C and Wire.Available() I am working on a project which requires communication from an Arduino Due (Master) and an FDC2214Q1 C to D IC (Slave), but there is some variability as to whether the code works or not depending on seemingly random variables.

I have narrowed the issue to the function I am using to read 2 bytes from the slave. The code is pretty standard, and is as follows:

// Read 2 byte from the FDC at 'address'
uint16_t FDC2214::read16FDC(uint16_t address) {

    uint16_t data;

    Wire.beginTransmission(_i2caddr);
    Wire.write(address);
    Wire.endTransmission(false); //restart
    Wire.requestFrom(_i2caddr, (uint8_t) 2);

    while (!Wire.available());
    data = Wire.read();
    data <<= 8;

    while (!Wire.available());
    data |= Wire.read();
    Wire.endTransmission(true); //end

    return data;
}

The code seems to get hung up sometimes on while (!Wire.available()) and if I simply remove that step, I never get the correct Device ID.

However, if I simply unplug the DUE and close the Serial Monitor and replug in and upload, it works. I just kind of upload and disconnect a few times and open and close the Serial Monitor and sometimes it works great, other times it gets hung up?

Any ideas what could be causing such and issue?

Code based on this library: https://github.com/zharijs/FDC2214/blob/master/src/FDC2214.cpp

Final code that has been working, removes need for While loop:

uint16_t FDC2214::read16FDC(uint16_t address) {

    uint16_t data;
        Wire.beginTransmission(_i2caddr); //queuing the slave address
        Wire.write(address); //queuing the register address/pointing regsiter
        byte busStatus = Wire.endTransmission(); //transmit all queued data and bring STOP condition on I2C Bus
        if(busStatus != 0x00)
        {
           Serial.print("Transmission Error....!");//transmissiion error wait here for ever
           while(1);
        }

        Wire.requestFrom(_i2caddr, (uint8_t) 2);     //this is looping code; when 2-byte has arrived, the loop terminates
        data = Wire.read();   //read the first byte from FIFO Buffer
        data = (data <<8)| Wire.read();   //16-bit data is formed
        Wire.endTransmission(true); //end
        return data;
}

Adafruit tells to avoid the Arduino Due. One of the reasons is the I2C bus. Can you use an other Arduino board? For example one of the MKR boards with a SAMD21 processor.

The Due has pullup resistors on the board for SDA and SCL which are too low in value. Sometimes the I2C bus with SDA and SCL works, but sometimes it does not work at all. Perhaps you are able to remove the pullup resistors at SDA and SCL from the board.

If possible use Wire1 with SDA1 and SCL1. Those have no pullup resistors at all, so you need to add 4k7 pullup resistors to 3.3V. When you use a library, you might have to change the library to use "Wire1" instead of "Wire".

You need to remove these, they are not doing something:

while (!Wire.available());    <- not doing something

Remove the Wire.endTransmission at the end.

Wire.endTransmission(true);   <- remove this
return data;

That library does not use the Wire library in a proper way.

The pullup resistors are 1k5 or sometimes 1k and are located in the upper-right corner, near pin 20 and 21. A value of 1k5 should be okay, when there are no other pullup resistors. When you board has 1k resistors, then I suggest to remove them.

Removing them is possible with a soldering iron and a big blob of solder. Check if the board is clean afterwards, for example with a magnifier. Avoid overheating your expensive Arduino Due board.

The I2C bus needs pullup resistors to work. A normal value is 4k7. Sometimes there are already 10k pullup resistors on a sensor module.

If the I2C has problems, start by using short seperate wires for SDA and SCL. When a cable is used for the I2C bus, then the cable is probably the problem and not the pullup resistors.


Output specific value using port manipulation How can I output a specific value on a pin using port manipulation?

Example: I want to use this code but without any arduino functions, just with port manipulation:

for (int i = 0; i < 255; i++){
analogWrite(11, i); //write the i value to pin 11
}

I want to replace the analogWrite function with register manipulation. Is that possible?

The analogWrite function is just an interface to setting up the hardware timers to do PWM (pulse-width modulation). I have a page about timers which you may find helpful.

Depending on which pin you want to output the PWM to, the registers will be slightly different. Here is one example from my page:

const byte OUTPUT_PIN = 3;  // Timer 2 "B" output: OC2B

const byte n = 224;  // for example, 1.111 kHz

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

  TCCR2A = bit (WGM20) | bit (WGM21) | bit (COM2B1); // fast PWM, clear OC2A on compare
  TCCR2B = bit (WGM22) | bit (CS22);         // fast PWM, prescaler of 64
  OCR2A =  n;                                // from table
  OCR2B = ((n + 1) / 2) - 1;                 // 50% duty cycle
  }  // end of setup

void loop() { }

  How can I output a specific value on a pin ?

I should point out that the only values you can output are +5V or 0V. There is no provision for outputting (say) 3.7V. The only way you can sort-of do this is by using PWM and then running the result through an RC filter. There is an example on my page about op amps.

An example circuit could be:

This uses a resistor and capacitor to filter out the "ripple" in the PWM, giving you a reasonably smooth output voltage, proportional to the PWM duty cycle.

For a larger range of output values a rail-to-rail op-amp would be preferable.


Why am I getting only around 40% the range of my ADS1115 using an Arduino Uno? I've connected my ADS1115 to an Arduino Uno as in the diagram (Vdd - 5V, Gnd - Gnd, SDA/SCL - SDA/SCL), all powered from the USB on a PC, with A0-3 unconnected, and am getting readings of around 3000 (i.e. 3000/65535 on 5V supply = 0.23V) from all four analog pins. Then if I connect them to 3.3V output on the arduino they give me only 17625 (i.e. 1.34V) i.e. about 40% of the full range I expected. If I try with a seperate 5V supply, it's still the same problem. Why is this?

P.S. sorry the code format below isn't very good, but basically it reads the four pins by
int16_t V1 = ads.readADC_SingleEnded(PIN).

#define THERMISTORPIN1 0
#define THERMISTORPIN2 1
#define SHELLPTPIN 2
#define SPAREPIN 3
#include < Wire.h >
#include < Adafruit_ADS1015.h >

Adafruit_ADS1115 ads(0x48);  //16 bit ADC add-on for arduino for better temperature resolution
float Voltage = 0.0;

void setup(void)
{
    Serial.begin(9600);
    ads.begin();//
}

void loop(void)
{
    int16_t V1;
    int16_t V2;
    int16_t V3;
    int16_t V4;
    long cumV1;
    long cumV2;
    long cumV3;
    long cumV4;
    float avgV1;
    float avgV2;
    float avgV3;
    float avgV4;

    //take readings of voltages between resistor and thermsitor
    int i=0;

    while(i<6) {
        V1 = ads.readADC_SingleEnded(THERMISTORPIN1); //5 readings to allow the arduino capacitors to equalize with the pin voltage, to increase accuracy
        V2 = ads.readADC_SingleEnded(THERMISTORPIN2);
        V3 = ads.readADC_SingleEnded(SHELLPTPIN);
        V4 = ads.readADC_SingleEnded(SPAREPIN);
        i++;
        delay(10);
    }

    while(6<=i && i<16) {
        cumV1+= ads.readADC_SingleEnded(THERMISTORPIN1);  //multiple measurements from which to take an average, to increase precision
        cumV2+= ads.readADC_SingleEnded(THERMISTORPIN2);
        cumV3+= ads.readADC_SingleEnded(SHELLPTPIN);
        cumV4+= ads.readADC_SingleEnded(SPAREPIN);
        i++;
        delay(10);
    }

    avgV1=cumV1/10;
    avgV2=cumV2/10;
    avgV3=cumV3/10;
    avgV4=cumV4/10;

    //print out information to serial monitor on laptop
    Serial.print(V1);
    Serial.print(" ");
    Serial.print(V2);
    Serial.print(" ");
    Serial.print(V3);
    Serial.print(" ");
    Serial.println(V4);
    Serial.print(" ");
    Serial.print(avgV1);
    Serial.print(" ");
    Serial.print(avgV2);
    Serial.print(" ");
    Serial.print(avgV3);
    Serial.print(" ");
    Serial.println(avgV4);
    //Serial.println();
    delay(1000);
}

Your readings are correct because you have the default gain set. You have incorrectly assumed that you can convert the ADC reading from your 16-bit ADC to Volts by dividing by 2^16 - 1. Your ADC has gain settings to have more accurate readings for certain voltage intervals. If we look at the example sketch, we see

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

  Serial.println("Getting single-ended readings from AIN0..3");
  Serial.println("ADC Range: +/- 6.144V (1 bit = 3mV/ADS1015, 0.1875mV/ADS1115)");

  // The ADC input range (or gain) can be changed via the following
  // functions, but be careful never to exceed VDD +0.3V max, or to
  // exceed the upper and lower limits if you adjust the input range!
  // Setting these values incorrectly may destroy your ADC!
  //                                                                ADS1015  ADS1115
  //                                                                -------  -------
  // ads.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3mV      0.1875mV (default)
  // ads.setGain(GAIN_ONE);        // 1x gain   +/- 4.096V  1 bit = 2mV      0.125mV
  // ads.setGain(GAIN_TWO);        // 2x gain   +/- 2.048V  1 bit = 1mV      0.0625mV
  // ads.setGain(GAIN_FOUR);       // 4x gain   +/- 1.024V  1 bit = 0.5mV    0.03125mV
  // ads.setGain(GAIN_EIGHT);      // 8x gain   +/- 0.512V  1 bit = 0.25mV   0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    // 16x gain  +/- 0.256V  1 bit = 0.125mV  0.0078125mV

  ads.begin();
}

Your ADC has a default gain of 2/3, or 0.1875mV per count. You say when you connect 3.3V to the pin, you get a reading of 17625. Thus we have

17625 * 0.1875 / 1000.0 [V]
= 3.3046875 [V]

Which is a correct reading. A reading on a floating pin (nothing attached) is irrelevant. Use the correct factors from above to convert your read ADC value to voltage.

Side note: In line

avgV1=cumV1/10;

You have the float avgV1 on the left and cumV1 (a long) divided by 10 on the right; this will do a integer division. Make sure to divide by 10.0f if you want a floating point average.

Side note 2:

These factors do make sense. If you apply positive 6.144V on the 2/3rd gain setting, you will read the maximum positive value of a int16_t, i.e. 2^15-1 = 32767 (solve above formula for the count). If you apply -6.144V, you get -32768; thus the full 16-bit number space is used. On differnt gain settings it analogous.


VGAX library only allows 4 colors, library or hardware limitation? I'm working with VGA DSUB-15 output, however VGAX only allows for 4 colors. I'm using an Arduino Nano that uses an 8-bit atmel chip, and I've seen many 8-bit computers of which have a bit more than 4 colors.

It's a memory limitation. The ATmega328 has 2 KB of RAM, and a 120x60 framebuffer at two bits per pixel (four colors) uses 1.8 KB. There's no room for more.


Resistors on LCD - does a small difference matter? I recently have tried to connect an LCD to my Arduino Uno. The tutorial
tells me I need a 220 Ohm resistor, but the only ones I have are 330 Ohm. Does it matter?

Here's the Fritzing diagram by the way:

No, it doesn't matter. That resistor is just for the backlight LEDs. The larger the resistor the dimmer the backlight will be.  As @VE7JRO suggests, you can always put two 330Ω resistors in parallel, which will halve the resistance to 165Ω, which will give a brighter backlight.


How to connect two LED strips (APA102/SK9822) to Arduino UNO? So what I am trying to do is to connect two SK9822 LED strips to Arduino UNO.

I am a bit confused about how to properly set this up so I can individualy control any led. So obviously 5V should go to 5V and GND to GND, but what about the CLOCK and the DATA pin.

According to the tutorials and stuff I found here, CLOCK pin needs to be connected to pin 13 and DATA to pin 10, but they only use one strip... so what I am trying to ask is can LED strips share pins? Can they be connected to the same CLOCK pin and different DATA pins or how can i set this up to use the minimum amount of pins?

I was planning on using FastLED library, where it looks like you can specify which pin is DATA and which is CLOCK,

FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN>(leds, NUM_LEDS);

Is this because different boards have different CLK and MOSI pins or can i use any pin and set it as CLOCK or DATA? This is probably obvious but I am new to this and this is my first project.

I don't know about SK9822 LED strips, however the other type of led strips can be used with every pin; this is to support multiple LED strips.

Because every LED strip has its own CLK input (wire), it would be inconvenient to share them... I'm not sure if it is possible practically, because the timing is critical and if you have just one 'master' CLK signal than the data signals for all LED strips should be sent in time. Also writing the library would be more difficult, since there is a relation between a (shared) CLK signal and other data lines.


how to count blinking LED flashes using arduino uno boards and LDR? i want to know code for counting the flashes of LEDs and display no. of flashes in particular time given.by using LDR.
basically i tried it with interrupts but i'm not getting it,so please help in this regard.

LDRs only give an analog output, proportional to the amount of light.

To make it give a HIGH and LOW value, you have to tweak the other resistor used in the voltage divider.

Alternatively you could use analogRead and add a threshold value in your code.


How to increase current in Arduino uno? How to increase current in O/P port in Arduino uno ?
to make it 200mA How I can do this?
It can in proggraming add more current
Which sample way to increase current ?
To control 2 Dc motor which normally work with 3 AA battery
Thanks

You add a transistor. Just like when you're controlling a relay, which needs more current that the Arduino can provide.


How to clear output buffer of Arduino Uno? I have coded arduino for DHT11 which used to print humidity in first and temperature in second line. But some times when I open SerialPort I get absurd data.

You can't.

The data you are seeing has already been sent by the previous execution of the sketch before the main MCU was reset. That data resides in a small buffer within the USB interface chip (or even within the USB CDC/ACM / USB UART driver itself, depending on your OS) to which you have no access.

You just have to ignore that data. The simplest way is to put a marker at the start of your program to indicate that whatever is receiving the data should start its receiving from this point on. Something like:

Serial.println();
Serial.println("START");


Data from PROGMEM array mismatches initialisation The amount of memory needed for my user interface is outrageous. Hence I decided to use flash memory. But after some successful readouts from program space, problems emerge.

Updated:
I have some sort of initialisation files to collect all global arrays which go into flash like this: (intitialisation.cpp)

#ifndef INITIALISATIONDEF
#define INITIALISATIONDEF

#include "initialisation.h" //which includes Arduino libraries and "globals.h"

const uint8_t gl_PsNMenuType[MAXMENUS] PROGMEM = { 0, 0, 0, 0, 0};  // this is, what I intend to read out later.
const uint8_t gl_PsNMenuParent[MAXMENUS] PROGMEM = { MAXMENUS, 0, 0, 0, 0};
const uint8_t gl_PsNMenuFixTexts[MAXMENUS][MAXFIXTEXTSPM] PROGMEM = {
  { 20, 2, MFTS, MFTS, MFTS}, // 0
  {2, 9, 1, MFTS, MFTS}, // 1
  {2, 10, MFTS, MFTS}, //2
  {2, 11, MFTS}, //3
  {2, 12, MFTS} //4

};
#endif

Updated:
while I propagate all global vars via another header (globals.h):

#ifndef GLOBALS
#define GLOBALS
#define SDTXT

#define MAXMENUS 80
#define MAXFIXTEXTSPM 5

#include "initialisation.h"
extern const uint8_t gl_PsNMenuType[MAXMENUS];
extern const uint8_t gl_PsNMenuParent[MAXMENUS];  // referenz auf den übergeordneten MP
extern const uint8_t gl_PsNMenuFixTexts[MAXMENUS][MAXFIXTEXTSPM];  // Liste der festen Menütexte zu jedem MP
#endif

as one can see, I do not initialise my arrays fully, as I'm in a development phase, but the first bytes should be zeroed out correctly AFAIK.

But, when accessing my stored values later in a third file: (uimenu.cpp)

#include "uimenu.h" // which includes globals.h and initialisation.h

// somewhere in the code inside a function, with uint8_t mp=0:
Serial.print(pgm_read_byte(gl_PsNMenuType[mp]));

The last line should print 0, as stated in initialisation, but it prints 12.

So, I think, I'm doing sth. substantially wrong here, but have no clue at the moment. I have several guesses:

I should not use const with PROGMEM. I did this to be informed by the compiler, if I accidentally write to an array stored in flash.
I made some mess with #includes, perhaps with order of occurrence. At the moment I try to sort the order out.
There's something with having global variables or arrays defined and declared in a header and accessed in another source files function. But I cannot imagene, what.
Updated: something wrong with my indices for my arrays? is uint8_t insufficient?

If you need more information or code, I'll edit my question accordingly. Thanks in advance! I appreciate any help.
(all files were edited for brevity before posting them)

Update:
I moved the definitions of the progmem arrays to the source file and all macro constants (#define) to globals.h. The outcome is: different numbers are printed, but they are wrong whatsoever. I poked elsewhere into the progmem array and got other wrong numbers.

@TMa: seems to work! I totally missed the necessity of referencing the array element. Thanks a lot. But I did not get any compiler warnings without the reference operator. Why isn't this call type-safe?

The PROGMEM word is an attribute, not a type. It might be type-safe but not attribute-safe (if there is such a thing). See Data in Program Space

Reference

Putting constant data into program memory (PROGMEM)


Including libraries from header files sometimes doesn't work I, once again have difficulties including libraries from code files other than my .ino file.

I have several .cpp and .h files in my project to keep it sorted and clean.
However one of my header files starting like this:

#ifndef DPLANDEF
#define DPLANDEF
#include <Arduino.h>
#include <EEPROM.h>
#include "syssettings.h"

yields the following errors:

  In file included from
  /var/folders/jl/nv1qvh6n569cxq9xxfd6dx980000gn/T/build4605486877500371361.tmp/dplan.cpp:2:0:
  /var/folders/jl/nv1qvh6n569cxq9xxfd6dx980000gn/T/build4605486877500371361.tmp/dplan.h:5:20:
  fatal error: EEPROM.h: No such file or directory  #include
                      ^ compilation terminated. Fehler beim Kompilieren.

EEPROM.h should be known to the IDE, because I can find it in the libraries menu, too. If it was a custom library, I might have botched something during installation, but this is a standard library. It should work out of the box. What's the problem here?

The problem here is that it's a header file.  The IDE doesn't treat header files like it does INO files - it doesn't parse them for included libraries, etc.

In order for it to work you must also include EEPROM.h in your main INO file so that the IDE knows that you want to include it in the rest of your files.


Detecting the light source location using multiple photoresistors I am not an expert yet, so please forgive any possibly wrong terminology that I may have used.

I am planning to place 6 light sensors in 1 meter (or maybe more) distance from one another, like this (sorry about the bad schematic, I am not an expert, but I hope it makes sense):

simulate this circuit – Schematic created using CircuitLab

I am going to place them in a relatively dark room. My goal is, when I am pointing a flash light towards them to be able to tell which sensor is measuring the highest values (where the light is coming from), and for how long (in milliseconds).

I know how to do the connections and measure values. My questions are two:

Which is the most efficient way to detect which of the 4 sensors is recording the higher values? I am assuming I have to compare the values that they are recording. However, I think that if in each loop I sort the captured values, the process might become heavy. I guess I could minimise the comparisons, since for example if LDR1's value is higher than LDR2 and LDR3, I can assume that the light source is cannot be pointing towards LDR6 for example. However, I am thinking that maybe there could be an even more efficient way to detect that (not necessarily in software).
Since the room will not be completely dark, the analog pins will record some values even when I am not pointing the flash light towards them. Is there a way to filter that out? I have come across calibration (https://www.arduino.cc/en/tutorial/calibration), but I am not sure whether this is the optimal solution. Please take into account that the light source might not be very strong (but its light will definitely be brighter than the room light).

The answer from Curt Sampson provides several good design considerations, plus the quite-reasonable suggestion that you run some experiments to characterize your LDRs and their placements.

Note that if you want to know which sensor has the highest reading, a simple find-maximum-value loop will do that, without any sorting:

int maxR = reading[1], maxS=1;
for (byte i=2; i <= nSensors; ++i) {
  if (reading[i] > maxR) {
    maxR = reading[i];
    maxS = i;
  }
}
// Now we know sensor maxS has max reading, maxR

The code above follows the 1–6 numbering scheme given in the question, and assumes that reading[i] stands for the reading from sensor i.

Code below, however, numbers the sensors and their readings from 0 to 5 instead of from 1 to 6, to allow simpler conditions in for loops.  From a programming standpoint, it makes sense to call the first sensor 0 if its data is stored in cell 0.

Finding x, y direction of the light

Assumptions behind the following code are that higher readings indicate more light, and that if necessary some background-lighting calibration has been done, and that background lighting has already been subtracted from readings data.  We also assume that maximum readings are less than (2¹⁵)/N, where N is number of sensors.

The point of the following code is to set two variables, x and y, that represent the relative location of a light source.  For example, if x and y are both positive, the light is above and to the right of the top right LDR.  If  x is negative and  y is near zero, the light is to the left of the middle-left LDR.  If knowing the signs of x and y is adequate for your purpose, then there's no need to do more arithmetic than shown.  On the other hand, if you want to compute some sort of angle, you can use atan2(y, x) to compute the direction of the light, in radians.

int reading[nSensors];
const int xdir[] = { -1, 1, -1, 1, -1,  1}; // x-direction sensor weights
const int ydir[] = {  1, 1,  0, 0, -1, -1}; // y-direction sensor weights
int x=0, y=0;
for (byte i=0; i < nSensors; ++i) {
  x += xdir[i] * reading[i];
  y += ydir[i] * reading[i];
}

Edit 1: Tracking the time a light is on

Issues with light-timing include what levels to start or stop timing at; necessary resolution (milliseconds? minutes?); necessary range (eg, is what happened a minute ago relevant); and when to reset accumulated time data.  It may be simplest to track the on times of all the sensors at the same time, then select one of the times or combine some times.  Do you want the largest time, the newest time, the newest large time, or the time corresponding to the largest light?

For example, the code below tracks light levels that remain high long enough to register, in smoothed averages, as above some threshold.  At intervals, current indications are rotated into bit maps that track the last 16 on-off levels for each LDR, and counts of number-of-ons are updated too.

// Initialization ...
uint16_t expAvg[nSensors]={0};  // Exponential averages over time
uint16_t bitMaps[nSensors]={0}; // Track each sensor's last 16 on-off levels
byte onCounts[nSensors]={0};    // Number of recent times sensor avg > threshold
unsigned long prevMilli=millis();
const int markInterval=50;   // ms interval for recording light levels
const int onThreshold=547*16; // Some light-is-on threshold

// In each pass of loop() ...
for (byte i=0; i < nSensors; ++i)
  expAvg[i] = reading[i] + 15*expAvg[i]; // exponential averaging with 1:16 weight

// In loop(), at intervals ...
if (millis()-prevMilli >=  markInterval) {
  prevMilli = millis();
  for (byte i=0; i < nSensors; ++i) {
    onCounts[i] += (expAvg[i] > onThreshold) - (!(bitMaps[i] & 0x8000));
    bitMaps[i] = (bitMaps[i]<<1) | (expAvg[i] > onThreshold);
  }
}


How to convert char array to String in arduino? I want to convert const char array in PROGMEM to String. How do I do this?

const char charArray[] PROGMEM = "Some text";

you can use a cast to __FlashStringHelper to invoke the right constructor of the String class. It is the constructor which copies the char array from PROGMEM. __FlashStringHelper is intended as return type for the F() macro.

const char charArray[] PROGMEM = "Some text";

void setup() {

  Serial.begin(115200);

  String s((const __FlashStringHelper*) charArray);

  Serial.println(s);
}

void loop() {
}


Can I control a 28BYJ-48 5V stepper with a DVR8825 driver? I have a stepper motor 28BYJ-48 rated 5 V and I want to use a DVR8825 driver so I can use the 1/32 micro-stepping feature. My problem is that DVR8825 has a minimum operating voltage of 8.2 V. Would the 28BYJ-48 stand a 10 V input?

Is there any alternative to the DVR8825 that operates at 5 V and has at least 1/32 micro-stepping?

Stepper motors are rated in two different ways. Some provide a "rated voltage" in combination with a "DC resistance", others provide a "phase current" and a "phase resistance". The way they operate is identical.

Stepper motors such as your 28BYJ-48 are usually intended to be driven with a fixed voltage, their rated voltage. At this voltage, the maximum permittable current flows in the steppers windings - determined mostly by cooling and wire thickness. If you exceed that voltage, more current will flow and will damage / destroy the stepper motor.

The DRV8825 is a current controlled stepper motor driver - it always uses the full available supply voltage - 8.2V+ - but uses PWM to limit the current actually flowing in the stepper. This is possible because the stepper motor coils are inductors, which inhibit the flow of current.

To use your stepper motor with a DRV8825 driver, you'll have to calculate the steppers equivalent "maximum phase current". According to this datasheet, it's rated 5 V at 50 Ohms, giving us a current of 0.1 A. You can then set this current via the potentiometer on the driver chip. The Vref voltage should be set so that Vref = Imax / 2.
Start at a Vref of 50 mV, and see how warm the motor gets and whether it's as strong as you would expect it to be.


Gas Sensor Library for Proteus Does any one know how to use Gas Sensor module in Proteus. I wanna use Gas Sensor but I am unable to find it in Proteus. So, does anyone know any way of adding Gas Sensor Library for Proteus software. Thanks in advance.

I have found the Gas Sensor Library for Proteus, so I thought to share it here so that others can also get benefit out of it. They have also posted the complete method of How to use this Gas Sensor Library and have also given an example to download.

Thanks.


Detect radio frequency keyfob Would it be possible to detect when somebody closes/opens/uses their keyfob (based on radio frequency) ? It is of course not the intention to hack the key. Just knowing when somebody has pushed a button on it.

If so what could be the possible range and what hardware/software should be needed (what antenna?, Arduino, Raspberry pi, extra software or drivers etc...)

Thank you so much for your help.

That should be possible. Your best option is SDR (Software Defined Radio). It uses a standard PC or even a Raspberry Pi in combination with a DVB-T tv receiver as the radio.

A great starting point would be GNU Radio and its hardware section


[SOLVED]how to send command to Gsm module from Arduino via serial port Am using SIM7600X 4G HAT module (GSM) and Arduino Uno
after I start the module and Arduino, I receive data from Gsm module but I can't send any command to it.
On my Arduino board when I get data RX led flashing, and when I send command TX led flashing.
#include <SoftwareSerial.h>
SoftwareSerial myserial(3, 4); // gsm_TX, gsm_RX

void setup(){
  myserial.begin(9600); //Initialize GSM serial port
  Serial.begin(9600); //Initialize Arduino default serial port
}

void loop(){
  while(1){
    while (myserial.available()) {
      //Serial received data, output via mySerial.
      Serial.write(myserial.read());
    }
    while(Serial.available()) {
      //myserial received data, output it via Serial.
      myserial.write(Serial.read());
    }
  }
}

As the picture I send "AT" command or any command it no response.
it show only module start up command.

My circuit

I solved my problem, On my circuit GSM module use an external source and my Arduino Uno use serial port source, So it cant communicate via pin because both ground of them did not connect to each other then the answer is connected GSM module GND to Arduino Uno GND.


Why am I receiving this error: “expected unqualified-id before numeric constant”? #include <LiquidCrystal.h>
LiquidCrystal 1cd(12, 11, 5, 4, 3, 2);
const int switchPin = 6;
int switchState = 0;
int prevSwitchState = 0;
int reply;
void setup() {
 1cd.begin(16, 2);
 pinMode(switchPin, INPUT);
 1cd.print("Interroga");
 1cd.setCursor(0, 1);
 1cd.print("la sfera!");
 // put your setup code here, to run once:

}

void loop() {
  switchState = digitalRead(switchPin);
  if (switchState != prevSwitchState){
    if (switchState == LOW){
      reply = random(8);
      1cd.clear();
      1cd.setCursor(0, 0);
      1cd.print("La sfera dice");
      1cd.setCursor(0, 1);
      switch(reply){
        case 0:
        1cd.print("si");
        break;
        case 1:
        1cd.print("probabilmente");
        break;
        case 2:
        1cd.print("certo");
        break;
        case 3:
        1cd.print("bene");
        break;
        case 4:
        1cd.print("forse");
        break;
        case 5:
        1cd.print("chiedi ancora");
        break;
        case 6:
        1cd.print("improbabile");
        break;
        case 7:
        1cd.print("no");
        break;// put your main code here, to run repeatedly:
      }
    }
  }
 prevSwitchState = switchState;
}

You're using an invalid variable name (1cd starts with the number 1).

Variables can consist of both uppercase (A-Z) and lowercase(a-z)
letters.
Variables can contain numbers 0 to 9, but cannot start with a number.
Variables may not have the same names as Arduino language keywords,
e.g. you cannot have a variable named float.
If you try and save a sketch with a space in the file name, the IDE will change the space to an underscore.


How does changing arduino power supply from USB to Adapter change the circuit? I have a circuit running with capacitive Sensors, that also has an LED strip. everything works fine when using USB power from a laptop (connected to the mains) and 12v 2A adapter powering 1m LED strip.

When the power supply is split and the arduino is also powered from this supply ( using adapter port ) the capacitive sensor begins to give junk values.

What changes in a circuit that would create such a porblem? Could it be a grounding issue? How else to ground this arduino to behave as it would with a usb connection?

I have run into problems like this before, often it can actually be that the voltage is not steady due to the LEDs sourcing current from it.

You may be able to solve the problem by adding a capacitor inline with the power input (from the +12v to GND). I would probably start with a value of around 10 μF and increase it if the interference continues.

Capacitive sensors and very sensitive to voltage fluctuations, you may even want to put a second capacitor across the VCC and Gnd of the sensor.


Printing SD card file contents on LCD This is a part of my program which reads data from file stored in SD card and displays that on an LCD screen.

  File dataFile = SD.open("1165.txt");

  if (dataFile) {
    Serial.println("File Opened");
    lcd.clear();
       delay( 5 );  //LCD-specific M
       lcd.setCursor( 0,0 );

  while (dataFile.available()) {
      Serial.write(dataFile.read());
      lcd.write(dataFile.read());
      lcd.print(dataFile.read());
    }
  dataFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error");
  }

When I look at the serial monitor it prints the contents of that file but none of these commands print what is printed in the serial monitor,

lcd.write(dataFile.read());
lcd.print(dataFile.read());

Any ideas?

When you call dataFile.read(), the file pointer is advanced, so you always read different bytes in each read call. Imagine the file like a book with many lines: Each time you read, you advance the current line, so with multiple calls, you never get the same data. The solution is to currently store the last read byte:

while (dataFile.available()) {
  char readByte = dataFile.read();
  Serial.write(readByte);
  lcd.write(readByte);
  lcd.print(readByte);
}

You have two calls for displaying data in the LCD, but be careful that the second call (print) might interpret your data as a number, so just remove the lcd.print(readByte) call altogether to be sure it's printing the raw character.


Problemm with the MPU6050 library I have a curiosity. What is the difference between adding a header file directly on the arduino IDE and the header file inside another h-file.
For example:
#include "MPU6050_6Axis_MotionApps20.h"
void setup()
{
}
void loop()
{

}

This last didn't give me any problem, but when I create a h-file and add inside that h-file that library, it gave me an error:
ARDUINO:
#include "Prueba.h"
void setup()
{
}
void loop()
{

}

Prueba.h
//#ifndef Prueba_H
//#define Prueba_H
//#define LIBRARY_VERSION   1.0.0

#include "MPU6050_6Axis_MotionApps20.h"
class Prueba
{
  public:
  Prueba();
};
//#endif

Part of the error code is:
C:\Users\linco\Documents\Arduino\libraries\MPU6050-0.2.1\src\MPU6050.cpp:1679:9: note: implicit this pointer type mismatch
 uint8_t MPU6050::getIntStatus() {
         ^
C:\Users\linco\Documents\Arduino\libraries\MPU6050-0.2.1\src\MPU6050.h:438:7: note: type 'struct MPU6050' itself violates the C++ One Definition Rule
 class MPU6050 {
       ^
C:\Users\linco\Documents\Arduino\libraries\MPU6050-0.2.1\src/MPU6050.h:438:7: note: the incompatible type is defined here
 class MPU6050 {
       ^
C:\Users\linco\Documents\Arduino\libraries\MPU6050-0.2.1\src\MPU6050.cpp:1679:9: note: 'getIntStatus' was previously declared here
 uint8_t MPU6050::getIntStatus() {
         ^
C:\Users\linco\Documents\Arduino\libraries\MPU6050-0.2.1\src\MPU6050.cpp:1679:9: note: code may be misoptimized unless -fno-strict-aliasing is used
collect2.exe: error: ld returned 1 exit status
exit status 1

Can someone explain me this?
Thanks in advance.

Well I don't know exactly why this work, but base on this question this. To solve this I should add 'inline' keyword in every method definition on the MPU6050_6Axis_MotionApps20.h
Like this:
inline uint8_t MPU6050::dmpInitialize() {
    // reset device
    DEBUG_PRINTLN(F("\n\nResetting MPU6050..."));
    reset();
    delay(30); // wait after reset

    // disable sleep mode
    setSleepEnabled(false);

    // get MPU hardware revision
    setMemoryBank(0x10, true, true);
    setMemoryStartAddress(0x06);
    Serial.println(F("Checking hardware revision..."));
    Serial.print(F("Revision @ user[16][6] = "));
    Serial.println(readMemoryByte(), HEX);
    Serial.println(F("Resetting memory bank selection to 0..."));
    setMemoryBank(0, false, false);

    // check OTP bank valid
    DEBUG_PRINTLN(F("Reading OTP bank valid flag..."));
    DEBUG_PRINT(F("OTP bank is "));
    DEBUG_PRINTLN(getOTPBankValid() ? F("valid!") : F("invalid!"));

    // setup weird slave stuff (?)
    DEBUG_PRINTLN(F("Setting slave 0 address to 0x7F..."));
    setSlaveAddress(0, 0x7F);
    DEBUG_PRINTLN(F("Disabling I2C Master mode..."));
    setI2CMasterModeEnabled(false);
    DEBUG_PRINTLN(F("Setting slave 0 address to 0x68 (self)..."));
    setSlaveAddress(0, 0x68);
    DEBUG_PRINTLN(F("Resetting I2C Master control..."));
    resetI2CMaster();
    delay(20);
    DEBUG_PRINTLN(F("Setting clock source to Z Gyro..."));
    setClockSource(MPU6050_CLOCK_PLL_ZGYRO);

    DEBUG_PRINTLN(F("Setting DMP and FIFO_OFLOW interrupts enabled..."));
    setIntEnabled(1<<MPU6050_INTERRUPT_FIFO_OFLOW_BIT|1<<MPU6050_INTERRUPT_DMP_INT_BIT);

    DEBUG_PRINTLN(F("Setting sample rate to 200Hz..."));
    setRate(4); // 1khz / (1 + 4) = 200 Hz

    DEBUG_PRINTLN(F("Setting external frame sync to TEMP_OUT_L[0]..."));
    setExternalFrameSync(MPU6050_EXT_SYNC_TEMP_OUT_L);

    DEBUG_PRINTLN(F("Setting DLPF bandwidth to 42Hz..."));
    setDLPFMode(MPU6050_DLPF_BW_42);

    DEBUG_PRINTLN(F("Setting gyro sensitivity to +/- 2000 deg/sec..."));
    setFullScaleGyroRange(MPU6050_GYRO_FS_2000);

    // load DMP code into memory banks
    DEBUG_PRINT(F("Writing DMP code to MPU memory banks ("));
    DEBUG_PRINT(MPU6050_DMP_CODE_SIZE);
    DEBUG_PRINTLN(F(" bytes)"));
    if (!writeProgMemoryBlock(dmpMemory, MPU6050_DMP_CODE_SIZE)) return 1; // Failed
    DEBUG_PRINTLN(F("Success! DMP code written and verified."));

    // Set the FIFO Rate Divisor int the DMP Firmware Memory
    unsigned char dmpUpdate[] = {0x00, MPU6050_DMP_FIFO_RATE_DIVISOR};
    writeMemoryBlock(dmpUpdate, 0x02, 0x02, 0x16); // Lets write the dmpUpdate data to the Firmware image, we have 2 bytes to write in bank 0x02 with the Offset 0x16

    //write start address MSB into register
    setDMPConfig1(0x03);
    //write start address LSB into register
    setDMPConfig2(0x00);

    DEBUG_PRINTLN(F("Clearing OTP Bank flag..."));
    setOTPBankValid(false);

    DEBUG_PRINTLN(F("Setting motion detection threshold to 2..."));
    setMotionDetectionThreshold(2);

    DEBUG_PRINTLN(F("Setting zero-motion detection threshold to 156..."));
    setZeroMotionDetectionThreshold(156);

    DEBUG_PRINTLN(F("Setting motion detection duration to 80..."));
    setMotionDetectionDuration(80);

    DEBUG_PRINTLN(F("Setting zero-motion detection duration to 0..."));
    setZeroMotionDetectionDuration(0);
    DEBUG_PRINTLN(F("Enabling FIFO..."));
    setFIFOEnabled(true);

    DEBUG_PRINTLN(F("Resetting DMP..."));
    resetDMP();

    DEBUG_PRINTLN(F("DMP is good to go! Finally."));

    DEBUG_PRINTLN(F("Disabling DMP (you turn it on later)..."));
    setDMPEnabled(false);

    DEBUG_PRINTLN(F("Setting up internal 42-byte (default) DMP packet buffer..."));
    dmpPacketSize = 42;

    DEBUG_PRINTLN(F("Resetting FIFO and clearing INT status one last time..."));
    resetFIFO();
    getIntStatus();

    return 0; // success
}
inline bool MPU6050::dmpPacketAvailable() {
    return getFIFOCount() >= dmpGetFIFOPacketSize();
}
inline uint8_t MPU6050::dmpGetAccel(int32_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = (((uint32_t)packet[28] << 24) | ((uint32_t)packet[29] << 16) | ((uint32_t)packet[30] << 8) | packet[31]);
    data[1] = (((uint32_t)packet[32] << 24) | ((uint32_t)packet[33] << 16) | ((uint32_t)packet[34] << 8) | packet[35]);
    data[2] = (((uint32_t)packet[36] << 24) | ((uint32_t)packet[37] << 16) | ((uint32_t)packet[38] << 8) | packet[39]);
    return 0;
}
inline uint8_t MPU6050::dmpGetAccel(int16_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = (packet[28] << 8) | packet[29];
    data[1] = (packet[32] << 8) | packet[33];
    data[2] = (packet[36] << 8) | packet[37];
    return 0;
}
inline uint8_t MPU6050::dmpGetAccel(VectorInt16 *v, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    v -> x = (packet[28] << 8) | packet[29];
    v -> y = (packet[32] << 8) | packet[33];
    v -> z = (packet[36] << 8) | packet[37];
    return 0;
}
inline uint8_t MPU6050::dmpGetQuaternion(int32_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = (((uint32_t)packet[0] << 24) | ((uint32_t)packet[1] << 16) | ((uint32_t)packet[2] << 8) | packet[3]);
    data[1] = (((uint32_t)packet[4] << 24) | ((uint32_t)packet[5] << 16) | ((uint32_t)packet[6] << 8) | packet[7]);
    data[2] = (((uint32_t)packet[8] << 24) | ((uint32_t)packet[9] << 16) | ((uint32_t)packet[10] << 8) | packet[11]);
    data[3] = (((uint32_t)packet[12] << 24) | ((uint32_t)packet[13] << 16) | ((uint32_t)packet[14] << 8) | packet[15]);
    return 0;
}
inline uint8_t MPU6050::dmpGetQuaternion(int16_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = ((packet[0] << 8) | packet[1]);
    data[1] = ((packet[4] << 8) | packet[5]);
    data[2] = ((packet[8] << 8) | packet[9]);
    data[3] = ((packet[12] << 8) | packet[13]);
    return 0;
}
inline uint8_t MPU6050::dmpGetQuaternion(Quaternion *q, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    int16_t qI[4];
    uint8_t status = dmpGetQuaternion(qI, packet);
    if (status == 0) {
        q -> w = (float)qI[0] / 16384.0f;
        q -> x = (float)qI[1] / 16384.0f;
        q -> y = (float)qI[2] / 16384.0f;
        q -> z = (float)qI[3] / 16384.0f;
        return 0;
    }
    return status; // int16 return value, indicates error if this line is reached
}
inline uint8_t MPU6050::dmpGetGyro(int32_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = (((uint32_t)packet[16] << 24) | ((uint32_t)packet[17] << 16) | ((uint32_t)packet[18] << 8) | packet[19]);
    data[1] = (((uint32_t)packet[20] << 24) | ((uint32_t)packet[21] << 16) | ((uint32_t)packet[22] << 8) | packet[23]);
    data[2] = (((uint32_t)packet[24] << 24) | ((uint32_t)packet[25] << 16) | ((uint32_t)packet[26] << 8) | packet[27]);
    return 0;
}
inline uint8_t MPU6050::dmpGetGyro(int16_t *data, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    data[0] = (packet[16] << 8) | packet[17];
    data[1] = (packet[20] << 8) | packet[21];
    data[2] = (packet[24] << 8) | packet[25];
    return 0;
}
inline uint8_t MPU6050::dmpGetGyro(VectorInt16 *v, const uint8_t* packet) {
    // TODO: accommodate different arrangements of sent data (ONLY default supported now)
    if (packet == 0) packet = dmpPacketBuffer;
    v -> x = (packet[16] << 8) | packet[17];
    v -> y = (packet[20] << 8) | packet[21];
    v -> z = (packet[24] << 8) | packet[25];
    return 0;
}
inline uint8_t MPU6050::dmpGetLinearAccel(VectorInt16 *v, VectorInt16 *vRaw, VectorFloat *gravity) {
    // get rid of the gravity component (+1g = +8192 in standard DMP FIFO packet, sensitivity is 2g)
    v -> x = vRaw -> x - gravity -> x*8192;
    v -> y = vRaw -> y - gravity -> y*8192;
    v -> z = vRaw -> z - gravity -> z*8192;
    return 0;
}
inline uint8_t MPU6050::dmpGetLinearAccelInWorld(VectorInt16 *v, VectorInt16 *vReal, Quaternion *q) {
    // rotate measured 3D acceleration vector into original state
    // frame of reference based on orientation quaternion
    memcpy(v, vReal, sizeof(VectorInt16));
    v -> rotate(q);
    return 0;
}
inline uint8_t MPU6050::dmpGetGravity(int16_t *data, const uint8_t* packet) {
    /* +1g corresponds to +8192, sensitivity is 2g. */
    int16_t qI[4];
    uint8_t status = dmpGetQuaternion(qI, packet);
    data[0] = ((int32_t)qI[1] * qI[3] - (int32_t)qI[0] * qI[2]) / 16384;
    data[1] = ((int32_t)qI[0] * qI[1] + (int32_t)qI[2] * qI[3]) / 16384;
    data[2] = ((int32_t)qI[0] * qI[0] - (int32_t)qI[1] * qI[1]
           - (int32_t)qI[2] * qI[2] + (int32_t)qI[3] * qI[3]) / (2 * 16384);
    return status;
}
inline uint8_t MPU6050::dmpGetGravity(VectorFloat *v, Quaternion *q) {
    v -> x = 2 * (q -> x*q -> z - q -> w*q -> y);
    v -> y = 2 * (q -> w*q -> x + q -> y*q -> z);
    v -> z = q -> w*q -> w - q -> x*q -> x - q -> y*q -> y + q -> z*q -> z;
    return 0;
}
inline uint8_t MPU6050::dmpGetEuler(float *data, Quaternion *q) {
    data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);   // psi
    data[1] = -asin(2*q -> x*q -> z + 2*q -> w*q -> y);                              // theta
    data[2] = atan2(2*q -> y*q -> z - 2*q -> w*q -> x, 2*q -> w*q -> w + 2*q -> z*q -> z - 1);   // phi
    return 0;
}

#ifdef USE_OLD_DMPGETYAWPITCHROLL
inline uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) {
    // yaw: (about Z axis)
    data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
    // pitch: (nose up/down, about Y axis)
    data[1] = atan(gravity -> x / sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z));
    // roll: (tilt left/right, about X axis)
    data[2] = atan(gravity -> y / sqrt(gravity -> x*gravity -> x + gravity -> z*gravity -> z));
    return 0;
}
#else
inline uint8_t MPU6050::dmpGetYawPitchRoll(float *data, Quaternion *q, VectorFloat *gravity) {
    // yaw: (about Z axis)
    data[0] = atan2(2*q -> x*q -> y - 2*q -> w*q -> z, 2*q -> w*q -> w + 2*q -> x*q -> x - 1);
    // pitch: (nose up/down, about Y axis)
    data[1] = atan2(gravity -> x , sqrt(gravity -> y*gravity -> y + gravity -> z*gravity -> z));
    // roll: (tilt left/right, about X axis)
    data[2] = atan2(gravity -> y , gravity -> z);
    if (gravity -> z < 0) {
        if(data[1] > 0) {
            data[1] = PI - data[1];
        } else {
            data[1] = -PI - data[1];
        }
    }
    return 0;
}
#endif

inline uint8_t MPU6050::dmpProcessFIFOPacket(const unsigned char *dmpData) {
    return 0;
}

inline uint8_t MPU6050::dmpReadAndProcessFIFOPacket(uint8_t numPackets, uint8_t *processed) {
    uint8_t status;
    uint8_t buf[dmpPacketSize];
    for (uint8_t i = 0; i < numPackets; i++) {
        // read packet from FIFO
        getFIFOBytes(buf, dmpPacketSize);

        // process packet
        if ((status = dmpProcessFIFOPacket(buf)) > 0) return status;

        // increment external process count variable, if supplied
        if (processed != 0) (*processed)++;
    }
    return 0;
}

inline uint16_t MPU6050::dmpGetFIFOPacketSize() {
    return dmpPacketSize;
}
#endif

I don't know why the guys that made this library didn't add this. Maybe I'm missing something.


Is there a way to replace an Arduino core function without modifying the Arduino code? (Let's just skip the suggestions that it's the wrong idea and interrupts for a while...).

Is there a way to replace the digitalWrite() method (for example) so I can add something more to happen in there? But the following rules must be obeyed:

A call to digitalWrite(pin, value) must invoke the new method.
A call to digitalWrite(pin, value) from a different library included in my code (SD.h for example) must invoke the new method.
None of the Arduino files can be modified (I don't want to do it on every Arduino version upgrade).
Everything must be done in a header file that I can include to use the new function.

I have tried this and it works, but only in my code, not in external libraries that I include after this header:

#include <Arduino.h>

class PinsHook {
  public:
    static void digitalWriteHook(uint8_t pin, uint8_t value) {
      digitalWrite(pin, value);
      if (pin == 8) {
        Serial.print("Pin ");
        Serial.print(pin);
        Serial.print(" changed to ");
        Serial.println(value);
      }
    }
};

#define digitalWrite(pin, value) PinsHook::digitalWriteHook(pin, value)

Not sure about the Arduino IDE (I don't have it installed right now) but using UECIDE it's as simple as defining a new digitalWrite function in your code.  When the whole shebang gets linked together the function in your code overrides the function in the libraries.

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

void loop() {
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(800);
}

void digitalWrite(int pin, int level) {
    // Not gonna do anything!
}

Comment out the digitalWrite function and the LED blinks.  Uncomment it and it doesn't blink any more.


Error: function was not declared in this scope when using a library without classes I have created a library of functions that doesn't have and mustn't have a class. In order to have functions inside the library that can only be called from the library itself, you just write them into the .cpp file and leave them out of the header file completely. Here is the .cpp file of the library (the header file is empty):

#include "Lib.h"

// Definition of foo1
static void foo1(){
    foo2();
}

// Definition of foo2
static void foo2() {}

When including the library in an empty sketch and compiling it I get the following error message:

  error: 'foo2' was not declared in this scope

What is the problem here?

When creating a library with functions that are not mentioned in the header file, the order of appearence in the .cpp file suddenly becomes relevant. In order for a function to be used by another function, it has to be declared first.

The first possibility in this example would be to define foo2 before defining foo1 like this:

#include "Lib.h"

// Definition of foo2
static void foo2() {}

// Definition of foo1
static void foo1(){
    foo2();
}

However, this is not only bad practice, it also doesn't always work. If there is any sort of recursive procedure that makes functions call each other, you can't define both of them before the respective other at the same time.

The more elegant and foolproof way to do this is by declaring each function first like you usually would in the header file and then defining what they actually do. The .cpp file of this library would then look like this:

#include "Lib.h"

static void foo1(); // Declaration of foo1
static void foo2(); // Declaration of foo2

// Definition of foo1
void foo1(){
    foo2();
}

// Definition of foo2
void foo2() {}


Random characters generated by LCD during serial.read() I am using the following codes to print characters on LCD display....

#include <LiquidCrystal.h>

const int rs = 8, en = 9, d0 = 4, d1 = 5, d2 = 6, d3 = 7;
LiquidCrystal lcd(rs, en, d0, d1, d2, d3);

void setup() {
  lcd.begin(16, 2);
  Serial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    delay(100);
    lcd.clear();
    while (Serial.available() > 0) {
      lcd.write(Serial.read());
    }
  }
}

but in the end it is generating an unwanted character also..

kindly help me with the problem

The character to the right of the 'A' on your LCD display does not correspond to any of the built-in character bitmap definitions (either on a EU or Chinese display).  This random pattern is likely one of the 8 programmable character bitmaps supported by the LCD that has not been defined yet (ASCII codes 0 to 7).

So, you're likely sending the LCD a character with a value between 0 and 7.  It's probably a good idea to filter out invalid characters before attempting to display them on your LCD.

Filtering Example:

char c = Serial.read();
if ((c >= 32) && (c <= 128))
  lcd.write(c);


is any windows application available for accelerometer based computer mouse I want to make an AIR mouse using Arduino
and accelerometer, for this i used USB to TTL
converter i have done everything successfully
but can anyone tell me how use it in computer.
I mean i don't know how to make computer
application for this mouse. please suggest me
any application for this. And give any idea for
"how can i use Bluetooth for this."


Getting BPM from the given code I have found code that can blink an LED on Arduino according to Heart Beat. I am using AD8232 as a sensor for Heart Rate.

Code for it is:

//  Variables
int PulseSensorPurplePin = 0; // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 0
int LED13 = 13; // The on-board Arduino LED
int Signal; // holds the incoming raw data. Signal value can range from 0-1024
int Threshold = 550; // Determine which Signal to "count as a beat", and which to ingore.

void setup() {
  pinMode(LED13, OUTPUT); // pin that will blink to your heartbeat
  Serial.begin(9600); // Sets up Serial Communication at certain speed.
}

void loop() {
  Signal = analogRead(PulseSensorPurplePin); // Read the PulseSensor's value.
  // Assign this value to the "Signal" variable.
  Serial.println(Signal); // Send the Signal value to Serial Plotter.
  if(Signal > Threshold) {
    // If the signal is above "550", then "turn-on" Arduino's on-Board LED.
    digitalWrite(LED13, HIGH);
  } else {
    digitalWrite(LED13, LOW); //  Else, the signal must be below "550", so "turn-off" this LED.
  }
  delay(10);
}

My question is: How can I get BPM?

Edited below:

Is this code for BPM correct?

int x = 0;
int LastTime = 0;
bool BPMTiming = false;
bool BeatComplete = false;
int BPM = 0;
#define UpperThreshold 518
#define LowerThreshold 490
int LED13 = 44; // The on-board Arduino LED
int Signal; // holds the incoming raw data. Signal value can range from 0-1024

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

void loop() {
  int value = analogRead(0);
  if (value > UpperThreshold) {
    if (BeatComplete) {
      BPM = millis() - LastTime;
      BPM = int(60 / (float(BPM) / 1000));
      BPMTiming = false;
      BeatComplete = false;
    }
    if (BPMTiming == false) {
      LastTime = millis();
      BPMTiming = true;
    }
  }
  if ((value < LowerThreshold) & (BPMTiming))
    BeatComplete = true;
    // display bpm
  Serial.print(BPM);
  Serial.println(" BPM");
  x++;
  Signal = analogRead(0); // Read the PulseSensor's value.
  // Assign this value to the "Signal" variable.
  if (Signal > UpperThreshold) {
    // If the signal is above "550", then "turn-on" Arduino's on-Board LED.
    digitalWrite(LED13, HIGH);
  } else {
    digitalWrite(LED13, LOW); //  Else, the signal must be below "550", so "turn-off" this LED.
  }
}

If you know the interval between heart beats, you can calculate the frequency using the formula: frequency = 1 / time. Now if you take the frequency and multiply it by 60, you should get BPM.

I don't have one of the sensors you are using so I connected a potentiometer to pin A0 to test this code.

    int UpperThreshold = 518;
    int LowerThreshold = 490;
    int reading = 0;
    float BPM = 0.0;
    bool IgnoreReading = false;
    bool FirstPulseDetected = false;
    unsigned long FirstPulseTime = 0;
    unsigned long SecondPulseTime = 0;
    unsigned long PulseInterval = 0;

    void setup(){
      Serial.begin(9600);
    }

    void loop(){

      reading = analogRead(0);

      // Heart beat leading edge detected.
      if(reading > UpperThreshold && IgnoreReading == false){
        if(FirstPulseDetected == false){
          FirstPulseTime = millis();
          FirstPulseDetected = true;
        }
        else{
          SecondPulseTime = millis();
          PulseInterval = SecondPulseTime - FirstPulseTime;
          FirstPulseTime = SecondPulseTime;
        }
        IgnoreReading = true;
      }

      // Heart beat trailing edge detected.
      if(reading < LowerThreshold){
        IgnoreReading = false;
      }

      BPM = (1.0/PulseInterval) * 60.0 * 1000;

      Serial.print(reading);
      Serial.print("\t");
      Serial.print(PulseInterval);
      Serial.print("\t");
      Serial.print(BPM);
      Serial.println(" BPM");
      Serial.flush();

      // Please don't use delay() - this is just for testing purposes.
      delay(50);
    }

Updated answer in response to your comments below:

The sketch is reading the data and sending the data to the serial monitor every 50ms because of the delay(50). What if we changed that to 1000 ms? The serial monitor would update once per second which would be more "human readable". The problem with that idea is for heart rates faster than 60 BPM, the reading would be inaccurate. I don't have a sensor to test with but I'm guessing a 1 second delay would make the code inoperable.

Before we add more complexity to this sketch we really should get rid of that delay. It would be nice to have one "timer" that we could use to update the BPM calculation and a second "timer" to update the serial monitor every second, or half second, or what ever you want it to be.

We can do that without any libraries using millis(). Here is an updated sketch using millis() for timers. This sketch has the blinking of the on board LED added to it. I'm using an Uno so you'll have to change LED_BUILTIN to what ever pin number you are using.

int UpperThreshold = 518;
int LowerThreshold = 490;
int reading = 0;
float BPM = 0.0;
bool IgnoreReading = false;
bool FirstPulseDetected = false;
unsigned long FirstPulseTime = 0;
unsigned long SecondPulseTime = 0;
unsigned long PulseInterval = 0;
const unsigned long delayTime = 10;
const unsigned long delayTime2 = 1000;
const unsigned long baudRate = 9600;
unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;

void setup(){
  Serial.begin(baudRate);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop(){

  // Get current time
  unsigned long currentMillis = millis();

  // First event
  if(myTimer1(delayTime, currentMillis) == 1){

    reading = analogRead(0);

    // Heart beat leading edge detected.
    if(reading > UpperThreshold && IgnoreReading == false){
      if(FirstPulseDetected == false){
        FirstPulseTime = millis();
        FirstPulseDetected = true;
      }
      else{
        SecondPulseTime = millis();
        PulseInterval = SecondPulseTime - FirstPulseTime;
        FirstPulseTime = SecondPulseTime;
      }
      IgnoreReading = true;
      digitalWrite(LED_BUILTIN, HIGH);
    }

    // Heart beat trailing edge detected.
    if(reading < LowerThreshold && IgnoreReading == true){
      IgnoreReading = false;
      digitalWrite(LED_BUILTIN, LOW);
    }

    // Calculate Beats Per Minute.
    BPM = (1.0/PulseInterval) * 60.0 * 1000;
  }

  // Second event
  if(myTimer2(delayTime2, currentMillis) == 1){
    Serial.print(reading);
    Serial.print("\t");
    Serial.print(PulseInterval);
    Serial.print("\t");
    Serial.print(BPM);
    Serial.println(" BPM");
    Serial.flush();
  }
}

// First event timer
int myTimer1(long delayTime, long currentMillis){
  if(currentMillis - previousMillis >= delayTime){previousMillis = currentMillis;return 1;}
  else{return 0;}
}

// Second event timer
int myTimer2(long delayTime2, long currentMillis){
  if(currentMillis - previousMillis2 >= delayTime2){previousMillis2 = currentMillis;return 1;}
  else{return 0;}
}

The code compile size with delay is 4,732 vs the millis timers at 4,682 (with the LED code removed). Two timers for less than the price of one delay :)

The LED will remain on for the duration of the heart beat reading above the LowerThreshold. If you want to have it on longer or decide how long it should be on for, I won't write the code for you but I will give you a hint. You can copy myTimer1() again and make a third timer.


At what frequency/rate does the digitalRead function read an input? Consider the following code:

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  }
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

The line buttonState = digitalRead(buttonPin); checks the input voltage.

But how is that checked internally?

I mean at what rate the input is checked?

When I get time, I will provide more definitive answers.

I did follow through with this, and the result is here, towards the end of the page: https://dannyelectronics.wordpress.com/2016/05/01/the-price-of-avr-arduino/

the short answer is: digitalRead() takes 4.9us to execute on a 16MIPS Arduino Uno, or 79 ticks (=instructions).

the fastest you can read digitalRead() is then 200KHz (= 1/4.9us).

Hope it helps.