Why are some of my GSM modules not taking commands? I posted a couple weeks ago about having a GSM error. I moved past it and the code seemed to be working on my GSM module (I think a SIMCOM). But then I needed to create some more systems and out of a total of 8 GSM modules, my code and setup only work on two of them - despite the fact that they should be identical and from the same supplier.

The following code (thanks to this genius post) works without error to send and receive SMS on two of the boards:

#include <SoftwareSerial.h>
char inchar; // Will hold the incoming character from the GSM shield
SoftwareSerial SIM900 = SoftwareSerial(2,3);

void setup() {
  Serial.begin(19200);
  initializeGSM();
}

void initializeGSM() {
  SIM900.begin(19200);
  Serial.println("Turned on");
  SIM900.print("ATEO\r");
  Response();
  SIM900.print("AT\r");
  delay(1000);
  Response();
  SIM900.println("AT+CMGF=1\r");  // set SMS mode to text
  Response();
  delay(1000);
  SIM900.println("AT+CNMI=1,2,0,0,0\r");
  delay(100);
  Response();
  delay(5000);  // give time to log on to network.
  Serial.println("Ready...");
}

void Response() {
  int count = 0;
  delay(1000);
  Serial.println(SIM900.available());
  while(1) {
    if(SIM900.available()) {
      char data =SIM900.read();
      if(data == 'K'){Serial.println("OK");break;}
      if(data == 'R'){Serial.println("GSM Not Working");break;}
    }
    count++;
    if(count == 100){Serial.println("GSM not Found");break;}
  }
}

void loop() {
  RecSMS();
  delay(2000);
}

void RecSMS(){...}

So again, the above code works to set up the module on 2 modules. On the other 6, it simply hangs during the Response() call. SIM900.available() returns 0 and then says "GSM Not Found." So I tried to initialize the TX pin during setup as:

digitalWrite(2, LOW);

Which then gives me a promising SIM900.available() value of about 63, which corresponds to what a confirmation would be. However, when I print the "data" variable containing the byte read off the GSM module/SIM card, I get a couple bits of garbage like the following output:

Has anyone experienced this problem and knows a way to properly initialize the GSM module?

I am owner of this blog whose link you shared, so first of all, I am felling happy that you got something out of it. Now secondly, this code you got from my post is incomplete.

You need to buy that one in order to get the complete code. The code I designed is using AT commands but the above code which you have mixed with your own code is using the Arduino library that's why it's not giving the correct results.

So, either use the complete code from my website or use the Arduino library code only because it has the commands for checking the response, you don't need to use my code to get the response.


I2C communication problem with two slaves (atlas scientific) and one Nano (official) I'm working on a project using an arduino Nano (official) and two peripherals from Atlas Scientific (pH and DO) communicating via i2c. Everthing works fine when i use a usb alimentation connected to the PC or to a 5V adaptater (typically a phone charger).

I want to use a 12V battery and a 12V DC 1.5A adaptater to power up my system, the problem is that it works fine for a moment (30 to 40 seconds) and then the pH start having problem with the communication and the led becomes red and the TX/RX leds from the arduino (which are connected to nothing start going crazy. I use 4.7k pull up resistors and an L7805ACV voltage regulator to go from 12 to 5V.

Attach, a part of the system schematics.

If you have any clue, starting to be new idealess

EDIT : Here is the part of the program concerning the i2c communication :

#include "Wire.h"

/*********************************************************************************************************
 *                                               Address
 *********************************************************************************************************
 */
int pH_address = 99;
int DO_address = 97;

/*********************************************************************************************************
 *                                         i2C CONFIGURATION
 *********************************************************************************************************
 */

byte received_from_computer = 0;
char sensor_data[20];
byte in_char_sensor = 0;
byte j = 0;
byte code = 0;
int time_ = 850;

void setup()
{
  Wire.begin();
}
void loop()
{
  pH = Get_i2C(pH_address);
  delay(200);
  DO = Get_i2C(DO_address);
  delay(200);
}

/**********************************************************************************************************
 *                                                  i2C
 * ********************************************************************************************************
 */

float Get_i2C(int address)
{
  char computerdata = 'R';
  Wire.beginTransmission(address);
  Wire.write(computerdata);
  Wire.endTransmission();

  delay(time_);

  Wire.requestFrom(address, 16, 1);
  code = Wire.read();
  while (Wire.available())
  {
    in_char_sensor = Wire.read();
    sensor_data[j] = in_char_sensor;
    j += 1;
    if (in_char_sensor == 0)
    {
      j = 0;
      break;
    }
  }
  return atof(sensor_data);
}

Two ideas.

1: Count your grounds. If you count more than 1 you have a problem. Your system should have a single ground, so ANY connection on every component labeled GND should be connected to ground.

The reason multiple grounds are a problem is that your signals (other than differential signals) are measured relative to ground, so if two components have different ideas of what "ground" is they start to disagree about what constitutes a 1 and a 0.

2: Scope your power supply. Check that your 5V supply is still providing 5V. It's possible (although unlikely) that the L7805ACV can't supply enough current and your system is browning out. If possible have a look with an oscilloscope to check for noise on the 5V supply.

Your boards should already have decoupling capacators, but adding another won't hurt, so also try adding a 0.1uf cap between 5V and GND to eliminate any noise.


Is it possible to split project into several folders? It is possible to split the project into server files. However, it looks like they all must be in the same folder with the.ino file.

Is it possible to split project into several folders? I’ve got several git repositories which I want to use in the same project and I can’t use them as libraries. Each repository must have its own folder…

I will try to give an answer as it is not easy to understand what you mean.

Probably it is also better if you know how the Arduino IDE works, before try to make complex projects.

Short answer:
Yes, it is possible

Normally, you have an ino-file, some other files and many libraries. If you want create something for your project, you can just create a folder inside the library folder.

But this is not what you want right?

You can create many folders inside your project and include any header inside your folders just with
#include "subfolder/yourfile.h"

The files will not be opened with your Arduino IDE.

You can also create your "mini library", so the compiler will compile it with your project. This library need to be in a subfolder called src. At this point it will be converted and compiled for your project.

Simple working example:
testsub.ino

#include "src/test.h"
Test *test = new Test();
void setup(){
  Serial.print(test->number());
}
void loop(){
}

Create a subfolder src and place your files:
test.h

class Test
{
public:
  Test();
  int number();
};

and
test.cpp

#include "test.h"
Test::Test() {
}
int Test::number() {
  return 95;
}

If you want another "library", you can create another subfolder called src.


Is there an advantage to set pinmodes via bitmask and register? I'm working with the capacitive sensor library currently and the author does not use digitalWrite(), but instead sets the output of a pin via functions changing the bitmasks of certain registers:

https://github.com/PaulStoffregen/CapacitiveSensor/blob/master/CapacitiveSensor.h#L39

I looked into the OneWire library description those functions come from, but I still can't see any advantage over simply using the standard way Arduino proposes.

Is there an advantage to set pinmodes via bitmask and register?

I can name a few:

1) speed - I benchmarked the arduino pin ops vs. direct register ops here;

2) size - the code size is considerably bigger with the arduino library;

3) portability - the bitmark approach is supported by any C-compiler;

4) convention - i'm used to the bitmask approach and wrote all of my libraries around it;
...

as i'm sure others have their reasons to use the bitmasks.


Example with dynamic array works with uint8_t, why not with uint16_t? I tried the following example that uses uint8_t.

Is using malloc() and free() a really bad idea on Arduino?

When I replaced it with uint16_t it stops running after five loops. Any ideas?

Leo

I suspect you changed everything to uint16_t but did not change the malloc call to account for the 2-byte size. Original:

_tester = (uint16_t *)malloc(len);

Try changing it to

_tester = (uint16_t *)malloc(len * sizeof(uint16_t));

This will multiply len by 2 to ensure it allocates enough space for all of the data.

(Beware that if you also changed len to be uint16_t then some of those random numbers from 1..1000 will be large enough to deplete all of the memory on an Uno. But at least it doesn't seem to crash.)


How long does it takes for arduino to reach main()? I am trying to emulate the behavior of a circuit using an Attiny85

This is the result I got so far:

In the picture above, D2 is VCC, D4, D5 and D6 are outputs of the circuit I am trying to emulate. D7 is the output of Attiny85

The code I am using is:

#define F_CPU 8000000L
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int main() {

  DDRB = 0b00001000;

  PORTB = 0b00001000;
  _delay_ms(5);

  PORTB = 0b00000000;
  _delay_ms(5);
  PORTB = 0b00001000;
  _delay_ms(5);

  PORTB = 0b00000000;
  _delay_ms(5);

  _delay_ms(5);

  while(1)
  {
     PORTB = 0b00001000;
    _delay_ms(1);
     PORTB = 0b00000000;
    _delay_ms(1);
  }
    return 0;
}

According to this, it takes roughly 64ms from powerup until it actually run the main program.

Is there any reason for such a delay? How can I reduce it somehow (ideally to 20ms or less)?

The ATtiny85 has a built-in delay counter that keeps the MCU in reset
mode for some time after the power is applied. This seems to be intended
as a wait for the clock and power to be stabilized. The length of this
delay depends on your selected clock source, and is somewhat
configurable with the fuses.

According to your code, your MCU is clocked at 8 MHz. I assume you
are then using the internal RC oscillator as a clock source. If this is
the case, you have three choices for the startup delay:

20 CPU cycles
20 CPU cycles + 4 ms
20 CPU cycles + 64 ms

The latter is recommended if your power rises slowly, and is the default
configuration in which these MCUs are shipped. If you power level rises
fast, you may want to select a shorter delay by programming the SUT
fuses. See the datasheet for details (section System Clock and Clock
Options → Clock Sources → Calibrated Internal Oscillator).


Button to optocoupler to fire camera 4 times Ok, this is my first project where I've not had @forsvunnet close by to help.

I've got a camera connected to an optocoupler, that just fires HIGH then LOW.

I can't get a button working with it, so when I push a button, it fires opto 3 times.

This is my sketch.

 // Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int opto = 12;
int buttonInput = 2;     // the number of the pushbutton pin
int buttonState = 0;         // variable for reading the pushbutton status

// the setup routine runs once when you press reset:
void setup()
{
// initialize the digital pin as an output.m
pinMode(opto, OUTPUT);
pinMode(buttonInput, INPUT);
digitalWrite(buttonInput, LOW);}

// the loop routine runs over and over again forever:
void loop()
{
  buttonState = digitalRead(buttonInput);
  if (buttonState == HIGH) {
      digitalWrite(opto, HIGH);
      delay(1000);               // wait for a second
      digitalWrite(opto, LOW);
      delay(1000);               // wait for a second
      digitalWrite(opto, HIGH);
      delay(1000);               // wait for a second
      digitalWrite(opto, LOW);
  } else {

  }

}

Anyone point me in the right direction? It's driving me mad.

First of all, the loop (if it worked well) would only fire twice. It should only fire when you turn it on/off in a cycle (unless it's a rising/falling edge circuit (i.e. a pull down button/a falling edge interrupt), but I won't get into that). In your code you toggle it twice. The third one? I suspect that your camera only fires when it's given a low signal. This means that, when you set it to low in setup(), it takes a photo. To fix this, switch all the HIGHs and the LOWs for the opto pin.

This is the code which I think should work for you:

// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
int opto = 12;
int buttonInput = 2;     // the number of the pushbutton pin
int buttonState = 0;         // variable for reading the pushbutton status

// the setup routine runs once when you press reset:
void setup()
{
// initialize the digital pin as an output.m
pinMode(opto, OUTPUT);
pinMode(buttonInput, INPUT);
digitalWrite(buttonInput, HIGH);}

// the loop routine runs over and over again forever:
void loop()
{
  buttonState = digitalRead(buttonInput);
  if (buttonState == HIGH) {
      digitalWrite(opto, LOW);
      delay(1000);               // wait for a second
      digitalWrite(opto, HIGH);
      delay(1000);               // wait for a second
      digitalWrite(opto, LOW);
      delay(1000);               // wait for a second
      digitalWrite(opto, HIGH);
      delay(1000);               // wait for a second
      digitalWrite(opto, LOW);
      delay(1000);               // wait for a second
      digitalWrite(opto, HIGH);
      delay(1000);               // wait for a second
      digitalWrite(opto, LOW);
      delay(1000);               // wait for a second
      digitalWrite(opto, HIGH);
  } else {

  }

}

Without much info about your camera, I'd imagine that the HIGH/LOW discrepancy is the issue. Another note: this code doesn't protect against bouncing. It's fine if as it is because the delays will cause the bounces to not be picked up. If you do a "blink without delay" type of sketch using millis() and a loop, you might need to fix this. Like I said, it'll work fine now, but it's kind a crude fix since it could cause problems later if mixed with other code.


Event driven programming I have ran across a couple of different event libraries that are available on the AVR and Andruino but I am not sure which one is the best option. What I would like to do is design my program in a event driven style but not sure how to go about this.

I have a project that I need to keep lightweight but also in this program I have several actions that can be happening at any given time i.e. Digital Inputs being triggered and I need to run code whenever these events happen.

I found the QP Framework that looked promising but I wanted to get some feedback from some others that might of used this type of library before and might be able to provide some examples and maybe some experiences.

Another site I found here and lists all sorts of different libs

You may want to take a look at LMX by David Anderson A Light-Weight Multi-Tasking Executive.

He has a very good set of videos on the code that he did for Dallas Personal Robotics Group (DPRG).

The specific videos for LMX are:

David Anderson on Robotics Software - part 1
David Anderson on Robotics Software - part 2


ESP32 Bluetooth SPP Max Speed I am trying to understand the maximum BT SPP transmission speed that can be achieved using ESP32.

What my project requires is to send 2bytes of data every 200us (5kHz) AND additional 15bytes of data every 50ms(20Hz) via BT.

I am trying to achieve that using BT SPP, however, I could not understand the speed of BluetoothSerial::write AND BluetoothSerial::print.

Based on my testing for 5kHz, the BluetoothSerial::write freezes after 2-3 seconds of connection.

BluetoothSerial::println function doesn't seem to freeze, however, the time taken for the function to complete doesn't seem to be constant. Please refer to the code below on how I measure the time taken for the function to complete.

The picture below shows the time in microseconds each time the function (dataFormat()) takes place. If you look through, there are 2 instances where the time duration is more than an average 0f 80us.

I would like to know, ESP32 BT SPP can achieve such a speed or there is another way I could achieve this.

Thank you for your time and assistance in this matter.
I have asked the same question in ESP32 Forum as well here.

void dataFormat(record r){
  serialBtPrint_dur = micros();
  char msg[20];
  sprintf(msg,"%04d%05d%05d%05",r.e, r.r, r.p, r.y);
  SerialBT.println(msg);
  serialBtPrint_dur = micros() - serialBtPrint_dur;
  }
}

void loop() {
  char msg[20];
  uint8_t testMsg[20] = "abcdefghijklmnop\n";
  if(!structs.isEmpty()){
    dataset[local_rd_ptr].yawData);
    data::dataFormat(structs.shift());
    Serial.println(serialBtPrint_dur);
  }
}

This seems more like an overflow issue with something than an actual delay.  If you look at the time in the log, it seems you aren't skipping seconds in the log (aka, 19:12:32.234 in two sequential log entries when you claim a delay).  I think it's an error of working with larger than 8-bit data sizes.  I know this is an old question, but I was looking for info and came upon it and figured I'd ask.


Master Reader/Slave Sender with Distance Sensor I am currently working on a project and want to transmit the information from a distance sensor from one arduino the another, but what i receive in the master board are not the correct measurements.

Slave Code

#include <Wire.h>

const int trig = 12;
const int echo = 13;

int state = 0;
int count = 0;
int contor = 0;
int set_distance = 5;
long duration, Distanceincm;

void setup()
{
  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);
  Serial.begin(9600);           // start serial for output
}

void loop()
{
 digitalWrite(trig, HIGH);
  delay(15);
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  Distanceincm = (duration / 58);
  if (state == 0 && (Distanceincm < set_distance) ) {
    state = 1;
    count++;
    contor++;
    Serial.print("Distance=");
    Serial.println(Distanceincm);
    Serial.print("Count=");
    Serial.println(count);
    Serial.print("ConuntDay=");
    Serial.println(contor);
  }
  if (Distanceincm > set_distance) {
    state = 0;
  }
  delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {

  Wire.write(Distanceincm);
  Wire.write(count);
  Wire.write(contor);
}

Master Code

#include <Wire.h>

void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);  // start Serial for output
}

void loop()
{
  Wire.requestFrom(2, 6);    // request 6 bytes from slave device #2
  while(Wire.available())    // slave may send less than requested
  {
    long a = Wire.read();
    Serial.print ("Distance = ");
    Serial.println(a);

    int b = Wire.read();
    Serial.print ("Count = ");
    Serial.println(b);

    int c = Wire.read();
    Serial.print ("CountDay = ");
    Serial.println(c);
  }

  delay(500);
}

What i get on the serial monitor is this :

Your code has some flaws, that I will address here:

The main problem, that you see here, is that you only let the slave write data into the buffer, when it is receiving data. But you never send data to it. So there is never anything in the buffer.

In the slave code you have

void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {

  Wire.write(Distanceincm);
  Wire.write(count);
  Wire.write(contor);
}

Besides the unbalanced parentheses (which let's me think, that this might not be the actual code, that you are running currently), you are writing to the buffer only inside the receiveEvent(). That only get's called, when the master does a Master-Write transmission (via Wire.beginTransmission() and Wire.endTransmission()). In the master code you are only using Wire.requestFrom(). If you want to send back data on a request, you need to use the onRequest callback of the Wire library. You need to set the appropriate callback function:

Wire.onRequest(onRequestEvent);

And then write data inside that callback function:

void onRequestEvent(){
    Wire.write(...)
}

I will explain how to write the values correctly in a different point below.
In the receiveEvent() function you want to loop through all received bytes but the last. But you are not doing anything with the data. You aren't even reading it. As your code currently stands, this line does not make any sense.
In your master code you are requesting data from the slave with the address 2. Your slave code initiates the Wire library with the address 4. From that point there should never be a successful I2C transmission, unless you have another slave on the bus with the address 2 (another point, where I suspect, that these codes are not exactly the ones used for the test).
In the master code you are using

while(Wire.available())

because the slave might have send less data, than requested. You are testing, that the number of available bytes is not zero. But then you are reading 3 bytes without checking again, which means, when you received 2 byte, you still would try to read 3 bytes, which cannot give good results.

The condition should be Wire.available() >= 3, to check, if at least 3 bytes are in the buffer, because you are reading 3 bytes from it. But also the loop does not make much sense to me. As you have a binary protocol here, how would you treat additional data (meaning excess data, send after the first valid data frame)? You want to receive 3 values per transmission and you are reading 3 values in one iteration of the loop. If there where more data in the buffer, you would be reading the next 3 bytes, throwing away the first 3 bytes. I don't think, that is what you want.

Instead use the return value of Wire.requestFrom(), which is the number of received bytes. Use it to distinguish valid transmissions, from those, which are too short:

uint8_t n = Wire.requestFrom(4, 3);
if(n >= 3){ // at least 3 bytes where received
    uint8_t value1 = Wire.read();
    uint8_t value2 = Wire.read();
    uint8_t value3 = Wire.read();
}

Any transmission, that is too small, will get ignored. Excess data in too long messages will also be ignored. Note, that I used uint8_t, which is an unsigned integer with 8 bits (1 byte) here for simplicity of that points logic. More about your data types and their implications on your code below.
For the to send datatypes on the slave you have int and long. int is a signed integer with 16 bits, long is a signed long integer with 32 bits. (I suspect you don't need a long for the distance, as ultrasonic sensors mostly reach only 3m, but that is up to you). In contrast the argument of Wire.write() is an uint8_t, which has only 8 bits. That call is used to put exactly 1 byte into the buffer, not more. When you are using

Wire.write(Distanceincm);

you are putting the least significant byte of Distanceincm into the buffer. The rest will just be thrown away (this happens at the cast from long to uint8_t). This works as long, as the value is between 0 and 127 (which is the upper part of the int8_t value range). With higher (or lower) values your received data will be garbage. Instead you need to write every byte of your data into the buffer:

Wire.write(Distanceincm  & 0x000000FF);
Wire.write((Distanceincm & 0x0000FF00) >> 8);
Wire.write((Distanceincm & 0x00FF0000) >> 16);
Wire.write((Distanceincm & 0xFF000000) >> 24);

With bitwise ANDing (&) of the hexadecimal value 0x000000FF, we are deleting all bits, beside the least significant byte (analog with 0x0000FF00 for the second least significant byte, and so on). Then we are shifting the corresponding byte to the position of the least significant byte (8 bits for the seconds least significant byte, 16 bits for the third least significant byte, and so on), which then gets used by Wire.write(). To better understand this, read about bitwise operators on the web.

You have to send both integer values in a similar fashion (though they both have only 2 bytes instead of 4).
Now that we are sending more bytes, we also need to receive and read all these bytes correctly. First we need to request the correct number of bytes. 4 bytes for the long value and 2 bytes for both int values --> 8 bytes. So you need to request 8 bytes:

Wire.requestFrom(4, 8);

Then you need to read these bytes into the corresponding variables:

long distance = Wire.read()
                | (Wire.read() << 8)
                | (Wire.read() << 16)
                | (Wire.read() << 24);

We are using the bitwise OR (|) to put the bytes together, shifting every byte to its correct position in the long value. In a similar way you are putting together the 2 int values.


Audio Recording using Arduino BT module I want to take audio signal through mic connected to Arduino and then transfer it to PC using BT module. I want to do it with BT (HC05) and Arduino Mega. I need audio packages at 44 KHz and 24-32 bits per sample.

Can I use AudioInI2S library to receive audio samples? Does HC05 support this type of communication?

I want to save and analyze the audio samples later on. I have worked on Arduino before but I am totally new to audio streaming and I am not sure where to begin from. Any guidance would be appreciated.

In short: No and no.

  Can I use AudioInI2S library to receive audio samples?

No.  The library is not for the Mega:

  This library provides simple way to play and analyze audio data using Arduino on SAMD21 based boards (i.e Arduino or Genuino Zero, MKRZero or MKR1000 Board) using the I2S bus.

  Does HC05 support this type of communication?

No.  The HC05 is a serial module. It works at baud rates that are far to low to transfer the data in a timely fashion, and can't send data in a form the PC sees as audio (so you'd need to write your own translation software to convert serial data into an audio file).

  Any guidance would be appreciated.

Just buy a cheap bluetooth headset.


Are breadboads available in EasyEDA? So far I have been using TinkerCAD which has them but I am unable to find them on EasyEDA Library. Are connectors supposed to do the same thing? I get this empty rectangle in the EasyEDA library which I am unable to make sense of.

EasyEDA is not designed for diy prototypes like TinkerCAD is.  EasyEDA's purpose is to simulate electronic circuits and design circuit boards for those circuit designs.  Because of this they don't have a breadboard object because there would be no point in having one, since you can just connect virtual wires in the schematic mode and wire traces in the board design mode.
Furthermore, it doesn't support simulating a full Arduino board with code.


Will I be able to control stuff from anywhere in the world if I use a wifi shield like ESP8266? Currently, I am using a Bluetooth shield, HC-05, which is working perfectly but there are two problems:

Only one person can connect to Bluetooth  at a time.
I have to be in a specific place to be able to control the lights.

I want to be able to control everything from anywhere in the world. I've thought about using an Ethernet Shield, but I'd prefer using a Wifi Shield if it can do the task.

answer on your comment on Majenko's answer:
(cannot comment due to reputation)

build a simple web server on your device and make sure it is accessible from a local network node (e.g. a PC).To do this open from a web browser the page ip:port where ip is the ip assigned to arduino (usually from your router's DHCP service) and port is the port which your web server listens to. This is configured in your arduino code. For an arduino Wifi shield you can find a tutorial for this step here
Now you have to set up port forwarding. This means that when somebody from the internet sends a request on your router, the router will forward this request on your arduino and not on another node on your local network. The nodes on your local network are individually recognized by their IP address. Port forwarding is configured per port, so you must set up port forwarding from a specific in-port to a specific ip,local-port combination. For example if your arduino has been assigned ip 192.168.2.10 and your web server listens on port 80, you can forward all requests from port 8080 to 192.168.2.10:80. This means that every request comes from the internet on port 8080 on your router (internet side) will be forwarded on your local node on ip 192.168.2.10 and port 80. Note that for simplicity in-port and out-port can be the same and they usually are. Port forwarding is configured in your router's menu and the exact procedure is different for every modem. Your best bet is to search google for your modem's model + port forwarding. If you succesfully configure this, then you will be able to load web server's page from a node outside your local network by visiting ip:port where ip is your router's internet ip and port is the aforementioned in-port. A simple page to see your internet ip is this.

These are basically the main steps to have access from internet. Further improvements could be:

solving dynamic IP issue (in order to access your arduino, you have to know your router's internet ip which can change by your ISP anytime. Buying a static IP or setting up a dynamic DNS solves this issue)
turning your web server to non web server (more advanced topic).


How do I load an image using fopen()? I am trying to write a program that fopen()s an image so I can use it later.
I've wired my SD card adapter exactly the way shown here:
[![enter image description here][1]][1]
And I'm using the following code to fopen():
FILE *streamIn;
streamIn = fopen("pic.bmp", "r");

When  I compile, I get the following error:

In function main:
ccA5H011.ltrans0.o:(.text.startup+0x29a): undefined reference to `fopen'

I have the most up-to-date Arduino software.
I am using the Arduino MEGA.
The image "pic.bmp" is 100x100 and is not in any folder of the SD card, it is located right in it instead (If I click on the SD Card in "My Files" when it is plugged into my computer, pic.bmp is there).

Simple answer: use the SD library provided by the IDE.

Long answer: fopen etc are designed for use with an operating system. While it is possible to 'bend' them to work without a kernel or filesystem abstraction layer, it's not easy. The AVR compiler and libraries don't provide the facilities for doing it.

So you need to use the method that is specific to the Arduino, which is contained in a library supplied with the IDE called SD.h. It has examples with it to show you how to use it.

There are other alternatives, as well, such as the much better written FatFS that has been ported to many platforms, Arduino included.


Can I control 4 DC Brushless motors with arduino uno and Adafruit motor shield? I need to control 4 DC brushless motors. I have no experience with arduino or coding. After some research the cleanest setup seems to be using the Adafruit motor shield, however the motors I'm using have 5 wires. Can I still make this work? I envision the motors being connected to the shield via the negative and positive power wires, but what do I do with the rest?  Thank you in advance.

You don't need the motor shield at all. The motor you link to has its own driver built in.

According to the connection table on the page you link to:

Red wire to +24V
Green wire is for sensing the RPM - you can ignore it
Yellow wire is the direction select - connect to any GPIO
Black wire is ground - connect to 24V GND and Arduino GND.
Blue wire is PWM control. Connect to any PWM output on the Arduino

Note that the motor will probably spin immediately power is applied until your sketch tells it to stop by driving the PWM output LOW (or 0% duty cycle).  There appears to be a 15-25kΩ (typical) pullup resistor on that pin, so adding a smaller pulldown resistor (say 1kΩ) on it should force it to be off until you turn it on.


Autolock transistor for powering Arduino I have a portable project where I want to take care about batteries getting discharged.

Usually I just put a switch at the very beginning of my circuit that completely cuts off the electricity when switched off. The problem with this approach is that if you forget to switch it off your batteries will discharge.

So I was thinking about an approach that after some inactivity time cuts off the circuit (I want to completely cut off the electricity to minimize power consumption, so I'm not interested in sleeping modes or similar approaches).

So my approach consist in changing a switch for a regular push button that   enables the circuit when pushed, and then one of the arduino pins is used to lock the transistor until a function times out and the pin gets to a low voltage (see image)

In the arduino code I can just test a simple program that keeps the circuit closed for 10 seconds and then switches it off.

setup() {
    pinMode(3,OUTPUT);
    digitalWrite(3,HIGH);
    delay(10000);
    digitalWrite(3,LOW);
}

loop() {
}

For the transistor part I'm not sure what to use. I was thinking about using an motor driver L298 (which should work and also accepts some load for other electronics that I might have in the project)

However this looks like something that should already exist (either in a shield or maybe integrated in some Arduino variant).

Does anybody have experience with such an approach or a suggestion on any standalone transistor that would also do the job?

Any help is appreciated :)

.

Here is a mock-up of what I usually do.

simulate this circuit – Schematic created using CircuitLab

Keep in mind that the resistors are just an example value: you'll have to make some calculations.

Now, M1 is a PMOS, while M2 is an NMOS. Both MOSFETs should be able to turn on and off with the voltages you can supply them (so look at their Vgs curves). Moreover the M1 mos will be the one where all the supply current will run, so you'll have to choose it wisely. The M2 mos will only have to supply a small current, so the smallest one is fine. Beware that if the Vin voltage is greater than the maximum Vgs voltage of M1 you'll have to add a resistor between M1 gate and M2 drain to form a voltage divider with R1.

The R4 and D1 are used if you want to detect a SW1 push (for instance to turn off the device). If you don't need this feature, remove them both.

The circuit works this way: when you push the button, a voltage (for instance 5V - 0.6V of D1) will come to the arduino Vcc. The arduino then should immediately bring up the pin. This will turn on M2, which in turn switches on the M1 transistor, thus bypassing the switch. When you remove it, the arduino stays powered.

When the arduino decides that it should turn off (either because you pressed the button again, or because it timed out, or who knows) it executes two instructions: one to pull down the pin and the other is while(1). This prevents it to continue executing the program. The M2 transistor shuts down, the M1 gate floats to Vin and so it shuts down too.

You can find the transistor as discrete componetns (sometimes also in the same SOIC-8 package. Usually I use big pMOS (e.g. IRF9310 in SOIC8) and smaller nMOS (usually in SOT-23 case). I do this because I can easily solder them also on perfboards (SOIC8 single transistors have a lot of redundancy for pins, while SOT-23 ones can be mounted easily on 3 pads).


I2C LCD Serial Interface Board not displaying text (wrong pins?) I have a 1602 LCD screen that works fine on its own. However I wanted to free some pins by using an I2C / IIC LCD controller I purchased separately.

While the controller seems to be communicating with my Arduino UNO on the right address, I cannot get text to display. By default (no code) it seems the LCD will have 1 line of 16 solid "squares". When using address 27 in my code, the LCD will change to 2 lines of 16 squares (see photo below). The code also calls for the backlight to flash 3 times, which works. However I cannot get anything but 2 lines of squares. (Full code is at the bottom of this question).

I'm using the LiquidCrystal_I2C library by F Malpartida, which seems to be commonly used.
Is there a better library I should be using?

I'm wondering whether it's just the wrong pins being used in the code. All sketches I see online use the following pins:

//                    addr,en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// Set the LCD I2C address

But all of the 1602 LCDs I see online have the same pins as mine, as you can see in my photo below:

These pins seem to be standard:

To further confuse me, the pins on the LCD board start with 1 on the left, yet the default code's pins seem to start with 0! So I tried changing the code's pins to the numbers on the LCD board. The LCD no longer changes to 2 lines of squares and no longer blinks the backlight. I then tried subtracting 1 from each pin (to start from 0), same result. I then tried used the default pins minus 1, same result. Thus the default pins are somehow more correct?! What am I doing wrong?

Has anyone else gotten one of these I2C controllers to work for them, and if so, how?

Full code:

/* YourDuino.com Example Software Sketch
 16 character 2 line I2C Display
 Backpack Interface labelled "YwRobot Arduino LCM1602 IIC V1"
 terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <Wire.h>  // Comes with Arduino IDE
// Get the LCD I2C Library here:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
#include <LiquidCrystal_I2C.h>

/*-----( Declare objects )-----*/
// set the LCD address to 0x27 for a 20 chars 2 line display
// Set the pins on the I2C chip used for LCD connections:
//                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address

void setup()   /*----( SETUP: RUNS ONCE )----*/
{
  Serial.begin(9600);  // Used to type in characters
  lcd.begin(16,2);   // initialize the lcd for 16 chars 2 lines, turn on backlight

// ------- Quick 3 blinks of backlight  -------------
  for(int i = 0; i< 3; i++) {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight(); // finish with backlight on

//-------- Write characters on the display ------------------
// NOTE: Cursor Position: (CHAR, LINE) start at 0
  lcd.setCursor(0,0); //Start at character 4 on line 0
  lcd.print("Hello, world!");
  delay(1000);
  lcd.setCursor(0,1);
  lcd.print("HI!YourDuino.com");
  delay(8000);

// Wait and then tell user they can start the Serial Monitor and type in characters to
// Display. (Set Serial Monitor option to "No Line Ending")
  lcd.clear();
  lcd.setCursor(0,0); //Start at character 0 on line 0
  lcd.print("Use Serial Mon");
  lcd.setCursor(0,1);
  lcd.print("Type to display");

}/*--(end setup )---*/

void loop()   /*----( LOOP: RUNS CONSTANTLY )----*/
{
  {
    // when characters arrive over the serial port...
    if (Serial.available()) {
      // wait a bit for the entire message to arrive
      delay(100);
      // clear the screen
      lcd.clear();
      // read all the available characters
      while (Serial.available() > 0) {
        // display each character to the LCD
        lcd.write(Serial.read());
      }
    }
  }

}/* --(end main loop )-- */

First of all, it looks like these wires aren't properly connected:

I haven't disassembled a female jumper before, so that might not be the issue. However, it seems likely that this could be a cause.

Also, you need to adjust the contrast by turning that trimmer (the blue thing that looks kinda like it has a screw in it). LCDs will either display nothing, a washed out version of the text, or blue boxes if the contrast is not set correctly. This is probably the cause.


Connecting TCD1304 with Arduino I'm working on a project, where I will have 2 red light beams, where one will be constantly turned on while the other will be turned on and off continuously with frequency about 100 hz.
I need to detect, on which side is the blinking beam and show it on the output (something such as if the blinking beam is on the left, turn green LED on; if it's on the right side, turn on the red LED). Each beam is big as 3mm circle.

I bought 3pcs (in case if I burn 2 of them :D) of Toshiba TCD1304 sensors(datasheet), which have 3684 elements in a row. I want to connect the sensor with Arduino, but I really don't know how I would even start this project. I've found some schematics, but it's either for some other model or is for different kind of a project(reading different colors over the field). Either way, none of them is useful for me.

It will look something like that at the end (the blue circle will be also red, but it's striped to show, it's the blinking one).

The TCD1304's minimum OS-datarate is 200 kHz. Quite a lot more than what the arduino is capable of. You should look to faster processors or to a different sensor. The TSL1401 seems to be popular with the arduino-community.

If you /need/ the TCD1304, then an arduino due will probably be able to do it, but I'm guessing you'll have to drop the arduino-IDE to achieve the full speed of the ADC.

Here's how I've done it with a STM32F4 processor:
https://tcd1304.wordpress.com/


How to write & read from SPIFFS file as object data on ESP8266 I am trying write four digit number to SPIFFS file, and read that four digit from SPIFFS file and display on seven segment.
The code, I am writing as below, I got "0" on each segment, but if manually make number = 4567; then seven segment show proper number on every segment.
Please help me to learn more about how to read & write and convert to object data.
Here is my code;
#include <FS.h>

const char* filename = "/InputInt.txt";
int digit_1 = 0;
int digit_2 = 0;
int digit_3 = 0;
int digit_4 = 0;

int Anode_1 = 16;
int Anode_2 = 14;
int Anode_3 = 5;
int Anode_4 = 4;
int count = 0;
int digits[4] ;
int AnodePins[4] = {4, 5, 14, 16};

int clockPin = 12;
int latchPin = 13;
int dataPin = 15;

int number = 0; //declear the variables

byte numbers[10] {B00000011, B10011111, B00100101, B00001101, B10011001, B01001001, B01000001, B00011111, B00000001, B00001001};

void setup() {
  Serial.begin(115200);
  Serial.println();

  bool success = SPIFFS.begin();

  if (!success) {
    Serial.println("Error mounting the file system");
    return;
  }
  SPIFFS.format();
  File fw = SPIFFS.open(filename, "w");

  if (!fw) {
    Serial.println("Error opening file for writing");
    return;
  }
  char Written = fw.print("1234");

  if (Written == 0) {
    Serial.println("File write failed");
    return;
  }
  fw.close();

  pinMode(Anode_1, OUTPUT);
  pinMode(Anode_2, OUTPUT);
  pinMode(Anode_3, OUTPUT);
  pinMode(Anode_4, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

} //End of setup

void loop() {
  int i;
  File fr = SPIFFS.open(filename, "r");

  if (!fr) {
    Serial.println("Failed to open file for reading");
    return;
  }

  for (i = 0; i < 4; i++) {
    byte number = (Serial.write(fr.read()));
  }
  fr.close();
  break_number(number);
  display_number();
  delay(3000);
} // End of loop

// seperate the input number into 4 single digits
void break_number(int num) {
  Serial.println("");
  digit_1 = num / 1000;
  digits[0] = digit_1;
  Serial.print(" Digit_1: ");
  Serial.println(digit_1);
  int dig_1_remove = num - (digit_1 * 1000);

  digit_2 = dig_1_remove / 100;
  digits[1] = digit_2;
  Serial.print(" Digit_2: ");
  Serial.println(digit_2);
  int dig_2_remove = dig_1_remove - (digit_2 * 100);

  digit_3 = dig_2_remove / 10;
  digits[2] = digit_3;
  Serial.print(" Digit_3: ");
  Serial.println(digit_3);
  digit_4 = dig_2_remove - (digit_3 * 10);

  digits[3] = digit_4;
  Serial.print(" Digit_4: ");
  Serial.println(digit_4);
}

void display_number() {                                             //scanning
  digitalWrite(AnodePins[count], HIGH);                            //turn on the relevent digit
  digitalWrite(latchPin, LOW);                                      //put the shift register to read
  shiftOut(dataPin, clockPin, LSBFIRST, numbers[digits[count]]);    //send the data
  digitalWrite(latchPin, HIGH);                                     //put the shift register to write mode
  delay(0);
  digitalWrite(AnodePins[count], LOW);                            //turn on the relevent digit
  count++;                                                          //count up the digit
  if (count == 4) {                                                 // keep the count between 0-3
    count = 0;
  }
}

Here is the result;
1234
 Digit_1: 0
 Digit_2: 0
 Digit_3: 0
 Digit_4: 0
1234
 Digit_1: 0
 Digit_2: 0
 Digit_3: 0
 Digit_4: 0
1234
 Digit_1: 0
 Digit_2: 0
 Digit_3: 0
 Digit_4: 0

Thanks,

I directly see 3 problems with your code:

Serial.write() will not return the written data, but the number of send bytes. This means that in your for loop you are only assigning the written number of bytes to the variable, not the data. But I guess you want to display the actual data, which was read from the file. You should assign the return value of fr.read() to a variable. Then you can send it via Serial.write() and still use that variable for other things later (like displaying).

You need to look into variable scope. You have a global variable number. But in the for loop you are defining a local variable with the same name via
 byte number = ...

This variable is only valid in that specific for loop iteration. When the iteration ends, the variable is thrown away and redeclared in the next iteration. It will not be there anymore, when you leave the for loop. So currently you are saving your data in a variable local to the for loop. It does NOT touch the global variable. Thus the other functions only see the value zero, with which the global variable number was initialized. You can remove the type byte before the variable in the for loop. That makes it an assignment instead of a definition. Thus then you really write the data into the global variable.

Data encoding: Clearly you have your number in the file as ASCII encoded text. But you seem to handle it as binary data. That cannot work. For example: When you read the first character of 1234 (which is written in the file), then you get '1' (the character, not the number). When looking at an ASCII table you can see, that this character corresponds to a decimal number of 49 (or 0x31 in hex). You can convert an ASCII encoded digit to a real number by subtracting the value of the character '0':
 int number = fr.read() - '0';

or
 int number = fr.read() - 48;

(both are equivalent).
Also you are currently just saving the read character into a single variable. That means, that after the for loop only the last character is left. Since this is a composite number, you should do something to compose it. Like this:
 number = 0;
 int factor = 1000;
 for(int i = 0; i<4; i++){
     number += (fr.read() - '0') * factor;
     factor /= 10;
 }

Note: This is untested, it is not the best way, but the easiest at this point, and it only works for numbers between 1000 and 9999 (4 digit numbers). You can implement this more versatile.
First we are resetting the number variable, so that old values are not getting in our way. We are using a variable holding the current factor (starting with 1000, since that is the figure in which the first digit lies). Then we go through the 4 characters, reading them. We subtract the character '0' (as described above) and then multiply by the factor. That resulting number is added to the variable number. Then we divide the factor by 10 (getting from 1000 to 100, then to 10 and finally to 1). At the end we can use number like any other integer variable.

Alternative implementation of reading the number, which is suitable for different numbers of digits:
number = 0;
// Prepare character buffer to read the number in
char buffer[10] = ""; // space for maximum 9 digits
int pos = 0; // position variable in the buffer
while(fr.available() && pos < 9){ // loop while there is data left to read in the file or we have no pace left in buffer (leaving one character for the terminating null character
    char c = fr.read(); // read character into variable
    if(isDigit(c)){
        buffer[pos] = c; // save digit in buffer
        pos++; // increment position for the next character
    } else {
       break; // break out of loop, if read character is not a digit (we don't want to read further when a non-digit character comes up)
    }
}
buffer[pos] = 0; // terminate buffer with null character
number = atoi(buffer); // use standard function to convert to integer number

Note:

This code is not tested, though it compiles without errors
You see, that it is not smaller, than the other one, but can handle different number of digits.
You can still use the first version with smaller numbers, if you always pad them with zeros. So instead 991 you would write 0991 to the file. That will make the first version work.


How to measure relay current draw from Arduino How does one measure the amount of current a relay is drawing from an Arduino?

Do I connect a multimeter in series with the digital pin to which the relay 'IN1' is connected (in this case pin 7), the 5V pin or GND pin?

Provisional testing gives me the following results (when the relay is ON):

Pin 7: 3.93 mA
5V pin: 70.2 mA
GND pin: 66.8 mA

Also, assuming I pull more than 40 mA through digital pin 7 for a number of seconds, is the pin likely to fail immediately? Or slowly degrade over time?

Have you noticed how the 5V current is, give or take a little inaccuracy on the part of your ammeter, the sum of the other two currents?

Without knowing what relay you are talking about, my guess is it is one of the SainSmart 5V relay modules with opto-coupler. Those, by default, use a common 5V input and split it between the opto-coupler (and then into your digital pin to be sunk through ground) and the relay to ground.  Therefore the 70mA is split between 66mA through the relay and 4mA through the digital IO pin.

So the correct place to measure the total current in this instance is the 5V pin since that is the common point for the circuit.

In answer to your second question, read the datasheet.  It quite clearly states:

  Although each I/O port can sink more than the test conditions (20 mA at VCC = 5V, 10 mA at V CC = 3V) under steady state conditions (non-transient), the following must be observed:

  ATmega48PA/88PA/168PA/328P:

  The sum of all I OL , for ports C0 - C5, ADC7, ADC6 should not exceed 100 mA.
  The sum of all I OL , for ports B0 - B5, D5 - D7, XTAL1, XTAL2 should not exceed 100 mA.
  The sum of all I OL , for ports D0 - D4, RESET should not exceed 100 mA.

  If IOL exceeds the test condition, VOL may exceed the related specification. Pins are not guaranteed to sink current greater than the listed test condition.

And also a similar note for sourcing current.

So although they can sink or source more than 20mA, and theoretically up to 40mA, anything more than 20mA is not guaranteed and should be avoided.

Basically overcurrents cause increased heat dissipation in the MOSFETs which causes the internals to break down.  Hence the note about under steady state conditions.

So sourcing or sinking more than 20mA for longer than a few ms is asking for trouble. More than 40mA is just being irresponsible.

Furthermore, the MOSFETs in the IO pins act like resistors when turned on.  As you should know, according to Ohm's Law, the voltage across a resistor is proportional to the current through the resistor.  Increase the current and you increase the voltage across the resistor.  Since that resistance is in series with your circuit that voltage gets subtracted from your available voltage on the IO pin - so drawing too much current will cause the voltage to drop (or rise for sinking) below (above) the specifications for the logic voltage for that IO pin.  So not only do you risk damage to the IO pin and other parts of the chip through overheating, but you also then operate outside the specifications for the logic levels which can cause things that you are communicating with to not work right.


Arduino UNO dead with CNC shield I have an Arduino UNO with a CNC shield. The Arduino is almost certainly a clone.

I installed GRBL with no issue and I have assembled a jig with CD-ROM motors. My first attempt to control this with UGS worked no problem.

I powered down to change the stepping with the jumpers and powered back up and was presented with a very hot smell after a few moments.

I removed the power quickly but now I can no longer program the UNO. It gets recognized in my devices but I can't send any code, even blink.

The jumpers were set like many examples I have seen on the web so I don't think this was the issue.

I am wondering if the way I powered it up was the issue? I am supplying the UNO with 12V 2A supply and I can't recall what order I plugged them in but I get the feeling it must have been supplying 12V to the Arduino.

I have now removed the shield and powering the unit solely from the USB and still can't communicate.

I have resigned to the fact this board is now toasted. Is it important which order you plug in the Arduino? USB first? Do you think it will be possible to recover this Arduino.

This sounds as the ATmega328p processor of the UNO was fried. As the UNO has a second processor (ATmega16U2) which is simply a USB-to-serial converter you only see the presence of this in the list of USB devices but it cannot communicate with the board's main processor anymore.

The plug-in order is not that important with the UNO board only but depending on the components you have attached it may be important. especially if the circuit does not have protection against induction current, p.e. fly-back diodes.


Industry Standard for Single-Board Computers? Do Arduinos, or any other single-board computer, come in any sort of industry-standard form factor? I'm trying to sell management on using Arduino, but they are stuck on the question "what if Arduino goes out of business", and if I could answer "we can just switch over to using brand X because it's the same size and has the same connectors", my life would be much easier.

Whether or not the Arduino company goes out of business isn't all that relevant. For one thing, there are now two competing companies vying for the Arduino trademark - arduino.cc and arduino.org.
The Arduino has such a ground-swell of popularity that clone boards are widely available on eBay and from other suppliers. While people are willing to buy them, someone will sell them.
The design is open-source, which makes it a safer choice than other designs who keep their design proprietary. For one thing, it guarantees that someone will make compatible boards, even if Arduino(s) fold.
The "heart" of the Arduino is (in most cases anyway) a chip from Atmel - so you really should ask if Atmel will go out of business. Probably not, but in any case, an alternative supplier might just as easily go out of business.
I wouldn't be building an "Arduino board" into a production system anyway - too much chance that wires would fall out of the prototyping sockets. However the prototyping board is good for learning about their capabilities, and testing your code.

  Do Arduinos, or any other single-board computer, come in any sort of industry-standard form factor?

I'm not aware of any industry-standard form factor. The Uno design has caused a lot of people to make "shields" that fit onto that form factor, so that is probably the closest you would get to an industry standard.


How do I lock a servo motor? I am working on a robot which uses Ackermann's steering principle. Now the steering principal itself is in the development stage and the first prototype is pretty much good except for the fact that it can get turned very easily.

So I was hoping to find a way to lock the servo operating the steering mechanism so that it only rotates when the servo does. Any way to do that??

I'm using a UNO.

Thanks!

A normale servo will stay in position when:

It's powered up (with enough current)
You are feeding the control signal into it.

And

It's rated for the amount of force applied.

Based on your comments, it seems that it's not a regular servo or could be faulty.
I couldn't find the datasheet for your servo, so I can't tell if it's normal behavior, though it seems unlikely. (Servo's aren't made to bounce around)

Edit:
It doesn't really make sense that it could be easily rotated by touching it, that would also mean that it can't lift anything? I would suggest trying another servo.


Can I have backup power for an Arduino device? I have an arduino project that will work while plugged into a generic outlet. But I want to connect a battery in case the power goes out. I know there are various power sources (coin cell, polymer lithium, 9V, etc.). But if I code my project to use the backup power if the main power goes down, would that mean the backup always has to be running? How would I go about this?

Thanks for the help! Every time you help me you save a kitten!!

you could set up a relay to work in reverse with the mains power,

have your backup battery connected to the gate contacts of the relay, and then use the mains power running your project to open the relay and keep it open as long as there is power. if the mains turns off, then the relay closes and the battery is connected.

you might want to put something in line with the power to the arduino to make sure you don't get any spikes when things switch.

hope this helps as i love kittens


Can I connect a remote control relay to a arduino uno board by disabling the remote control in the relay? I was making a home automation system by making some of the appliances in the home like fans and lights voice activated. But by mistake I bought a remote controlled relay in place of a normal relay from a shop and return does not seems possible. So I want to know if I will be able to use that remote controlled relay in this project?

I don't like to work with mains, so I use those outlets and connect a 433MHz transmitter to the arduino to activate the outlets.

You'd have to check the frequency of the unit, and see if anyone have decoded the transmitted data package.

If that doesn't float you're boat, you could open up the unit, and remove/desolder the relay. Add a transistor, and flyback diode and you're done. Just be careful with mains power.


Get a specific item from comma separated text I use bluetooth (works like serial monitor).
Let me say i send a text to my hc-05 (same as sending to serial monitor)
My current code is displaying text from serial monitor/HC-05 TO LCD
#include <LiquidCrystal.h>

LiquidCrystal lcd(4, 6, 10, 11, 12, 13);
String readString;

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

void loop() {
  while(Serial.available()){
    delay(50);
    char c=Serial.read();
    readString+=c;
  }
  if(readString.length()>0){
    Serial.println(readString);
      lcd.clear();
      lcd.print(readString);
    readString="";
  }
}

from serial monitor i type `a,b,c,d`

now my goal is to just get the a and display in lcd

or

in other words i want to get the value of a b c d in the text that is CSV to list or array and get value for index 1,2,3,4

OR

split string by delimiter

so how can i do it
details-ARUINO UNO

Use the strtok function.
From Geeks for geeks (https://www.geeksforgeeks.org/strtok-strtok_r-functions-c-examples/):
arguments:

str: The string which is to be split
delim: The character on the basis of which the split will be done Return value

The function performs one split and returns a pointer to the token split up. A null pointer is returned if the string cannot be split.


Battery solution Nano 33 iOT Since the Nano 33 boards are quite new right now, I haven't found any details on how to hook one up with batteries.

I'm pretty daft when it comes to electronics (I'm a software man), and I read that the new Nano 33 requires 3.2V, which is a bit of a departure from the 5V the old models supported.

From what I can tell, I might be able to use a single LiFePO4 cell. Am I correct in this assumption? And if so, are there any pitfalls in going this route?

EDIT: I might have misunderstood the difference between operating voltage and input voltage. Does this mean that I can plug any AA battery pack in as a power source?

You can either use the 3.3V pin to supply power to the board, or use the Vin pin.

By using the VIN pin to power goes through a (step down) voltage regulator, that provides a nice stable 3.3V to the board. The regulator in the Nano 33 IoT is the MPM3610, which requires an input voltage of at least 4 - 4.5 Volt. Which is more that a LiPo or LiFePo single cell can supply. You could use a multi-cell battery pack. Or a USB power bank. So this solutions is not really ideal.

The other option was to connect the battery directly to the 3.3V pin. The voltage of a LiFePo however changes as it is being discharged. The voltage is around 3.65V when full, and 2.5-2.75V when "empty". The 3.2V rating is called the nominal voltage (kind of an average voltage).
So it's a bit too high when full, and too low when empty. The voltage also isn't regulated, so it can fluctuate a bit, based on the amount of current that's being used.

The maximum voltage for the SAMD21 on this Nano is 3.63V. Maximum voltage for the gyro (LSM6DS3) is 3.6V. The absolute maximum voltage for the radio (NINA-W10) is 3.6V.

So a full LiFePo is slightly too high for the Nano. Though I think you should be fine. But don't try this with a regular LiPo of Lion battery (4.2V when full).


Where is the inaccuracy of my arduino thermistor circuit coming from? I've setup four thermistors and a known resistor in series and connected them to the 3.3V output (as I've heard it's cleaner than the 5V) of an Arduino Uno (with the 3.3V also connected to ARef to increase accuracy), with the four analog inputs testing the voltage drop across each thermistor to determine its resistance, and hence temperature.

But even with no change in the thermistor temperatures, the voltages I get from the arduino vary significantly. See below an example readout of the four arduino inputs (with thermistor temperatures/resistances same throughout):

230 424 634 849

212 412 597 819

241 415 611 857

204 413 654 845

The accuracy I come out with is around 5-10 degrees - way more than I expected. Why is this? And what can I do to get it down to less than one degree? Many thanks

UPDATE:
A MASSIVE THANKYOU to all those who helped me on this, particularly @NickGammon, @Talk2 and most of all @JRobert for the brilliantly clear and simple to follow circuit instructions to follow, all of which helped to thoroughly solve my problem! The sensor works great now, many thanks!!

Why are you using the voltage divider and measuring by parts? As @nickgammon points out, you are measuring only a 1/5 of full scale at each measurement, meaning your resolution is down by 5:1 over what the A/D is capable of. Also, the divider network comes to around 500KOhms. Work out the current through that and you get a very feeble <7 microAmps. The wires are antennas that could well be contributing noise at a significant fraction of that level.

Is there a reason for the divider circuit? Could you use a single thermistor from Vcc to Gnd plus a resistor in a 2-way divider? That will have the advantages of:

Using (more of) the full range of A/D;
Taking only one reading instead of several (and the several are necessarily skewed in time since you're multiplexing the one A/D);
A larger current (ok, only 33 microAmps, but 5x better than before);
Presumably less pickup into the network than with 5 leads. Keeping the measurement lead as short as possible may help, too.

Update:

Then you probably want a 2-component divider for each temperature you need to measure, paralleled between the power rails. I just guessed, not calculated, the resistances of R1, R3, R5, & R7. You'll want to estimate the maximum and minimum temperatures of interest in each channel and pick values that will give you the best ranges without drawing excessive currents when the thermistor values are low.

simulate this circuit – Schematic created using CircuitLab


Alter baud rate after being certain events I'm using my HC-05 (Master) to receive strings from a sensor (Slave). Each string is supposed to have 7 items divided by ',' like so:

  a,b,c,d,e,f,g

But it isn't always received in such a manner. Sometimes it's 1.5 of a string or 2 strings in 1. I have tested the sensor with its native software and others, so the sensor shouldn't be the problem. So I believe it may be a baud rate issue. I tried to increase the HC-05's baud rate to 115200, but wasn't able to test anything because I need to use AT commands at the beginning of the program and for that the baud rate has to be 38400.

Is there any way to change the baud rate for Serial after the fact?

PS: I'm using a Mega 2560 and the sensor has a sample rate of 8Hz.

#include <SoftwareSerial.h>
#include <SD.h>

String test="";
char aux;
File myFile;

void setup() {
  pinMode(22, OUTPUT);
  digitalWrite(22,HIGH);
  Serial1.begin(38400);
  Serial.begin(38400);
  Serial.println("To begin capture press any key and enter");
  while(!Serial.available());
  Serial1.println("AT+INIT");
  while(!Serial1.available());
  Capture();
}

void Capture() {
  while(!Serial1.available());
  for(int i=0;i<2;i++) {
    delay(125);
    while(Serial1.available()) {
      aux=Serial1.read();
      Serial.print(aux);
    }
  }
  Serial.println("END");
}

void loop() {
}

To answer your specific question, yes you can alter the baud rate after an event.  Just use a Serial.end() then a Serial.begin() with the new baud rate.


LCD shows output without pressing the sensor #include<LiquidCrystal.h>
LiquidCrystal lcd(13,12,11,10,9,8);
#define vibrate_sense 7

char str[70];
char *test="$GPGGA";
char logitude[10];
char latitude[10];

int i,j,k;
int temp;
//int Ctrl+z=26;    //for sending msg
int led=13;

void setup()
{
  lcd.begin(16,2);
  Serial.begin(4800);
  pinMode(vibrate_sense, INPUT);
  pinMode(led, OUTPUT);
  lcd.setCursor(0,0);
  lcd.print("..Initializing..");
  lcd.setCursor(0,1);
    lcd.print("....System...");
delay(1000);
lcd.clear();
lcd.setCursor(0,0);
  lcd.print("Searching for");
    lcd.setCursor(0,1);
      lcd.print("Gps Signals");
  delay(2300);
lcd.clear();
  lcd.setCursor(0,0);
    lcd.print("Setup Completed");
  delay(500);
  lcd.setCursor(0,0);
    lcd.print("Accident detect");
  lcd.setCursor(0,1);
    lcd.print("& Alert system");
  delay(1500);
  lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("No accident");
        lcd.setCursor(0,1);
        lcd.print("occured");

}

void loop()
{
  if (digitalRead(vibrate_sense)==0)
  {
    for(i=18;i<27;i++)          //extract latitude from string
    {
      latitude[j]=str[i];
      j++;
    }

    for(i=30;i<40;i++)          //extract longitude from string
    {
      logitude[k]=str[i];
      k++;
    }

lcd.clear();
    lcd.setCursor(0,0);        //display latitude and longitude on 16X2 lcd display
    lcd.print("Latitude(N)");
    lcd.print(latitude);
    lcd.setCursor(0,1);
    lcd.print("Longitude(E)");
    lcd.print(logitude);
    delay(500);
    lcd.clear();
        lcd.setCursor(0,0);
    lcd.print("Accident has");
            lcd.setCursor(0,1);
    lcd.print("been Detected");
delay(500);
lcd.clear();
    lcd.print("Sending SMS");
    delay(500);
    lcd.clear();
    Serial.begin(9600);

    Serial.println("AT+CMGF=1");    //select text mode
    delay(10);
    Serial.println("AT+CMGS=\"7066128969\"");  // enter receipent number
    Serial.println("Vehicle Accident occured:");
    Serial.print("Latitude(N): ");             //enter latitude in msg
    Serial.println(latitude);                  //enter latitude value in msg
    Serial.print("Longitude(E): ");            //enter Longitude in Msg
    Serial.println(logitude);                  //enter longitude value in msg
    Serial.print("http://maps.google.com/maps?&z=15&mrt=yp&t=k&q=");
    Serial.println(latitude);
    Serial.println("+");
    Serial.println(logitude);
    Serial.write(26);                      //send msg  Ctrl+z=26

      lcd.setCursor(0,0);
    lcd.print("SMS Sent");
delay(1000);
lcd.clear();
          lcd.setCursor(0,0);
    lcd.print("Help Please");

    temp=0;
    i=0;
    j=0;
    k=0;
    delay(20000);                        // next reading within 20 seconds
    Serial.begin(4800);
  }
}

void serialEvent()
{
  while (Serial.available())            //Serial incomming data from GPS
  {
    char inChar = (char)Serial.read();
     str[i]= inChar;                    //store incomming data from GPS to temparary string str[]
     i++;
     if (i < 7)
     {
      if(str[i-1] != test[i-1])         //check for right string
      {
        i=0;
      }
     }
    if(i >=60)
    {
     break;
    }
  }
}

This is my code for my project.
It is accident detection system and it has to work like, when I press the sensor or limit switch, it has to show a message on an LCD that an accident occurred. But it shows the message on the LCD WITHOUT pressing the sensor button.

What to do?
I think there is a mistake in my program. Can anybody please tell me where it is?

First off I edited indentation in your code because incorrect indentation is little bit confusing.

#include <LiquidCrystal.h>
LiquidCrystal lcd(13,12,11,10,9,8);
#define vibrate_sense 7

char str[70];
char *test="$GPGGA";
char logitude[10];
char latitude[10];

int i,j,k;
int temp;
//int Ctrl+z=26;    //for sending msg
int led = 13;

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

  pinMode(vibrate_sense, INPUT);
  pinMode(led, OUTPUT);

  lcd.setCursor(0,0);
  lcd.print("..Initializing..");
  lcd.setCursor(0,1);
  lcd.print("....System...");
  delay(1000);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Searching for");
  lcd.setCursor(0,1);
  lcd.print("Gps Signals");
  delay(2300);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Setup Completed");
  delay(500);
  lcd.setCursor(0,0);
  lcd.print("Accident detect");
  lcd.setCursor(0,1);
  lcd.print("& Alert system");
  delay(1500);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("No accident");
  lcd.setCursor(0,1);
  lcd.print("occured");
}

void loop(){
  if (digitalRead(vibrate_sense) == 0){
    for(i = 18; i < 27; i ++){          //extract latitude from string
      latitude[j]=str[i];
      j++;
    }

    for(i=30;i<40;i++){          //extract longitude from string
      logitude[k] = str[i];
      k++;
    }

    lcd.clear();
    lcd.setCursor(0,0);        //display latitude and longitude on 16X2 lcd display
    lcd.print("Latitude(N)");
    lcd.print(latitude);
    lcd.setCursor(0,1);
    lcd.print("Longitude(E)");
    lcd.print(logitude);
    delay(500);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Accident has");
    lcd.setCursor(0,1);
    lcd.print("been Detected");
    delay(500);
    lcd.clear();
    lcd.print("Sending SMS");
    delay(500);
    lcd.clear();
    Serial.begin(9600);

    Serial.println("AT+CMGF=1");    //select text mode
    delay(10);
    Serial.println("AT+CMGS=\"7066128969\"");  // enter receipent number
    Serial.println("Vehicle Accident occured:");
    Serial.print("Latitude(N): ");             //enter latitude in msg
    Serial.println(latitude);                  //enter latitude value in msg
    Serial.print("Longitude(E): ");            //enter Longitude in Msg
    Serial.println(logitude);                  //enter longitude value in msg
    Serial.print("http://maps.google.com/maps?&z=15&mrt=yp&t=k&q=");
    Serial.println(latitude);
    Serial.println("+");
    Serial.println(logitude);
    Serial.write(26);                      //send msg  Ctrl+z=26

    lcd.setCursor(0,0);
    lcd.print("SMS Sent");
    delay(1000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Help Please");

    temp = 0;
    i = 0;
    j = 0;
    k = 0;
    delay(20000);                        // next reading within 20 seconds
    Serial.begin(4800);
  }
}

void serialEvent(){
  while (Serial.available()){            //Serial incomming data from GPS
    char inChar = (char)Serial.read();
    str[i] = inChar;                    //store incomming data from GPS to temparary string str[]
    i++;
    if (i < 7){
      if(str[i-1] != test[i-1]){         //check for right string
        i = 0;
      }
    }
    if(i >= 60){
      break;
    }
  }
}

Second thing is this line if (digitalRead(vibrate_sense) == 0){ you are checking there vibrate_sense for value 0. Are you sure, that triggered value is 0 and not 1? Try this code to test which value is equal to triggered state.

#define vibrate_sense 7

void setup() {
  Serial.begin(9600);
  Serial.println("Sensor testing");
  pinMode(vibrate_sense, INPUT);

}

void loop() {
  Serial.println(digitalRead(vibrate_sense));
  delay(300);
}

Last thing is connection of your sensor/button. For button you have to use also PULL_UP/PULL_DOWN resistor to have correct logic value on digital pin.


Error 400. The request has an invalid header name ESP8266 (HTTP-POST) I'm trying to send a http post to my server from an esp8266-Wifi (I use the ESP8266 library)

I check all my http post format, and I guess is okay... but at the response, the monitor serial answer me like this:

Requesting POST: HTTP/1.1 400 Bad Request
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
Date: Sat, 10 Jun 2017 23:12:48 GMT
Connection: close
Content-Length: 339

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii">

Bad Request - Invalid Header

HTTP Error 400. The request has an invalid header name.

closing connection

and this is my code:

#include <ESP8266WiFi.h>
const char* ssid     = "Putostodosmenosyo";
const char* password = "CetriX.2016%Gdl";

const char* host = "187.201.44.110";

const String Cadenadatos = "info=Micanton|2017-06-09%2012:00|25" ;
//const String Tamano = String(Cadenadatos.length()) ;
const String postiu = "POST /wsCo2Keellingv1002/wsCo2Keelling.asmx/GuardaInfoArduino HTTP/1.1\r\nHost:187.201.44.110:80\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length:144\r\n\r\n?info="+String(Cadenadatos)+"\n" ;
const String postam = String(postiu);

void setup() {
  Serial.begin(9600);
  delay(100);

  // We start by connecting to a WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  delay(2000) ;
}

void loop() {

  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host,httpPort)) {
    Serial.println("Conexion fallida");
    return;
  }

 //String data = "pst=temperature>" + String(random(0,100)) +"||humidity>" + String(random(0,100)) + "||data>text";

   Serial.print("Requesting POST: ");
   // Send request to the server:
   //client.println("POST /wsCo2Keellingv1002/wsCo2Keelling.asmx/GuardaInfoArduino HTTP/1.1");
   //client.println();
   //client.println("co2kelling.hopto.org") ;
   client.println("POST /wsCo2Keellingv1002/wsCo2Keelling.asmx/GuardaInfoArduino HTTP/1.1");
   client.println("Host: co2kelling.hopto.org");
   client.println("Content-Type: application/x-www-form-urlencoded");
   client.print("Content-length: ");
   client.print(postiu.length());
   client.println();
   client.print(String(Cadenadatos));
   while(client.connected())
   {
    while(client.available())
    //String line = client.readStringUntil('\r') ;
    Serial.write(client.read()) ;
   }

   /*delay(500); // Can be changed
  if (client.connected()) {
    client.stop();  // DISCONNECT FROM THE SERVER
  }*/
  Serial.println();
  Serial.println("closing connection");
  delay(5000);
}

NOTE: this is my fixed url
http://187.201.44.110/wsCo2Keellingv1002/wsCo2Keelling.asmx/GuardaInfoArduino?info=Micanton|2017-06-09%2012:00|25

EDIT

This is my Post format:

POST /wsCo2Keellingv1002/wsCo2Keelling.asmx/GuardaInfoArduino HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: length
info=string

You are lacking the required blank line between the headers and the content. Also your content length is wrong.

Change

client.print(postiu.length());

Into

client.println(Cadenadatos.length());


Returning struct from function generates 'does not name a type' compilation error I have a main.ino file that contains
struct EulerAngles {
  double roll, pitch, yaw;
};

void setup() {
  EulerAngles angles;
  angles = anglesCalc();
  Serial.print(angles.yaw);
}

void loop() {
  Serial.println("In loop");
  delay(1000);
}

and an angles.ino file that contains
EulerAngles anglesCalc(){
   EulerAngles a;
   // calculate a
   return a;
}

When I compile the program, I get a compile error in the main.ino file:
   code/so_examples/main.ino:5:1: error: 'EulerAngles' does not name a type
 void setup() {
 ^~~~~~~~~~~
code/so_examples/main.ino: In function 'void setup()':
code/so_examples/main.ino:7:12: error: 'anglesCalc' was not declared in this scope
   angles = anglesCalc();
            ^~~~~~~~~~
code/so_examples/main.ino:7:12: note: suggested alternative: 'angles'
   angles = anglesCalc();
            ^~~~~~~~~~
            angles
[Build] Error occurred.

How do I fix this? Note that struct is declared before all else, so this answer does not seem to apply.  I am using the Stino plugin for Sublime Text as the IDE.

I would avoid having multiple .ino files, because of the issues raised
in the other answers. If you want to split your code into multiple
files, the scheme that works reliably is to have:

a single .ino file, named like the containing folder, holding the
“main” program (this is Arduino-specific)
a pair of .h/.cpp files for each “module” implementing a sub-feature
of the program (this is common C++ practice).

Within the .h/.cpp pair, the .h file declares everything the compiler
needs for understanding code that uses the feature: type definitions
(including classes) and function prototypes. The .cpp file holds the
actual implementation.
Applying this scheme to your case would give:
my-sketch.ino (actually, with the name of the containing folder):
#include "angles.h"

void setup() {
  EulerAngles angles;
  angles = anglesCalc();
  Serial.print(angles.yaw);
}

void loop() {
  Serial.println("In loop");
  delay(1000);
}

angles.h:
struct EulerAngles {
  double roll, pitch, yaw;
};

EulerAngles anglesCalc();

angles.cpp:
#include <Arduino.h>
#include "angles.h"

EulerAngles anglesCalc() {
   EulerAngles a;
   // calculate a
   return a;
}

Note that including <Arduino.h> is only useful if the code uses the
Arduino core API. Otherwise you can omit it. The main sketch does not
need to include <Arduino.h> because it is implicitly included in the
.ino file by the Arduino IDE. There is no such implicit inclusion when
the IDE processes .cpp files.


Can't swipe between RTC and some event Some ideas please?
I'm stuck and also don't judge me for how i wrote the code. I'm new into coding and still learn. So, the idea is that i want to display data and clock on lcd but when the lamp is on i want a message to be printed for 5 sec then the clock and date will be printed again... and so on.
Data from serial is comming from an esp which trigger some event wireless.Arduino receive feedback that the job has been done and then display a message on lcd. More exactly.. Using mqtt - from browser i push a button to turn on a lamp. Once the lamp is on, a message arrives at esp from the mqtt broker that lamp is on now. esp then send data to arduino using serial. and arduino should display the text " Lamp on "

    #include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <DS3231.h>

LiquidCrystal_I2C lcd(0x3F,20,4);
DS3231 rtc (SDA, SCL);

int verificare_stare_releu = A13;
char a;

void setup(){
  Serial.begin(115200);
  rtc.begin();
  lcd.init();
  lcd.backlight();
  pinMode(A13,INPUT);
}

void loop(){

  int b = analogRead(verificare_stare_releu);
    if(!Serial.available()){
    display_clock();
    }
    if(!Serial.available()){
    if(b >= 900){
      lcd.print("Lamp ON ");
    }

    if( b < 900 ){
      lcd.print("Lamp OFF");
    }

    }

  if(Serial.available()>0){
    a = Serial.read();
    if(a == 102){
    lcd.setCursor(0,0);
    lcd.print("Lamp ON ");
    }
  if(a == 110){
    lcd.setCursor(0,0);
    lcd.print("Lamp OFF");
  }
  }

}

  //a = digitalRead(verificare_stare_releu);

void display_clock (){
   lcd.setCursor(0,0);
  lcd.print("Ora: "+(String)rtc.getTimeStr());
  lcd.setCursor(0,1);
  lcd.print((String)rtc.getDOWStr()+(String) rtc.getDateStr());
}

Although I still do not understand how to combine the data from the serial port with the analog input, I can show how to display a message for 5 seconds, using the Blink Without Delay example.

A boolean variable 'message' is used to prevent the normal code to use the display during the 5 seconds. The same boolean variable is used to check if 5 seconds have passed (using millis). Once the 5 seconds have passed, the boolean variable is set to 'false' and that releases the display so it can be used for normal things.

To start the 5 seconds, these two lines are required:

previousMillis = millis();
message = true;

When 'message' is set to true, the variable 'previousMillis' must be valid. Once 'message' is false, the value of 'previousMillis' is not used anymore.

The sketch can be like this:

unsigned long previousMillis;
const unsigned long interval = 5000;  // 5 seconds
bool message = false;     // true if message is displayed

void setup() {
  // the code for setup here
}

void loop() {
  if(!message) {          // message not displaying ?
    // show temperature, time, etc.
  }

  if(Serial.available() > 0) {
    int a = Serial.read();
    switch(a) {
      case 102:
        lcd.setCursor(0,0);
        lcd.print("Lamp ON ");
        previousMillis = millis(); // remember this moment
        message = true;    // set boolean variable
        break;
    }
  }

  if(message) {
    if(millis() - previousMillis >= interval) {
      // 5 seconds have passed ?
      message = false;    // release the display
    }
  }
}


My two ultrasonic sensors are reading inaccurately I am having trouble getting two of my ultra sonic sensors to read accurate results in cm. I am using a HC-SR04 currently.

I get random numbers at different distances with an object in front (smooth cover book)

Test 1:
Real distance: 10 cm
Sensor 1: 0.00cm
Sensor 2: 82.42

Test 2:
Real distance: 10cm
Sensor 1: 92.11cm
Sensor 2: 95.03

Against the wall with no book:

Test 1:
Real distance: 10 cm
Sensor 1:0.00cm
Sensor 2: 13.20

Test 2:
Real distance: 10 cm
Sensor 1:24.37cm
Sensor 2:26.75

The numbers constantly fluctuate. I am trying to get accurate results.

I am not sure if the sensors are broken or if my code is incorrect.I appreciate any help.

Here is my set up: [

#define trigPin1 13
#define echoPin1 12
#define trigPin2 11
#define echoPin2 10

float duration, distance, duration1, distance1, duration2, distance2;

void setup() {
  Serial.begin (9600);
  pinMode (trigPin1, OUTPUT);
  pinMode (echoPin1, INPUT);
  pinMode (trigPin2, OUTPUT);
  pinMode (echoPin2, INPUT);

}

void loop() {

  FindRange(trigPin1, echoPin1);
  duration1 = duration;
  distance1 = distance;
  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;
  Serial.print(distance1);
  Serial.print(" cm  ");
  Serial.print(distance2);
  Serial.println(" cm");
  delay(100);

}

void FindRange(int trigPin, int echoPin) {

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

  duration = pulseIn(echoPin, HIGH);
  distance = (duration / 2) * 0.0345;
  delay(100);

}

I am not sure but may be it helps just by checking principle of working of this sensors as it is depicted for low range distance you must be carefull about reflection from other source of ultrasonic. I think it would be a good Idea to place a delay between these two module so to make sure it get less noise from each other

  FindRange(trigPin1, echoPin1);
  duration1 = duration;
  distance1 = distance;
  delay(1000);//add delay
  FindRange(trigPin2, echoPin2);
  duration2 = duration;
  distance2 = distance;
  delay(1000);//add delay

the other reason for getting zero may be your controller could not measure reflection from wall due to lowspeed sampling (if you are polling) or reading time with low precision so I have a suggestion for you if you are familiar with STM32 there is a built-in hardware implementation for measure time of pulse using timers called one-pulse mode it may helps you get precision you need


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

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

And the link

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


How to Run Stepper motor through Serial Communication I am trying to run a Stepper motor from my c++ application, from which I sent commands but its not running not sure why would it not run, outside serial check it run but inside serial check it not run.

Here is my code, not sure what am doing wrong, my first time with Arduino.

#include <AccelStepper.h>

#define BAUD 9600

// CNC Shield V3  Step and Dir pins on Mega 2560
#define step_pin_x 2
#define dir_pin_x 5
#define MOTOR_X_ENABLE_PIN 8
// Drive A4988
#define motorInterfaceType 1

AccelStepper stepper_X = AccelStepper(motorInterfaceType, step_pin_x, dir_pin_x);

void setup() {
  Serial.begin(BAUD);
  pinMode(53, OUTPUT);   // for red led it pin # 53
  pinMode(MOTOR_X_ENABLE_PIN, OUTPUT);  // for X stepper motor

    stepper_X.setMaxSpeed(1000);
    stepper_X.setSpeed(500);
}

void loop() {
    String input;
  //If any input is detected in arduino
  if(Serial.available() > 0){
    //read the whole string until '\n' delimiter is read
    input = Serial.readStringUntil('\n');

    if (input.equals("ON")){
       digitalWrite(53, HIGH);   // Turn ON RED LED
       stepper_X.runSpeed();      // Suppose to run stepper motor .. but not working
       Serial.println("X Motors:: "+input);

    }else if (input.equals("OFF")){
       stepper_X.stop();
       digitalWrite(53, LOW);    // Turn OFF RED LED
       Serial.println("X Motors:: "+input);
    }

  }else{
  //  stepper_X.runSpeed();      // if uncommented stepper motor will run
  }
}

Update
so it seems its code blocking issues

i update my code according to tut : https://majenko.co.uk/blog/reading-serial-arduino

    char buf[80];

    int readline(int readch, char *buffer, int len) {
        static int pos = 0;
        int rpos;

        if (readch > 0) {
            switch (readch) {
                case '\r': // Ignore CR
                    break;
                case '\n': // Return on new-line
                    rpos = pos;
                    pos = 0;  // Reset position index ready for next time
                    return rpos;
                default:
                    if (pos < len-1) {
                        buffer[pos++] = readch;
                        buffer[pos] = 0;
                    }
            }
        }
        return 0;
    }

void loop() {
   if (readline(Serial.read(), buf, 80) > 0) {
   if(strcmp("n", buf) == 0){
          digitalWrite(53, HIGH);
         stepper_X.setMaxSpeed(1000);
         stepper_X.setSpeed(500);
          stepper_X.runSpeed();
          Serial.print("All Motors:: ");
          Serial.print(buf);

        }
    }
}

now its working ok

Update 2 : c++ sending command via Serial

    std::string input_command = "ON";
    //Creating a c string
     char *c_string = new char[input_command.size() + 1];
     //copying the std::string to c string
     std::copy(input_command.begin(), input_command.end(), c_string);
     //Adding the delimiter
     c_string[input_command.size()] = '\n';

// using this serial lib : https://github.com/manashmndl/SerialPort
   writeSerialPort(c_string, MAX_DATA_LENGTH);

Per the documentation of the AccelStepper’s runSpeed()
method:

  You must call this as frequently as possible, but at least once per
  step interval,

It appears the AccelStepper library is not compatible with blocking
code. Not a big deal, blocking code is almost always bad practice
anyway. However, Serial.readStringUntil() is a blocking function: it
will prevent the program from doing any useful work.

You have to read the serial port in a non-blocking fashion,
use the commands to set the motor speed, and always call runSpeed() as
frequently as possible.


What is the maximum length an Interrupt Service Routine? In general, what's the maximum length of instructions that can be included in an Interrupt Service Routine?

The docs say an ISR should be "as short and fast as possible", but that's bit vague.

For example, I have an ISR that gets called for each pulse on an motor's encoder.

void on_encoder_pulse(){
    encoder_change = true;
    count1 += 1;
    count2 += last_call;
    last_call = millis();
}

Will this run without interruption?

As already explained by jwpat7, interrupts are, by default, not
interruptible. Thus, if another interrupt fires while your ISR is
running, it will no be serviced until your ISR completes. This delay you
impose on other interrupts is called latency. So your question boils
down to “how much latency can the other interrupts tolerate”.

There is no simple answer: it all depends on the timing requirements
of whatever those interrupts are servicing. For example:

The millis() counter is updated by interrupts. Any latency longer
than 1024 µs (on the Uno) can make it loose tics.
If you are using the serial port to receive data, a latency longer
than one byte time (1040 µs at 9600 pbs, less at higher baud
rates) will make you loose data.
If you are using the Servo library, any interrupt latency will
create jitter in the drive signal, and at some point this may become
visible as mechanical jitter.

Then, if you really need a precise answer, you will have to check the
timing requirements of every piece of hardware and every library you
are using. And then check the latency already imposed by the ISRs in
those libraries, as your latency can come in top of that.

If your program relies on loop() looping fast enough, you should also
keep in mind that interrupts also slow that.


IMU (MPU9250) and Ticker on ESP32 I want to read the data from an IMU (MPU9250) periodically. To do that I use a ticker as shown in the following code:
#include <Ticker.h>
#include "MPU9250.h"

constexpr int SERIAL_BAUDRATE = 115200;
constexpr float SAMPLING_FREQUENCY = 1.0;

Ticker TimerIMU;
MPU9250 IMU(Wire, 0x68);

void readIMU()
{
    // read the sensor
  IMU.readSensor();
  // display the data
  Serial.print(IMU.getAccelX_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelY_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelZ_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroX_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroY_rads(),6);
  Serial.print("\t");
  Serial.println(IMU.getGyroZ_rads(),6);
}

void setup()
{
  // serial to display data
  Serial.begin(115200);
  while(!Serial) {}
  // start communication with IMU
  int retVal = IMU.begin();
  if(retVal < 0)
    Serial.println("IMU initialization unsuccessful: check your wiring or try resetting power to the sensor.");
   // start ticker
  TimerIMU.attach(1.0 / SAMPLING_FREQUENCY, readIMU);
}

void loop()
{
}

This approach does not produce the expected results: the IMU returns always the same values. Putting the readIMU function in the main loop and commenting the Ticker works well. I use an ESP32-WROVER.
Where is my error? Any suggestion would be appreciated.

readIMU() is called by the library from an ISR (Interrupt Service Routine). While the ISR runs, other interrupts cannot be handled. The IMU sensor works over I2C, which relies on interrupts being serviced. So, when initiating the communication inside an ISR, the transmission can never be finished correctly, since the needed ISRs are not executed. At least the library doesn't seem to block in that case, so the code runs, but the values are never updated.
You should not do interrupt dependent things inside of an ISR. Instead you can define a global flag variable, which you set inside the ISR. Then in your main code you just constantly check this flag and execute the ISR dependent code, if the flag is set. After the execution you reset the flag.
The response time is dependent on the speed, that your loop runs in. But this shouldn't be a problem here, since you don't have any other code in loop() and your frequency is just 1Hz, so a delay of a few microseconds should not be relevant.

Note, that using Serial is also interrupt dependent. So writing or printing to Serial inside an ISR is also not very good. Though you can get away with it, when you make sure, that you never send more data, than the Serial buffer can hold, and that you leave enough time between the interrupts for the actual transmission. Inside an ISR the printing and writing statements will just fill the buffer. The data will then gets send in the background via interrupts.


External Flash Memory File System I'm building a weather data collector and I want to be able to dump that weather data somewhere. I've considered the options, and since I'm going to be storing a fairly small amount of data (in the megabyte range) I don't want to use SD cards (also SD cards are expensive). I've heard of use of NAND flash memory chips (like the W25Q32), and I was hoping that I could possibly interact with them in a simple way (since most ways require writing to each individual address). Is there possibly a way to build a file system within one of these small flash memory chips and interact with them as simply as interacting with an SD card?

TLDR: I want to interact with a flash memory chip easily to store basic ASCII data

I don't think you need a file system: that is usually needed when you want to manage many files. Your weather data log sounds like a single file.

What you seem to need is to access EEPROM as a stream, exactly like you would for an open file. There are stream wrappers around some EEPROM libraries, e.g. this one for ESP. I suggest you check it out and see if you can adapt it to the EEPROM library you use.


Arduino Nano off 9V : is there any change to output? I'm building a test circuit on an Arduino Nano that consists of a simple 220 Ohm resistor and an LED on pin D2 which is routed back to GND (ground).

It's as simple as this:

It's running a very simple program to blink the LED on and off.  It all works while connected to the USB port.  I know the USB port provides 5V.

Now I want to run it my Nano and circuit from a 9V battery.  The datasheet says that you can run the Nano on 6V -12V by connecting it to pin 30 (VIN).  Of course, I know I'll have to add a line from GND back to the (common) battery ground also.

When I do that, the voltage on the OUTPUT pin (D2) will never be higher than 5V though, right?
I should not expect any change in output voltage even though I'm changing voltage that is powering the Nano, correct?

It looks like VIN connects to a LM2940, 5 volt regulator, so the voltage on the OUTPUT pin (D2) will never be higher than 5V.