what is the importance of the resistors that connect to push buttons ? can i replace them by wires? Please, iam a junior in arduino and i want to know what is the importance of the resistors that connect to push buttons? can i replace them by wires?
thanks in advance.

They are what is known as Pull-Up resistors.  The circuit will not work if you replace them with wires.  Not only that but you will short circuit the power supply when you press a button.

Why don't you want to use resistors?

The value is not important - you could use the same value as you are using for the LED if you don't have the 10k resistors shown in the drawing.

Having said that an alternative is to leave them out and instead activate the internal pull-ups within the processor on the Arduino:

pinMode(pin, INPUT);           // set pin to input
digitalWrite(pin, HIGH);       // turn on pullup resistors


Sending GPS data to computer via USB and then to iPhone app through Wi-Fi on LAN I was wondering how I would parse data from a GPS module from the Arduino to my laptop and from there send it to an iPhone app I'm building.

One idea I had was to have it print the incoming serial data to a terminal and save that to a text file, then send that file to the phone, although I'm not sure how to do that continuously and automatically or details such as overwriting each time or overwriting after the file reaches a certain size, etc.

Also I'm not sure on how to start sending that data over Wi-Fi to an iPhone on a local network using the laptop's Wi-Fi either.

Any suggestions or pointers in the right direction would be greatly appreciated. Thanks!

So the Arduino gets the data over serial from the GPS and passes it over serial or USB serial port to the PC.

PC is either configured to be a WiFi hub or is connected over Ethernet to a WiFi hotspot.

The PC runs a TCP server with software so that any data from the Arduino is passed to any connected clients.

The iPhone connects to the WiFi and opens a TCP socket to the server on the PC. The PC can then stream the data to the phone as it comes in (and you can pass data the other way if you need to). If the PC has a static IP address then it's a little simpler for to tell the phone where to connect to.

If you can find a TCP server program for the PC which sends data entered from the keyboard (there are plenty around) then you could cheat and configure the Arduino to pretend to be a USB keyboard rather than a serial port. That way the PC software is completely off the shelf.

At some point you'll need to parse the GPS output (NMEA at a guess) to extract the time, location, and anything else you want. This could be done at any point in the chain, wherever you feel most confident writing and debugging code is probably the best place to put it.


max7219 chained display showing mirrored text I'm using a max7219 like this one max7219. When I first tested my circuit, I used an 8x8 display and the code worked just fine. Now, after I modified the code with the one that can be found online at arduino code and changed the display with the chained one, the text appears to be mirrored on the matrix display.

.

Below, I'll attach part of the code. Please help me find the problem.

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface

#define MAX_DEVICES 4
#define CLK_PIN     13
#define DATA_PIN    11
#define CS_PIN      10

// Hardware SPI connection
MD_Parola P = MD_Parola(CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

void setup(void)
{
  P.begin();
  P.displayText("Hello", PA_CENTER, 0, 0, PA_PRINT, PA_NO_EFFECT);
}

void loop(void)
{
  P.displayAnimate();
}

Since version 3.0 MD_MAX72xx.h no longer supports that definition. Now the hardware type is defined as a parameter on creation (in the "Example" file you are using - not in MD_MAX72xx.h)

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
...
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

Note that I've changed the hardware type from PAROLA_HW to FC_16.


How to create a smooth change in voltage? We are given two voltages A and B between 0 and 5V.
So how do I generate a smooth/continuous analog change in
voltage from A to B in a predefined time? The current with that varying voltage is 1 ma or less. The output voltage value is described by a simple quadratic (aX^2)+(bx)+c, at time x seconds.

If that not possible using an Arduino - what is the nearest  solution to it? It seems that it would require an RC circuit?

When I mean smooth/continous I mean it doesn't move in "digital steps" or to use an analogy with resistance instead of voltage - it would be like the way resistance changes when a potentiometer is turned between two places, in a given time, by hand.

A potential solution would be to make a circuit that generate arbitrary voltage between 0 and 5v, some how, at a point in time. For each subsequent small change in time, the change in time is constant, generate the desired voltage from a sketch. If the change of time is small and constant, will putting in a high pass RC filter work? Though I'm not sure of a circuit that can create an arbitrary voltage, or arbitrary voltage resolution or how good the RC filter approximates the quadratic smoothness. I don't know the answer.

I'm not sure that there exists a perfect solution for what you want.  Generating the correct output voltage for time is easy.  Just keep track of time and use the formula you wrote to compute the correct voltage you should be at.  Then you can use a PWM output.  However, this isn't going to be perfect since it is made with pulses rather than a continuous output.  On the Uno the pulses are at 490Hz or 980Hz depending on which pin you use.  Use an RC filter and you can then make it continuous - when you tell it output 2.5V you get 2.5V rather than 0 then 5 then 0 then 5 in short bursts.  But, you're still going to get discrete steps based on the resolution of the ADC - for an Arduino Uno, it's 255 steps I believe.  You could get a separate DAC chip to increase this and can probably get enough steps that their small enough you won't notice.  Some versions of the arduino like the due have 12bit analog output and higher frequency, which should help.


Format hour and minute integers to HH:MM format (char*) In Arduino code, I'm calling the getTextBounds() and print() API methods on my TFT handler object which accepts char* parameters and I have two integers holding a specific time's hour and minute part, for example:

int _hour = 7;
int _minute = 30;

I need to construct a char* variable that holds this string: 07:30.
What is the simplest way to do that?

I tried this:

char* timestr = (_hour < 10 ? '0' : '') + _hour + ':' + (_minute < 10 ? '0' : '') + _minute;

But it gives me two kind of errors:

error: empty character constant
error: invalid conversion from 'int' to 'char*' [-fpermissive]

You don't want a char *, you want a character array, i.e. you have to
allocate the memory for the string, not only for a pointer. That being
said, you can build the string one character at a time like this:

char timestr[6];
timestr[0] = '0' + _hour / 10;
timestr[1] = '0' + _hour % 10;
timestr[2] = ':';
timestr[3] = '0' + _minute / 10;
timestr[4] = '0' + _minute % 10;
timestr[5] = '\0';

Then you can use timestr just as you would use a char*.

Edit 1: If you are not too short on RAM, you could allocate the string
statically, and have the C runtime initialize the characters ':' and
'\0' at program startup. Then you just have to set the four remaining
chars on each conversion:

static char timestr[] = "--:--";  // initialized only once, with template
timestr[0] = '0' + _hour / 10;
timestr[1] = '0' + _hour % 10;
timestr[3] = '0' + _minute / 10;
timestr[4] = '0' + _minute % 10;

Edit 2: Maybe the “simplest”, in the sense “closest to what you had
in mind”, would be to use a String object:

String timestr = String() + (_hour < 10 ? "0" : "") + _hour
    + ':' + (_minute < 10 ? "0" : "") + _minute;

You could print() that String directly, or retrieve the internal
char* with the c_str() method.

I added this method only for completeness. Although simple in the source
code, it would not be my first choice: it uses more memory, it is more
CPU-intensive and – what worries me most – it uses heap allocation,
which carries the risk of memory fragmentation.


Pro Micro Voltage regulator burned I'm using Arduino Pro Micro (5v version) in one of my project for my car. The car's 12V +ve connected to RAW input of ProMicro and everything seems to work perfectly until I crank the ignition of my car.
Here's what actually happened, my circuit works perfectly fine when car's ignition is in ON state. However, as soon as I started my car the voltage dropped from 12v to between 9-10volt and the LG33 (SMD voltage regulator) burned out. Now, I want a good solution as what should I do now?
I have already LM2596 DC 3A Step-Down regulator. So should I use that to step-down 12v to 5v OR is there anything else I can do which might be a better solution?

What happened was the ignition caused massive spikes on the 12V power. You require an automotive grade regulator that can cope with spikes in excess of around 70V or more.

Your best bet is probably a car USB charger adapter since they are cheap and easy to get hold of.


How can I move these global variables to be I'm taking a sample I found on the web about how to get ROS and arduino to communicated together over serial. I have the sample working and now I'm moving the idea of the sample into my OOP project and am running into some trouble.

My sketch works but when I move a certain global variable to a protected member it breaks my sketch.

How do I declare this global variable

ros::Publisher chatter("chatter", &str_msg);

as a protected variable

protected:
  ros::Publisher chatter("chatter", &str_msg);

without getting this error

expected identifier before string constant

sample .ino

/*
 * rosserial Publisher Example
 * Prints "hello world!"
 */

#include <ros.h>
#include <std_msgs/String.h>

ros::NodeHandle nh;

std_msgs::String str_msg;
ros::Publisher chatter("chatter", &str_msg);

char hello[13] = "hello world!";

void setup()
{
  nh.initNode();
  nh.advertise(chatter);
}

void loop()
{
  str_msg.data = hello;
  chatter.publish( &str_msg );
  nh.spinOnce();
  delay(1000);
}

ROSController class

#include <ros.h>
#include <std_msgs/String.h>

class ROSController {
  protected:
    ros::NodeHandle _nh;
    std_msgs::String str_msg;
//    ros::Publisher chatter("chatter", &str_msg);
    int _throttle;
    bool _is_on = false;
  public:
    void loop();
    ROSController();
    double* getAttitude();
    bool isOn() {
      return this->_is_on;
    }
    int getThrottlePerc() {
      return this->_throttle / ROSController::THR_MAX;
    }

    static const int THR_MAX;
};

const int ROSController::THR_MAX = 100;

ROSController::ROSController() {
  this->_nh.initNode();
//  this->_nh.advertise(chatter);
}

double* ROSController::getAttitude() {
  return new double[3]{0, 0, 0};
}

void ROSController::loop() {
//  str_msg.data = new char[] {"hello"};
//  chatter.publish( str_msg );
  this->_nh.spinOnce();
  delay(1000);
}

The problem you are having is you are trying to both define and declare a class member variable at the same time. You can't. Instead you need to split it:

protected:
    ros::Publisher chatter;

ROSController::ROSController() : chatter("chatter", &str_msg)
{
    this->_nh.initNode();
//  this->_nh.advertise(chatter);
}

That is, set up the variable as a protected member, then have the constructor call the constructor for you with the right parameters.

(I think that is the right syntax off the top of my head).


Arduino Uno - why doesn't memory leak crash the program? I wrote this test program:

void loop()
{
    digitalWrite(13,1);
    delay(300);
    digitalWrite(13,0);
    delay(300);
    void *a = malloc(10000000000000000000000000000000000000000);
}

Curiously, the LED keeps blinking and so it means the loops continues.

My question is how can it continue when it runs out of heap memory like that?

malloc() by itself generally doesn't crash a program.  It attempts to allocate the requested amount of memory, and if it can it will.  If it can't (there isn't enough memory available) then it won't allocate anything and will just return NULL.

By trying to allocate more memory than you have it will just fail every time and no memory will be allocated - thus you don't actually have a memory leak, so your program doesn't fail.

The main reason for crashing is a phenomenon called stack smashing where the memory area used by malloc() (known as the heap) and the memory area for the stack (used by local variables and for storing the contents of registers during function calls) collide with one another and one corrupts the other.  For instance, if the return address of the current function in the stack is corrupted, when the function finishes it will return to the wrong memory location and who knows what may happen then?  Wrong instructions will be executed for sure.

For instance, try this program out instead:

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

void loop() {
    char *a = (char *)malloc(10);
    if (a != NULL) {
        Serial.println("Allocated 10 bytes");
    } else {
        Serial.println("Allocation failed");
    }
}

If all goes well you should see lots of "Allocated 10 bytes" followed by some "Allocation failed".  Since the memory is now full there is a chance that it may now crash as the stack and heap collide - in which case you would expect to see the "Allocation failed" messages stop.


Use Higher Resistance Than Instructed in a Circuit I'm following the "Get Started with Arduino" Guidebook, and I'm at the part where pulse width modulation (PWM) is discussed.

The instructions say to create a simple circuit with a breadboard, red LED, arduino (connected at pin 9 and ground) and a 270 ohm resistor. My power source will be the usb connection.

I have a 510 ohm resistor.

May I use it instead?
In general, will using a resistor with a higher resistance than intended in a circuit fry the arduino?

Thanks very much for your help. I'm new to arduino and electronic circuits. I have a Uno R3.

The cases where using a higher value resistor will damage a circuit exist, but are a bit less usual than the cases where it may simply produce a weaker result than desired, or a different frequency response than desired.

The primary situations where you do have to watch out come about where "feedback" is used to adjust one thing in relation to something else, and so putting a larger resistor on the "sense" side of the circuit can cause the "output" to be too high.  Examples you might run into would be adjustable voltage regulators (obvious potential for damage with wrong output) and op-amps (higher than desired output, though more often distortion than damage).

It seems quite likely the the role of the resistor in your circuit is to limit the current through the LED - protecting that (and to a more vaguely best-practices degree, the ATmega pin) from damage.

For your needs it could be worth noting that a parallel combination of two 510 ohm resistors will give an effective resistance of half that, or 255 ohms.  This is very close to the design intent, so might be a decent substitution (cheap resistors have a larger tolerance for piece-to-piece variation of value than that anyway).

Normally I would say the desired 270 ohms feels a little small, and that I'd prefer to start with 330 ohms.  But if you do parallel two 510's, the 255 ohms would give just under 20ma of current if connected directaly across a 5v supply.  Given your LED will have some forward voltage drop (varies widely with color), and your Arduino pin a little of its own, the actual voltage and thus current will be less - as a guess the end result is likely to be in the 15ma range, and not unreasonable for many common LEDs.

Resistors would also be a fairly easy component to salvage out of old electronics - the leads will end up short, but other than that you basically just need to read the color code, and perhaps confirm the value after removal with a meter.

Ultimately though it is worth buying an assortment of resistors - the 1/4 watt size are generally preferred for breadboarding as the leads are the best fit.


Send serial commands through IDE while RX pin is in use This is really a two part question. I have an ESP8266 hooked up to USB. I have connected my LED strip (WS2812B LEDs) to the RX port, so I can control them individually and so on. I realised WiFi is a bit slow and will eventually crash the ESP8266 if I send enough requests, which is why I want to give serial a go.

If I open up the serial monitor, how do I send something to it, such as a color or 100 colors in one command? I'd assume Serial.read() inside a Serial.write() would display whatever I type in, but it doesn't do that. I can Serial.write() inside a loop, and it will display that.
Is something like this even possible? I'm looking for a way to send a lot of information (could be 100 colors (1 per LED)) as fast as possible. Speed is the key here.

Software serial is an option as well, as long as it's faster than WiFi.

Regarding “I have connected my LED strip (WS2812B LEDs) to the RX port”:  If you connect an LED strip to the RX pin, there's a good chance you won't be able to read serial data reliably on that pin, and may have trouble loading new sketches.  It makes sense to connect the LEDs to some pin other than RX.

Regarding “If I open up the serial monitor, how do I send something to it”:  Ordinarily, one uses the serial monitor to receive data from an attached MCU or to send data to the MCU. (An MCU is a microcontroller – eg an Arduino or ESP8266.)  In the sketch on the MCU, use Serial.write() to send binary data to the monitor, and Serial.print() to send text and formatted numbers to the monitor.

If you want to send serial data rapidly from your host computer to the MCU, write a C or Python (etc) program that opens a serial port, marshals the data, and sends it.  In the  sketch on the MCU, use Serial.available to test if characters are available to read, and Serial.read to read a character.  For faster transmission, you can send binary data instead of ASCII, but would need to read up on that before attempting it.

For fast data transmission, aim for either high data rates or strong data compression.  For example, you might make up a protocol that only sends colors for pixels that are going to change; or might have high-level commands that tell the MCU how to generate a set of data, via color end points, step rates, and numbers of steps.

In general, wifi data rates are somewhat higher than serial data rates.  If that is not what you are experiencing, perhaps review the article Found a way to upload data VERY fast by wifi from github.com/esp8266.

Edit 1:
Regarding “Nothing is displayed in the serial monitor” [from code like if (Serial.available()) { Serial.write(Serial.read()); }]:  I'm assuming that the sketch in use has a setup() routine containing a Serial.begin(somedatarate) statement, with the same data rate selected in the serial monitor as in the Serial.begin() statement.   I'm also assuming the sketch has a loop() routine containing the if (Serial.available()) { Serial.write(Serial.read()); } code.

I'm also assuming the sketch was properly downloaded, and then the serial monitor was opened, using the USB-serial port the ESP8266 is attached to, and then you typed some text into the text entry box of the serial monitor and pressed or clicked Enter to send the text to the ESP8266, with a proper setting for the end-of-line character.

If all those assumptions are correct, but nothing shows up in reply to the text you send, then it seems likely some hardware or software issue is occurring.  For example, when the Serial data structure is set up (when the sketch begins running) it might be selecting an incorrect Rx pin.  Or something may be loading down the Rx pin.  To find out if either of those is the case, use an oscilloscope (if you have one) to look at what's arriving at different ESP8266 pins when you send text from the  serial monitor.  If no scope, connect a 5K-10KΩ resistor to an LED and use that as a logic probe.  One end of the resistor connects to a probe; the other end goes to the LED anode; and the LED cathode is grounded.  Test if that's working by touching the probe to +3.3V.  When the probe appears to be working ok, use it to check for brief flashes of data at different Rx pins on the ESP8266 when you send data from the serial monitor.  If no data gets to the ESP8266, it can't echo it.  (Note, I'm not sure how your NodeMCU ESP8266 handles serial-via-USB data; my notion that serial data should be visible on some Rx pin might be wrong.)

If it appears data is getting to some pin but isn't showing up as available, you might try opening software serial on that pin.  Some examples appear in code in a serial monitor note at github.com/esp8266.  I don't know enough about NodeMCU / ESP8266 to say what to do if probing and software serial don't help.


Mega SPI communication changing between setup and loop I am attempting to use an arduino MEGA 2560 to control a digital potentiometer (AD5206), but I am getting some strange behavior. I have attached the CLK and MOSI pins (52 and 51, respectively) to an oscilloscope, and have run the following code:

#include <SPI.h>
void setup() {
    SPI.begin();
    SPI.transfer(5);
    delay(500);
}

void loop() {
    SPI.transfer(5);
    delay(500);
}

When I look at the signal, the transfer in the setup() looks correct (5V x 00000011), but then the transfer in the loop() looks like it's shifted by -5V (-5V x 11111100). Has anyone ever run into this? Is it possible for the MEGA to output a negative voltage?

No, there is no problem with SPI on the Mega. If there were it would have been noticed by now.
Instead it's either the way you are measuring it or your method of generating the SPI signals that are at fault (and since you won't show us your real code we can't help you with that).
This is a trace of your provided "code" with the delays reduced to allow easier fitting on a single trace:

Clock goes low when SPI.begin() is called. Then there are the successive transfers - the first being in setup() and the rest in loop(). As you can see they are all identical.


Using MULTIPLE shields on Arduino Uno R3 I'm very new to using Arduino!  I'll be using Ocean Controls KTA 259 thermocouple multiplexing shield AND a Sparkfun microSD shield on my UNO--to log temperature data for a study I'm doing.  The KTA 259 has a library and the integral SD library should work for the SD shield.
Q1:  I believe they physically connect no problem, but how can I be sure there are no pin conflicts, disastrous or otherwise?  In other words--what conditions MUST I avoid using shields and multiple shields?
Q2:  Can (or must) a single data pin be used by both shields, eg from thermo as output to SD as input, or does Arduino juggle all that?
Q3:  Can (or must) a single function, eg CS, be mapped onto the same pin on BOTH shields, or do they have to be separate allowing Arduino to handle that?
Thank you; I appreciate the help!

You will have to consult a source like this one: http://shieldlist.org
There are no simple rules for which pin conflicts are OK and which ones are not, it all depends on the concrete protocol (i.e. I2C is designed for all bus participants to share lines, while in SPI, each participant needs their own select line, while the other lines are shared).

In your concrete case, both shields you want to use are addressed by SPI, which means D13 (SCK) and D12 (MISO) are shared between the shields by design, while they MUST have different slave select pins. In your case, the SS pin for the microSD shield is fixed as D8, while the one for the KTA shield seems to be selectable, so either D9 or D10 should be OK.

Peripherals generally don't have facilities to become an SPI master, so all data has to be transferred through the Arduino.


HD44780 display incorrectly black-on-blue instead of white-on-blue I have a generic HD44780 compatible 16x2 LCD display, with an already soldered on PCF8574 module. Its backlight is blue, and the characters are supposed to be white (on blue).

It is connected to a generic "Lolin" ESP8266 module which is working fine and is not related to the problem, I hope.

Using the LiquidCrystal_I2C library available at https://github.com/lucasmaziero/LiquidCrystal_I2C, I uploaded the simple "Hello, World" sketch provided, and it works. Used the most current libraries and Arduino IDE as of 2019-03-20.

However, the text displayed is a very dim black-on-blue instead of a bright white-on-blue.

I do not have any clue on why it happens and how to fix it (and that's my question).

What I know is that if I somehow "glitch" the display (for example by disconnecting and reconnecting the power lead) it will sometimes display gibberish, but in a very clear white-on-blue, so I know the LCD hardware is not defective per se.

I also tried a few other libraries to the same effect: LiquidCrystal_PCF8574 and LiquidCrystal_I2C (the version available directly from the Arduino IDE, source at https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library)

Below, the example sketch used to generate the problem. Be aware it is for the first LiquidCrystal_I2C library I referred above, but with changes, works with the others I tried.

#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup()
{
  // initialize the LCD
  lcd.begin(); // Init with pin default ESP8266 or ARDUINO
  // lcd.begin(0, 2); //ESP8266-01 I2C with pin 0-SDA 2-SCL
  // Turn on the blacklight and print a message.
  lcd.backlight();
  lcd.setCursor(0, 0);

#if defined(ESP8266)
  lcd.print("ESP8266");
#else
  lcd.print("ARDUINO");
#endif

  lcd.setCursor(0, 1);
  lcd.print("Hello, world!");
}

void loop()
{
  // Do nothing here...
}

And a photo of the anomalous display. Turning the constrast potentiometer does not help.

This answer is just to complement @smajli's answers posted (and accepted) before.

The problem lies in that the contrast pin has to be fed negative voltages when the module is powerered via a 3.3V supply to be able to show text in the correct white-on-blue setting and not on the faint black-on-blue.

@smajli correctly showed how the negative voltage may be generated from the normal positive supply and a pulse generator. However, in my scenario, the pulse generator was connected to the +3.3V rail instead of +5V and the pulses where generated via the ESP8266's PWM feature. Using a duty cycle of 50% it generates about -2V. I'll not reproduce his schematic here, though, but below is a photo of it assembled and in action.

The updated code is exactly the same, with only the PWM generation added inside the setup() function:

  pinMode(D8, OUTPUT);
  analogWrite(D8, 512);   // 10-bit!

Finally, the photo below illustrates the final result.

Again, thanks again to @smajli for the previous insights and answer.

P.S.: Keen readers will notice the module used now is NOT the same used when I asked the question originally. It is another generic HD44870 module, but without the I2C interface, working in 4-bit mode. However, the exact same problem (black-on-blue text) occurs when the contrast pin is set to anywhere between +3.3V and GND and is promptly solved when using negative voltage.


Nano v3 dual power source use & detection I would like to run a Nano 3.0 from both the VIN (mains power supply 7V) and USB power (backup). I understand it selects the highest voltage and switches to VIN at 6.6V. However I am unsure of the following:

How is it possible to detect which power source is being used?
How is it possible to detect if the source has been switched?
How is it possible to detect if the power source NOT in use has been disconnected.

To check, if VIN is connected, you can connect VIN through a voltage divider to a digital pin (as suggested in the comment of Code Gorilla). For checking the USB connection you would have to connect VUSB to another digital pin. Since VUSB is not exposed on a pin, this could be difficult to do, but it is possible.

But note, that this would also show a disconnect, when the voltage drops (e.g. empty battery). When you want to detect real mechanical disconnects, you need a power jack with an extra switch integrated.

Let's take a look at the schematics: Arduino Nano 3.0 Schematics

The selection of voltage supply is done by the diode D1. If the voltage resultung from the VIN regulator is higher than VUSB - diode_voltage_drop, the diode is closing and the power comes from VIN. If the voltage resulting from VIN is lesser, the current can flow from VUSB. How much power is really drawn from USB depends on the voltage difference.

So - to detect which source is actually used - you can measure the voltage on the diode with an analog measurement with the ADC or through connecting for example a comparator and using a digital pin.

Note that the voltage on the diode can be positive or negative, depending on which source is used.


WiFi.begin doesn't work with ArduinoJson's const char* output I'm using ArduinoJson to parse a file full of JSON strings that contain the SSID and password for the registered networks. I have a little web interface that runs in soft AP mode so you can scan for networks and add them to the file. Adding networks to the file works fine, but reading them back and using them as input for WiFi.begin doesn't work. It moves to status code 1, which means it failed to find a network with that SSID.

I have compared the value of the result of const char* ssid = networks[network]["ssid"]; with const char* _ssid = "MySSID"; using strcmp and it returns 0, so I can't figure out why it's not working. It works if I replace networks[network]["ssid] with my SSID (though I need to replace the password with the string literal as well, otherwise it stays on status code 6, disconnected).

I can't figure out what it is about ArduinoJson, but it seems that the result of grabbing a string doesn't return a string that is formatted correctly for WiFi.begin, but it satisfies strcmp?

Edit:
I modified the code quite a bit in an effort to get it to work. I am no longer passing the ArduinoJson object, I'm now passing a struct with the data, and it still doesn't work. Is this the work of some advanced c++ constants/pointers stuff that I don't seem to understand?

main.cpp:

#include <ArduinoJson.h>
#include <ESPAsyncWebServer.h>
#include <ESPmDNS.h>
#include <SPIFFS.h>
#include <vector>
#include <elapsedMillis.h>

#include "config.h"
#include "restserver.h"
#include "scanwifiserver.h"

AsyncWebServer *Server = new AsyncWebServer(80);

ScanWifiServer *scanWifi;
RestServer *restServer;

struct Network {
    const char* ssid;
    const char* password;
};

std::vector<Network> readAP(fs::FS &fs) {
    //fs.remove("/ap.txt");
    File file = fs.open("/ap.txt");
    std::vector<Network> networks;
    if (!file) {
#ifdef DEBUG
        Serial.println("Failed to open file for reading");
#endif
        return networks;
    }

    while (file.available()) {
        DynamicJsonDocument n(JSON_CAPACITY);
        auto s = file.readStringUntil('\n');
        deserializeJson(n, s);
        struct Network network = {n["ssid"], n["password"]};
        networks.push_back(network);
        Serial.println(networks.back().ssid);
    }

    file.close();
    return networks;
}

void setup() {
#ifdef DEBUG
    Serial.begin(BAUDRATE);
    delay(2000);
#endif

    SPIFFS.begin();
    auto networks = readAP(SPIFFS);
    if (networks.size() > 0) {
        Serial.println("Networks:");
        int network = 0;
        Serial.println(networks.size());
        while (WiFi.status() != WL_CONNECTED && network < networks.size()) {
            const char* ssid = networks[network].ssid;
            const char* password = networks[network].password;
            Serial.printf("%s, %s\n", ssid, password);

            WiFi.begin(ssid, password);

            while (WiFi.status() != WL_CONNECTED) {
                if (WiFi.status() == WL_CONNECT_FAILED || WiFi.status() == WL_NO_SSID_AVAIL)
                    break;
                delay(500);
                Serial.print(WiFi.status());
            }
            Serial.println("");
            network++;
        }
        if (WiFi.status() == WL_CONNECTED) Serial.println("Connected");
        else networks.clear();
    }
    if (networks.size() == 0) {
        Serial.println("Starting ScanWifiServer");
        WiFi.mode(WIFI_AP);

        scanWifi = new ScanWifiServer(Server);

        Server->begin();

        MDNS.begin("grow");
        MDNS.addService("http", "tcp", 80);
    }
}

void loop() {}

I found the solution myself. I switched from using struct Network network = {n["ssid"], n["password"]}; to declare the struct and const char pointers to using char arrays and strcpy

struct Network network;
strcpy(network.ssid, n["ssid"]);
strcpy(network.password, n["password"]);

Seems like the pointers were getting freed or something right at the same time that I tried to use the value to connect to the network?


LED bar graph script not working I have LED bar graph on pins 2-11. Eventually I want to use a voltage divider to figure out the amount of voltage left in a power supply. Currently, this script should set the number of LEDs on the bar graph based on round((v_actual/v_reference)*10), I am just using some placeholder numbers in the mean time to test this portion of the script e.g. v_actual of 5 and v_reference of 10. However, the convert variable keeps printing 0. I've checked that the other variables were passing and they are. What is the issue here?

#include <Wire.h>

int ledBarNum = 10;    // # of leds
int vref = 10;     // max voltage of power supply

void setup(){
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}

void loop() {

  ledBarSetup(5);
}

void ledBarSetup(int v) {

  // logic vref=8; vactual or v = 4; (4/8)*10 = 2
  // e.g. number of leds we need to light up to represent the total amt left

  Serial.println(v);
  Serial.println(vref);

  int convert = round((v/vref)*10);

  Serial.println(convert);

  ledBar(convert);

}

void ledBar(int n) {

  int startingPin = 2;

  for (int thisPin = 2; thisPin < ledBarNum; thisPin++) {

    if (thisPin <= n) {

      digitalWrite(thisPin, HIGH);

    } else {

      digitalWrite(thisPin, LOW);

    }

  }

}

Both v and vref are integers, which means that integer division will be performed. if v is ever less than vref then the result will be 0. Multiply first, then divide.


Digital Read Serial tutorial - calculating the resistor value The Arduino Digital Read Serial tutorial guides you through the wiring of a simple button. My questions are centered around the resistor.

Why is the resistor necessary?

I think I understand this, but correct me if I am wrong. To ensure that the input pin reads a low signal, and does not float, we should connect the pin to ground when the button is not pushed. When the button gets pushed, we will have a 5V signal flowing to both the pin and to ground. Kirchhoff's voltage law states that total voltage in closed loop must equal zero, so we have to deal with this 5V that is flowing directly to ground. That is why we put a resistor between the button and ground.

How was the resistor value chosen?

This is what I am unclear on. Ohm's law states that...

resistance = voltage / current

This is a 5V supply and the Arduino Uno spec says that the pin provides 40 mA of DC current. So..

resistance = 5V / 0.04A = 125 Ohms

In the Digital Read Serial tutorial, why do we have a 10K Ohms resistor? That is way overkill, right? Which leads to another question: Can you ever put too much resistance in place, if your only goal is to obliterate voltage?

Thanks in advance for any feedback!

You're very close. The resistor is there to act as a pull down resistor; If the input pin is floating it is just an antenna picking up random static. The key is that when positive is supplied (by pressing the button) the positive source needs to "overwhelm" the pull down resistor so that the input pin reads positive.

If there were no resistance, than the input pin would be reading in the middle of a direct path that does not favor positive or negative. Asside from the direct short that would be occurring, Which state the arduino would read I suspect would either be random or some property of the power supply; It would probably still read ground.

With the resistor, the signal is read directly connected to positive, before the load resistance. This way it will be sure to get a HIGH signal.

The exact size of the resistor is of little consequence. Too small and you waste current, but too much resistance is effectively just disconnecting ground again. There is a very wide range of values that will work fine between those.

I would like to note that when an arduino pin is set to input mode, it will effectively supply no current. It can be moddeled is being in series with a 100 megaOhm resistor. see http://arduino.cc/en/Tutorial/DigitalPins
for details.


Pins are not switching I am trying to make pins 13, 12, 10 and 9 to switch between high and low. That is, when pin 13 is high, pin 12 should be low, then pin 10 should be high and pin 9 should be low.

Code:

 unsigned char driver[4] ={13, 12, 10, 9};
 String mystring = "";
 void setup() {
   // put your setup code here, to run once:
   Serial.begin(9600);
   for(int i = 0; i < 4; i++){
     pinMode(driver[i], OUTPUT);
   }
 }

 void backward(){
   digitalWrite(driver[0], HIGH);
   digitalWrite(driver[1], LOW);
   digitalWrite(driver[2], HIGH);
   digitalWrite(driver[3], LOW);
 }

 void forward(){
   digitalWrite(driver[0], LOW);
   digitalWrite(driver[1], HIGH);
   digitalWrite(driver[2], LOW);
   digitalWrite(driver[3], HIGH);
 }

 void STOP(){
   digitalWrite(driver[0], LOW);
   digitalWrite(driver[1], LOW);
   digitalWrite(driver[2], LOW);
   digitalWrite(driver[3], LOW);
 }

 void loop() {
   // put your main code here, to run repeatedly:
   while(Serial.available()){
     delay(10);
     char mychar = Serial.read();
     if(mychar == '\0')
       break;
     mystring += mychar;
   }

   if(mystring == "F" || mystring == "f"){
     forward();
     mystring = "";
     Serial.println("moving forward!");
   }

   else if(mystring == "B" || mystring == "b"){
     backward();
     mystring = "";
     Serial.println("moving backward!");
   }

   else if(mystring == "S" || mystring == "s"){
     STOP();
     mystring = "";
     Serial.println("stopped!");
   }

   else
     mystring = "";
   }

When I test it, there is no switching, that is when moving backward, pin 13 is high throughout, pin 12 is low throughout, pin 10 is high throughout, and pin 9 is low throughout

What line ending are you using in your IDE? Because if it is other than 'no line ending', you are also sending a new line, carriage return or both. Those control caracter get included in mystring.

Better to be safe and filter out control caracter. Try this:

String mystring = "";

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

void loop() {

  while (Serial.available()) {
    delay(10);
    char mychar = Serial.read();
    if (mychar == '\0')
      break;

    if (isAlpha(mychar)) {
      //  Doesn't include control caracters in mystring
      mystring += mychar;
    }
  }

  if (mystring != "") {
    Serial.print("***"); Serial.print(mystring); Serial.println("***");
    if (mystring == "F") {
      Serial.println("mystring is equal to 'F'");
    } else {
      Serial.println("mystring is not equal to 'F'");
    }
    mystring = "";
  }
}


Arduino stacking wifi and gsm shield I'm fairly new to this and I need some help before I buy anything...

If I understand correctly I can buy an arduino, couple of shields and just stack them one onto another if they are compatible...

I'll be doing some work with an arduino and I would need both WiFi and GSM shields but I'm not sure if they're compatible... On the arduino.cc I saw that they both use pin 7 (GSM as modem reset and WiFi as "handshake")

Is there any way I can use both of the shields even though they use the same pin?

Thanks

You can still use both of them although you'll need to buy another piece to make it work.

This is called the Go-Between Shield and it basically lets you re-route a pin to a different one.  You will need to change the pin number in your code to the one you re-assign that signal to but it will still work.

The signals you listed that go on that pin are very incompatible, as in if you try to do it, you'll have problems.  Every time your Wifi shield will try to connect to something, your GSM shield will reset.


None of the pins work as inputs I’m using an Arduino-uno
I'm trying to read an PWM signal being output by pin 6.
I'm attempting to read it with pin A0.
5 volts are being supplied from pin 6 to a 300 ohm resister in series with one led.
This circuit returns to the analog input pin A0.
It'll admit it's a strange set up and I was told to use a pass through filter to read the signal.
At this point I'm not concerned with whether the program reads the right values,
so despite the code involving the serial monitor I'm just trying to figure out why the led won't turn on anymore.
As I stated in the sketch, this exact set up was working fine yesterday. The led was on and (accurate or not) there were consistent values being printed to the serial monitor.
I'm trying to figure out now what changed after I unplugged it last to create a now open circuit.

```

void setup() {

  Serial.begin(9600);
  pinMode(6, OUTPUT);
  // I  also tried setting the A0 pin as an input even though I thought you didn't have to and it didn't change anything.

}

void loop() {

  analogWrite(6, 255); // This pin is working as an output, I tested it to ground and led lights.

  int value = analogRead(A0); // I realize inputs are typically used for things like potentiometers
                              // But just as an example the LED should still turn on when connected here, correct?
                              //And it did the first few times I did it... maybe that was the problem?

  Serial.println(value);  // This was  all working previously. It just randomly stopped.
                          // Now this just prints random numbers and the circuit remains incomplete.
                          // Even if the input pins are not supposed to be used with 5 volts, Why was it working before then...
                          // ALSO it does not matter which pins you use for what...
                          // No current is running through the digital inputs with digital output set to HIGH.
                          // And No current runs through the analogInput pins when analogWrite is set to 255.
                          // Once again, I apologize if my terminology is off.

}
```

This is what I did to trouble shoot:
With the same sketch running on the board...
I connected a jumper from pin A0 to ground and the serial monitor switched from a bunch of random values to a solid 0. So it recognizes input still... in a sense.
Then I modified the sketch...
void setup() {

Serial.begin(9600);
pinMode(6, OUTPUT);
pinMode(8, INPUT);

}

void loop() {

// now I'm attempting to read a digital signal with the same circuit...
// Pin 6 is connected to a 300 ohm resistor in series with an led which returns to pin 8.

digitalWrite(6, HIGH);

int value = digitalRead(8);

Serial.println(value);

}

This gave the same result. The led wont turn on anymore unless the circuit ends are connected from a voltage source to ground.
Previously, any pins configured as INPUT would not only read consistent values but also complete the circuit, turning the led on.
Now the pins only recognize zero volts and do not complete any circuits. You can't even use a simple potentiometer if you wanted.
Each pin that can be configured as an INPUT acts the same way.
The only thing I did between the times when it was working and wasn't was unplug and plug in the board...

Sounds like there's a basic misunderstanding here.
Setting a pin as "output" mean it'll either supply +5V ("HIGH") or 0V ("LOW"). Both those states are considered "outputs", and the pin can source or sink current in those states. When driven "LOW", the circuit does "input" current to the chip, but that's not what "input" usually means.
"Input" means you can use the pin to read the voltage applied to the pin. When connected to a PWM source, this might manifest as the pin quickly switching between "1" / "HIGH" / "+5V" and "0" / "LOW" / "0V".
Normally, you would use the "input" mode to read things like switches, or potentiometers on the analog input pins.
Your desired use of "current input" pins will require you to configure the pin as "output", and then set it to "LOW", which will make it able to sink current.


Problem with a seven segment display. The segments blink then turn off I can't figure it out what is the problem with my circuit, the segments turning on for sec and then they are turning off for good.

I tried to connect to GND instead of the 5 V but then, nothing happened.

My code:

void setup() {
  for (int pin = 2 ; pin < 9 ; pin++){ // setup pins 2 – 8 to be output
    pinMode(pin, OUTPUT);
  }

  for (int pin = 2 ; pin < 9 ; pin++){ // turn on pins 2 - 8
    digitalWrite(pin, HIGH);
  }
}

void loop(){}

Working simulation demo

The first thing to understand is how to connect the 7 segment display to your Arduino. The common anode pin connects directly to 5VDC. Each "segment" connects to the Arduino through a current limiting resistor (1k ohm is a good value to start with).

To turn a segment on, you supply a ground to it (through the resistor of course). Change: digitalWrite(pin, HIGH) to: digitalWrite(pin, LOW) in your sketch to turn on the segments.

I'm sure there are plenty of tutorials on the internet showing one resistor on the common anode input, but that is not the correct way to drive the display. Think about what happens when you display the number 1 VS the number 8. Changing the number of segments drawing power from the single resistor will vary the intensity of the display. The number 1 will be far brighter than the number 8.


Remotely uploading code to an Arduino board over the internet I recently used Particle Photon that allows me to upload firmware (.bin file) remotely over the internet.

I would like to use something like this for my Arduino but I cannot find anything like that. Does anyone know any possible way to upload firmware to my Arduino board remotely connected to internet via Ethernet shield of any WiFi module?

You can upload to your Arduino board over Ethernet if you flash it with a special bootloader named Ariadne.

You will need an Ethernet module or shield that uses the W5100, W5200, or W5500 Ethernet controller chip. You can not use the ENC28J60 Ethernet controller with Ariadne.

You will need an ISP programmer to burn the Ariadne bootloader to your Arduino board. If you don't own an ISP programmer, you can use a spare Arduino board as an "Arduino as ISP" programmer. If you're going to purchase an ISP programmer, I recommend the 6 pin USBasp. The USBasp works well with the Arduino IDE and is very reasonably priced. You can buy them on eBay.

A description of how the Ariadne upload over Ethernet process works:

Compile the sketch you want to upload.
Use avr-objcopy to convert the .hex file of the sketch generated from the Arduino IDE compilation into a binary (.bin) file.
Reset the Arduino board to activate the bootloader code. You could do this by pressing the reset button on the board but the need to have physical access to the board negates much of the advantages of uploading over Ethernet. For this reason, the upload will typically be accomplished by sending a command to your Arduino board which triggers the application to reset the microcontroller by activating the watchdog timer and then allowing it to time out. There is a library named EthernetReset bundled with the Ariadne hardware package for this purpose, but you can easily implement your own solution if you have other needs.
Start a TFTP upload of the .bin file to the IP address of your Arduino board within the 10 seconds that the bootloader is activated after the reset. The upload doesn't need to finish within the 10 second window, it only needs to start.

You can get the Ariadne bootloader, as well as detailed instructions, here:
https://github.com/loathingKernel/ariadne-bootloader


Virtual analog inputs? Possible? Just wondering whether it is possible to create 'virtual analog' signals, I am designign a system that uses a tank level sensor (pressure transducer); the component has not yet arrived and I am expecting it in a few weeks.

Is there any way to simulate the signals it would spit out, using some sort of GUI where I can physically control the 'virtual' tank level?

I'm thinking something along the lines of Wonderware's Intouch?

Would appreciate the help! Thanks

You don't specify the sensor you're trying to emulate, so we can't tell you exactly how to do it.

The obvious hardware approach would be a potentiometer.

You could also do it in software by writing a function to get the value, and temporarily replacing its implementation with one which generates random values, or reads values from a serial port, or reads them in order from a hard-coded array, or calculates them according to the time, or whatever you want.


smart coding possible? Is there a way to clean up this code...or do some smart coding?

In this example I use 6 relays, in the final code it will be 10.

Also I now use 5 switches and that will be 8, each with an own led. Now I only stated 1 led.

The code reads a button, and a few relays will get a signal. Also the buttonled will go on.
I will add more cases later. But I was wondering, is it possible/easier/just another way of writing the high/low to the relays and leds.

Can I somehow combine the LOWs or HIGHs within a case?

int relay1 = A5;
int relay2 = A4;
int relay3 = A3;
int relay4 = A2;
int relay5 = A1;
int relay6 = A0;

int led1 = 3;

int sw1 = 5;
int sw2 = 6;
int sw3 = 7;
int sw4 = 8;
int sw5 = 9;

int sw1Status, sw2Status, sw3Status, sw4Status, sw5Status;
int order = 1; // default is to set all relays off.

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

  pinMode(led1, OUTPUT);

  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  pinMode(relay5, OUTPUT);
  pinMode(relay6, OUTPUT);
  // input pull-up, so default state of buttons is HIGH.
  pinMode(sw1, INPUT_PULLUP);
  pinMode(sw2, INPUT_PULLUP);
  pinMode(sw3, INPUT_PULLUP);
  pinMode(sw4, INPUT_PULLUP);
  pinMode(sw5, INPUT_PULLUP);

}

void loop() {

  // read the buttons status
  sw1Status = digitalRead(sw1);
  sw2Status = digitalRead(sw2);
  sw3Status = digitalRead(sw3);
  sw4Status = digitalRead(sw4);
  sw5Status = digitalRead(sw5);

  if (sw1Status == LOW) { // if button 1 pressed
    order = 2; // go to case 2
  }
  if (sw2Status == LOW) {
    order = 3;
  }
  if (sw3Status == LOW) {
    order = 4;
  }
  if (sw4Status == LOW) {
    order = 5;
  }
  if (sw5Status == LOW) { // button 4 toggle
    if (order != 7) { // if order is not equal 5 turn on relay 1 & 4
      order = 6;
    }
    else { // else go to case 1, which will turns off all relays
      order = 1;
    }
  }

  switch (order) {
    case 1: // if order equals 1
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, LOW);
      digitalWrite(relay4, LOW);
      digitalWrite(relay5, LOW);
      digitalWrite(relay6, LOW);
      digitalWrite(led1, LOW);
      break;

    case 2: // if order equals 2
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, HIGH);
      digitalWrite(relay4, LOW);
      digitalWrite(relay5, HIGH);
      digitalWrite(relay6, LOW);
      digitalWrite(led1, HIGH);
      break;

    case 3: // if order equals 3
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, HIGH);
      digitalWrite(relay3, LOW);
      digitalWrite(relay4, HIGH);
      digitalWrite(relay5, LOW);
      digitalWrite(relay6, HIGH);
      digitalWrite(led1, LOW);
      break;

    case 4: // if order equals 4
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, HIGH);
      digitalWrite(relay3, HIGH);
      digitalWrite(relay4, LOW);
      digitalWrite(relay5, LOW);
      digitalWrite(relay6, LOW);
      digitalWrite(led1, LOW);
      break;

    case 5: // if order equals 5
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, LOW);
      digitalWrite(relay4, HIGH);
      digitalWrite(relay5, HIGH);
      digitalWrite(relay6, HIGH);
      digitalWrite(led1, LOW);
      break;

    case 6: // if order equals 5
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, LOW);
      digitalWrite(relay3, HIGH);
      digitalWrite(relay4, HIGH);
      digitalWrite(relay5, LOW);
      digitalWrite(relay6, LOW);
      digitalWrite(led1, LOW);
      break;

    default: // if none of above cases is valid go to case 1
      order = 1;
      break;
  }
}

If all are handled the same and they don't have individual names, arrays and for loops are what you are looking for.

const byte relayPins[] = { A5, A4, A3, A2, A1, A0};
const byte ledPin = 3;
const byte swPins[] = {5, 6, 7, 8, 9};

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  for (const byte relayPin: relayPins) pinMode(relayPin, OUTPUT);
  for (const byte swPin: swPins) pinMode(swPin, INPUT_PULLUP);
}

Even arduino C++ nowadays understands the foreach syntax.

BTW: for your final pin count you'll need other/additional hardware. Either a Mega or shift registers or port expanders.


SMS in modem's memory I am working on SMS communication with my phone and Arduino. My intension is simple. When somebody send an SMS, the Arduino should read a text file located on my server and forward the content to the same number.

The problem here is, when I send an SMS to my Arduino, which is waiting for my message, it does not read my message. But when I separately run this example code, I see my SMS is received. It means my SMS is already present in the modem memory. But why does this happen? How to solve this? Here is my code:

// libraries
#include <GSM.h>

// PIN Number
#define PINNUMBER ""

// APN data
#define GPRS_APN       "GPRS_APN" // replace your GPRS APN
#define GPRS_LOGIN     "login"    // replace with your GPRS login
#define GPRS_PASSWORD  "password" // replace with your GPRS password

// initialize the library instance
GSMClient client;
GPRS gprs;
GSM gsmAccess;
GSM_SMS sms;

// URL, path & port (for example: arduino.cc)
char server[] = "yourdomain.com";
char path[] = "/current.txt";
int port = 80; // port 80 is the default for HTTP

char k[30];
char z = '*';
int s=0;
String place;
char remoteNum[20];  // telephone number to send sms

void setup() {
    // initialize serial communications and wait for port to open:
    Serial.begin(9600);
    while (!Serial) {
        ; // wait for serial port to connect. Needed for Leonardo only
    }
    Serial.println("SMS connected");
    // connection state
    boolean notConnected = true;
    while(notConnected) {
        if((gsmAccess.begin(PINNUMBER)==GSM_READY) &
           (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY))
            notConnected = false;
        else {
            Serial.println("Not connected");
            delay(1000);
        }
    }
    Serial.println("GPRS connected...");
    Serial.println("Server Connecting.");
    // if you get a connection, report back via serial:
    serverr();
}

void loop() {
    if (sms.available()) {
        Serial.println("Message received from:");
        sms.remoteNumber(remoteNum, 20);
        Serial.println(remoteNum);
        sms.flush();
        Serial.println("MESSAGE DELETED");
    }
}

void smss() {
  // I just want phone number
    if (client.available()) {
        char c = client.read();
        //***************************************************
        //       Filtering a specific message
        //**************************************************
        if (z==c) {
            s=1;
        }
        if(s == 1) {
            int i=0;
            k[i] = c;
            i=i+1;
            // Serial.print(k);
        }
        place +=k;
        //Serial.print(place);
    }
    //***************************************************

    if (!client.available() && !client.connected()) {
        sms.beginSMS(remoteNum);
        Serial.print("Place =");
        Serial.print(place);
        sms.print(place);
        sms.endSMS();
        sms.flush();
        Serial.println("MESSAGE DELETED");
        Serial.println();
        Serial.println("disconnecting.");
        client.stop();
        // do nothing forevermore:
        for(;;)
            ;
    }
}

// if you didn't get a connection to the server:
// Serial.print(server);

void serverr() {
    if (client.connect(server, port)) {
        client.print("GET /current.txt");
        Serial.print("GET /current.txt");
        client.println(" HTTP/1.1");
        Serial.println(" HTTP/1.1");
        client.println("Host: www.yourdomain.com");
        Serial.println("Host: www.yourdomain.com");
        client.println("User-Agent: Arduino");
        Serial.println("User-Agent: Arduino");
        client.println("Accept: text/html");
        Serial.println("Accept: text/html");
        client.println("Connection: close");
        Serial.println("Connection: close");
        client.println();
        Serial.println();

        Serial.println("\nCOMPLETE!\n");
        //client.stop();
    } else {
        Serial.println("connection failed");
        Serial.println("\n FAILED!\n");
    }
}

I see one problem with the global structure of your program; everytime loop() is run, it:

checks if an SMS is present, and gets the originating phone number if present, otherwise it just goes on, ie smss() function returns without modifying remoteNumber
send an SMS to remoteNumber

One problem here is that your loop() will repeatedly try to send an SMS to the same remoteNumber even if no SMS was received; actually, to solve this issue, you should modify smss() to:

either wait (forever) for an SMS to be received and return only in this situation
or return a value (eg bool) that indicates whether an SMS was received or not; then an SMS should be sent if and only if an SMS was just received.

Here is an example:

void setup()
{
    GSM and GPRS initialization
    Connection to server
}

void loop()
{
    if (smss())
    {
        Reading the txt file content in server

        sms.beginSMS(remoteNum);
        sms.print(txtMsg);
        sms.endSMS();
    }
}

bool smss() // I just want phone number
{
    if (sms.available())
    {
        Serial.println("Message received from:");
        sms.remoteNumber(remoteNum, 20);
        Serial.println(remoteNum);
        sms.flush();
        Serial.println("MESSAGE DELETED");
        return true;
    }
    return false;
}

Note that this code does not integrate error support as it should; indeed sms.remoteNumber() may return error codes (any value >1), in which case you should consider no SMS was received at all.


Multiple void loops with ESP8266 I want to run multiple sketches on one sketch. I use the method of multiple void loops. It works but esp8266 take a lot of time to execute commands.

void Setup()
 {
  setup1();
  setup2();
 }
void loop()
 {
  loop1();
  loop2();
 }

Is there any method to avoid that ?

If the setup() or loop() functions call delay() then of course that will delay getting to the next function and will slow down the whole process.

The only way to deal with that is to rewrite the code, combining what you're calling and fixing it so that it takes into account the other work it needs to do.

Same thing if you call any blocking functions, like reading from Serial until you get a newline.

If that's not the case... well, the ESP8266 is a small, not particularly fast processor. If there are no delays or blocking functions then your code is running as fast as your code might run and you'll just have to live with it.


Adafruit Circuit Playground Express interrupt not working I have interrupts attached to pins 4 and 5 which correspond to the left and right inbuilt buttons on the circuit playground express (https://learn.adafruit.com/adafruit-circuit-playground-express/pinouts). For some reason the right button interrupt works perfectly however the left interrupt doesn't even trigger. Here's the code:

#include <Adafruit_Circuit_Playground.h>
#include <Adafruit_CircuitPlayground.h>

volatile bool leftState = false, rightState = false;

void left()
{
    if (CircuitPlayground.leftButton())
        leftState = !leftState;
}

void right()
{
    if (CircuitPlayground.rightButton())
        rightState = !rightState;
}

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

    attachInterrupt(digitalPinToInterrupt(4), left, CHANGE);
    attachInterrupt(digitalPinToInterrupt(5), right, CHANGE);
}

void loop()
{
    Serial.print(leftState);
    Serial.print("\t");
    Serial.print(rightState);
    Serial.print("\n");
}

Pin 4 on Zero can't be used with attachInterrupt. It is pin PA08 of the SAMD21 and this has NMI as interrupt control function in EIC and can't be used as EXTINT.

Adafruit Circuit Playground maps PA28 to pin 4, but the description of the pin is left as for Zero and doesn't declare interrupt capability.

In file arduino/hardware/samd/1.6.21/variants/circuitplay/variant.cpp change the line for pin 4 to

  { PORTA, 28, PIO_DIGITAL, (PIN_ATTR_DIGITAL), No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_8  },                           // GPIO D4 / Left Button

Packages are located in ~/.arduino15/packages/ on Linux and %userprofile%\AppData\Local\Arduino15\packages\ on Windows (AppData is a hidden folder).

Warning: In variant.cpp the overview comment's table describes Zero, not Circuit Playground.

Note: It is not beneficial to read a button with interrupt. You can only set some flag in interrupt and then handle it in the loop(). But then you can directlly check in loop the state of the pin, because it will be active many loops even if the user pushes it for a short time.


Design vehicle tracking device I want to create an Arduino based vehicle tracking device which will be moved into a production board without Arduino later. Right now I have a few questions:

What GPS module should I use for a best result (little time to fix from a cold start and high accuracy locations)? It will be good if support GLONASS. I want to detect when the car is turning (using HMC5983). I've bought Ublox NEO-6M GPS module and tested it into the car, but it cannot find a location.
What MCU I should buy? I also want to communicate with OBD II port of vehicle over the CAN protocol (using MCP2551 + MCP2515). For now i choose ATMega328.
How to power all elements ?

PS: Data from the vehicle and the GPS locations will be send over GPRS with SIM800l module.

Cheers

There are some SIMCOM modules with GPRS + GPS, for example: SIM968

In addition to GPS, it also supports GLONASS/Galileo/QZSS.

As for the MCU, you will need something more powerful than ATMega328, because 2KB RAM is not enough for multi-threading + GPS code + GSM/GPRS code + CAN + etc. Also it hasn't CAN peripheral. You will need MCU with ARM core. From Arduino line, Arduino Due looks suitable: has 96KB RAM, multiple HW serials, CAN. There is also compatible CAN library here. Also worth looking on STM32F103 (or STM32F407 with Cortex M4) which also can used be with Arduino IDE with some extra effort (STM32 MCUs usually more cost effective than Atmel counterparts, and have higher performance).


Double clap sensor not working as intended I have this double clap sensor code written, it seems it would work but it seems to trigger the double clap even on a single clap, any ideas?

int soundSensor = A1;
int relay = A2;
int relay2 = A3;
int relay3 = A4;
int relay4 = A5;
int claps = 0;
long detectionSpanInitial = 0;
long detectionSpan = 0;
boolean clapState = false;
int doubleClap = 0;

//Light sensor
int photocellPin = A0;     // the cell and 10K pulldown are connected to a0
int LEDbrightness;

//int delayValue = 100;
int photoSensor = 0;

// sound sample
const int sampleWindow = 50; // Sample window width in mS (50 mS = 20Hz)
unsigned int sample;

//other
boolean isRelaysOn = false;
void setup() {
  pinMode(soundSensor, INPUT);
  pinMode(relay, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  turnRelayOff();
  Serial.begin(9600);
}

boolean state = false;
boolean lastState = true;
boolean lightTurnedItOff = false;
void loop() {

  /////////////
  // photo sensor
  ////////////////////

  photoSensor = analogRead(photocellPin) > 623;

  /////////////
  // clap sensor
  /////////////////////
  double sensorState = getSoundLevel();
  Serial.println(sensorState);
  double threshold = .2;

  if (sensorState > threshold)
  {
    if (claps == 0)
    {
      detectionSpanInitial = detectionSpan = millis();
      claps++;
    }
    else if (claps > 0 && millis()-detectionSpan >= 50)
    {
      detectionSpan = millis();
      claps++;
      Serial.println(" CLAP ADDED!!!!");
    }
  }

  if (millis()-detectionSpanInitial >= 400){

    if (claps == 2)
    {
      claps++;
      doubleClap = 1 - doubleClap;
      state = !state;
      Serial.println("TWO claps!");

      if(lastState == state ){
        relayControl(doubleClap);
        lastState = !lastState;
      }
    }
    claps = 0;
  }

  if(isRelaysOn == true && photoSensor == 1){
    turnRelayOff();
    lightTurnedItOff = true;
  }
  if(isRelaysOn == true && photoSensor == 0 && lightTurnedItOff == true){
    turnRelayOn();
    lightTurnedItOff = false;
  }

}

void relayControl(int doubleClap){
  /////////////
  // relay control
  /////////////////////

  if(doubleClap == 1){
    turnRelayOn();
    Serial.println("on");
    isRelaysOn = true;

  }
  else{
    turnRelayOff();
    Serial.println("off");
    isRelaysOn = false;
  };

}

void turnRelayOn(){
  int delayAmount = 100;
  digitalWrite(relay, LOW);
  delay(delayAmount);
  digitalWrite(relay2, LOW);
  delay(delayAmount);
  digitalWrite(relay3, LOW);
  delay(delayAmount);
  digitalWrite(relay4, LOW);
  delay(100);
  digitalWrite(relay4, HIGH);
  delay(100);
  digitalWrite(relay4, LOW);
}

void turnRelayOff(){
  digitalWrite(relay, HIGH);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);
}

double getSoundLevel(){

  unsigned long startMillis= millis();  // Start of sample window
  unsigned int peakToPeak = 0;   // peak-to-peak level

  unsigned int signalMax = 0;
  unsigned int signalMin = 1024;

  // collect data for 50 mS
  while (millis() - startMillis < sampleWindow)
  {
    sample = analogRead(soundSensor);
    if (sample < 1024)  // toss out spurious readings
    {
      if (sample > signalMax)
      {
        signalMax = sample;  // save just the max levels
      }
      else if (sample < signalMin){
        signalMin = sample;  // save just the min levels
      }
    }
  }
  peakToPeak = signalMax - signalMin;  // max - min = peak-peak amplitude
  double volts = (peakToPeak * 3.3) / 1024;  // convert to volts

  return volts;
}

Serial monitor:

  0.02
  0.02
  0.02
  0.02
  0.01
  0.01
  2.20
  0.30  CLAP ADDED!!!!
  0.13
  0.09
  0.04
  0.02
  0.02
  0.01
  0.02 TWO claps! on
  1.11
  0.06
  0.05
  0.07
  0.15
  0.10
  0.03
  0.10
  0.06
  0.03
  0.04
  0.06

If your first clap rings for more than 50ms, the program counts it as a second clap.  After detecting a clap, you need to wait for the sound to die down before you start listening for a second clap.


Real Time clock module error-DS3231 This is not a code error I have been using DS3231 RTC module with battery. When I bought this module It worked perfectly now when I get it to use, The time is running perfectly. when I set the current time of my location, it has been running along with that time but the problem is when I unplug the power of my Arduino Nano and again when I give the power I can see the time is running from its start, I could not see any current time value my location but I have attached CR2032 battery along with DS3231 module? what is the problem with this? I changed another battery too but It shows same problem my DS32321 haven't kept the time when I unplug and re-plug the power
This is the code I'm using for set the time
#include <DS3231.h>

// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);

void setup()
{
  // Setup Serial connection
  Serial.begin(115200);
  // Uncomment the next line if you are using an Arduino Leonardo
  //while (!Serial) {}

  // Initialize the rtc object
  rtc.begin();

  // The following lines can be uncommented to set the date and time
  rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
  rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
}

void loop()
{
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");

  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());

  // Wait one second before repeating :)
  delay (1000);
}

This is the code I'm using to make Interrupt
 #include <DS3231.h>

int Relay = 4;

DS3231  rtc(SDA, SCL);
Time t;

const int OnHour = 21;
const int OnMin = 46;
const int OffHour = 21;
const int OffMin = 48;

const int On2Hour = 14;
const int On2Min = 54;
const int Off2Hour = 21;
const int Off2Min = 48;

void setup() {
  Serial.begin(115200);
  rtc.begin();
  pinMode(Relay, OUTPUT);
  digitalWrite(Relay, LOW);
}

void loop() {
  Serial.println("Time:  ");
  Serial.print(rtc.getTimeStr());
  Serial.print('\n');

  Serial.println("Date: ");
  Serial.print(rtc.getDateStr());
  Serial.print('\n');

  t = rtc.getTime();
  Serial.print(t.hour);
  Serial.print(" hour(s), ");
  Serial.print(t.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay (1000);
  //can be set lcd display alspo
  if(t.hour == OnHour && t.min == OnMin){
    digitalWrite(Relay,HIGH);
    Serial.println("LIGHT ON");
    }

    else if(t.hour == OffHour && t.min == OffMin){
      digitalWrite(Relay,LOW);
      Serial.println("LIGHT OFF");
    }
  if(t.hour == On2Hour && t.min == On2Min){
    digitalWrite(Relay,HIGH);
    Serial.println("LIGHT ON");
    }

    else if(t.hour == Off2Hour && t.min == Off2Min){
      digitalWrite(Relay,LOW);
      Serial.println("LIGHT OFF");
    }
}

I am posting a code please try it may be it can help you
    #include "RTClib.h"

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup () {
  Serial.begin(57600);

#ifndef ESP8266
  while (!Serial); // wait for serial port to connect. Needed for native USB
#endif

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, let's set the time!");
    // When time needs to be set on a new device, or after a power loss, the
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
     rtc.adjust(DateTime(2020, 10, 19, 10, 13, 0));
  }

  // When time needs to be re-set on a previously configured device, the
  // following line sets the RTC to the date & time this sketch was compiled
  // rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  // This line sets the RTC with an explicit date & time, for example to set
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}

void loop () {
    DateTime now = rtc.now();

    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();

    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");

    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));

    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();

    Serial.print("Temperature: ");
    Serial.print(rtc.getTemperature());
    Serial.println(" C");

    Serial.println();
    delay(3000);
}

Upload the above code and then upload the same code just comment the following part
if (rtc.lostPower()) {
        Serial.println("RTC lost power, let's set the time!");
        // When time needs to be set on a new device, or after a power loss, the
        // following line sets the RTC to the date & time this sketch was compiled
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
        // This line sets the RTC with an explicit date & time, for example to set
        // January 21, 2014 at 3am you would call:
         rtc.adjust(DateTime(2020, 10, 19, 10, 13, 0));
      }

This will work and even if you plug and unplug it from power the RTC time will not reset


Arduino PWM output cannot drive MOSFET 0-12V On an Arduino Uno, the PWM pin 3 is connected to the gate pin of an N-channel MOSFET STP16NF06L. The source pin is connected to ground of a 12 V power supply and drain pin connected to a multimeter. The other end of the multimeter is connected to the positive terminal of the power supply.

Question: When Arduino varies its PWM output from 0 to 255, the multimeter reading goes from 11.50 V to 12.10 V. Why isn't it 0 to 12 V?

When the FET gate is connected to the Arduino pin that outputs either 0 V or 5 V, the multimeter reading is as expected at 0 V and 12 V respectively.

Assuming you have a suitable FET You should have a circuit in line the following.
http://elinux.org/RPi_GPIO_Interface_Circuits#Using_a_FET

You should have some kind of load (a multimeter will have too high an impedance). Use a resistor 4.7k or smaller. You should also have a resistor on the gate


Arduino Serial Queue So I am programming an LED Music Visualizer that uses a combination of Processing and Arduino. I have it all working as I want to but there is a small problem. If I were to stop the music, then the Arduino will keep displaying the visualization for a few seconds. I believe that this issue would be caused by it "catching up" on new serial data from Processing like a queue. So my question is: When arduino uses the Serial.read() function, is it using the most recent value or is it using the next value received after the last one that it used, like a queue of values.

Example: Processing sends the values 1,2,3,4,5,6,7,8,9 over serial in 10 millisecond intervals. Arduino only performs Serial.read at 20 millisecond intervals. Would the arduino read the values 1,3,5,7,9 in or would it read the values 1-9 but in twice the time?

Sorry for the confusing question, hopefully somebody could shed some light. At the core, it is a question on how serial works, you can ignore the part about the music visualizer.

It sounds like you figured most of your question out already.

(Someone correct me here if I'm wrong). The Atmega 328p uC, I believe, has an 8 byte hardware buffer for RX serial data. In software, the Arduino core code defines a maximum ring buffer of 64 bytes that acts as a FIFO queue.

So, what does his mean? Let's just focus on the hardware buffer since it's fairly easy. Say you send your data 1,2,...,10 at 10ms intervals, and you read your data at 100ms intervals (for illustration purposes). The problem is that you send 10 bytes of data but only have room for 8 bytes. So, your first two values (1,2) are pushed out of the buffer and lost. This idea also illustrates a FIFO queue, first in first out.

The same idea can be extended to a ring buffer.

Anyway, like you said, this could explain your problem. If you have 64 bytes, which will obviously be full since your inevitably losing data (20ms read with a 10ms write), you'll be seeing the effects for 64 * 20ms = 1.28s. There's probably some processing delay too which will extend this delay, but it's more than likely minimal if it's efficient code.


HardwareSerial - check for overflow The SoftwareSerial library has a built-in Overflow function, but the Serial library does not.  Is there a simple way to check for a data buffer overflow on a hardware serial port?

A look at HardwareSerial_private.h shows incoming bytes are always read (interrupt-based), regardless of what your code is doing. So we can't set up a hardware interrupt to notify us when the chip's RX register has overflowed, because such an interrupt would depend on overflow flags but these flags never become set because, like I said, bytes are always read. It also shows that while all incoming bytes are read, not all are added to the 64-byte Serial buffer i.e. a byte may be read but if the buffer is full, nothing else happens; it is simply read to clear hardware flags. So the only (direct) way I can think of is to constantly poll Serial.available() in loop() to check if the number of bytes available for reading is equal to 64. If this condition yields TRUE, then you may safely conclude that the Serial buffer is full and about to overflow. This should suffice:

    void loop(){
        //your code
        if (Serial.available() == SERIAL_RX_BUFFER_SIZE){ // Just to be general, 64 bytes in most cases
            //buffer is overrun, do what u will
        }
    }

You could make some changes to HardwareSerial_private.h to get something like the overflow() method of SoftwareSerial. The relevant lines are:

    if (i != _rx_buffer_tail) {
        _rx_buffer[_rx_buffer_head] = c;
        _rx_buffer_head = i;
    }

The snippet above ensures that the current write position is not equal to the tail of the ring buffer (i.e. if we are about to overwrite a character in the buffer), before writing the incoming byte to the buffer. An else block could be added to set some global variable to indicate overflow. This global variable would have to be cleared when Serial.read() is called.


Changing how a longpress is executed I have an RGB LED common Anode attached to my Uno and this code detects a long press to turn the LED on and off.  Short presses cycle through colors, then off.

The problem is that a longpress is 2+sec, but it doesn't register until I release the button.  How would I set this up to execute the code at 2sec regardless of whether the button is released?

It's probably not worth my time if it requres too much modification.  I have a working item, it's just not... ideal.

Xhunsigned long keyPrevMillis = 0;
const unsigned long keySampleIntervalMs = 25;

int redPin = 11;
int greenPin = 10;
int bluePin = 9;
int LEDcolor=0; // 0=White, 1=Red, 2=Green, 3-Blue, 4=Yellow, 5=Purple, 6=Pink, 7=Orange, 8=Off
int LEDstatus =0; //0=Off, 1=On
int changed =0; //has the LEDstatus just changed?
byte longKeyPressCountMax = 80;    // 80 * 25 = 2000 ms
byte longKeyPressCount = 0;

byte prevKeyState = HIGH;         // button is active low
const byte keyPin = 2;            // button is connected to pin 2 and GND

// called when button is kept pressed for less than 2 seconds
void shortKeyPress()
{
   Serial.println("short");
   if (LEDstatus==1)
   {
      LEDcolor = LEDcolor +1;
      if (LEDcolor==0) {analogWrite(redPin, 0);analogWrite(greenPin, 0);analogWrite(bluePin, 0);Serial.println("White");}
      if (LEDcolor==1) {analogWrite(redPin, 0);analogWrite(greenPin, 255);analogWrite(bluePin, 255);Serial.println("Red");}
      if (LEDcolor==2) {analogWrite(redPin, 255);analogWrite(greenPin, 0);analogWrite(bluePin, 255);Serial.println("Green");}
      if (LEDcolor==3) {analogWrite(redPin, 255);analogWrite(greenPin, 255);analogWrite(bluePin, 0);Serial.println("Blue");}
      if (LEDcolor==4) {analogWrite(redPin, 0);analogWrite(greenPin, 0);analogWrite(bluePin, 255);Serial.println("Yellow");}
      if (LEDcolor==5) {analogWrite(redPin, 175);analogWrite(greenPin, 255);analogWrite(bluePin, 175);Serial.println("Purple");}
      if (LEDcolor==6) {analogWrite(redPin, 0);analogWrite(greenPin, 255);analogWrite(bluePin, 155);Serial.println("Pink");}
      if (LEDcolor==7) {analogWrite(redPin, 5);analogWrite(greenPin, 215);analogWrite(bluePin, 255);Serial.println("Orange");}
      if (LEDcolor==8) {analogWrite(redPin, 255);analogWrite(greenPin, 255);analogWrite(bluePin, 255);Serial.println("Off");LEDstatus=0;}
   }
}

// called when button is kept pressed for more than 2 seconds
void longKeyPress()
{
   Serial.println("long");
   if (LEDstatus==0 && changed==0)
   {
      analogWrite(redPin, 0);
      analogWrite(greenPin, 0);
      analogWrite(bluePin, 0);
      LEDcolor=0;
      changed=1;
      LEDstatus=1;Serial.println("On");
   }
   if (LEDstatus==1 && changed==0)
   {
      analogWrite(redPin, 255);
      analogWrite(greenPin, 255);
      analogWrite(bluePin, 255);
      LEDcolor=0;
      changed=1;
      LEDstatus=0;Serial.println("Off");
   }
   changed=0;
}

// called when key goes from not pressed to pressed
void keyPress() {
   Serial.println("key press");
   longKeyPressCount = 0;
}

// called when key goes from pressed to not pressed
void keyRelease() {
   Serial.println("key release");

   if (longKeyPressCount >= longKeyPressCountMax) {
      longKeyPress();
   }
   else {
      shortKeyPress();
   }
}

void setup()
{
   Serial.begin(9600);
   pinMode(keyPin, INPUT);
   digitalWrite(keyPin, HIGH);
   pinMode(redPin, OUTPUT);
   pinMode(greenPin, OUTPUT);
   pinMode(bluePin, OUTPUT);
   analogWrite(redPin, 255);
   analogWrite(greenPin, 255);
   analogWrite(bluePin, 255);
}

void loop() {
// key management section
   if (millis() - keyPrevMillis >= keySampleIntervalMs) {
      keyPrevMillis = millis();

      byte currKeyState = digitalRead(keyPin);

      if ((prevKeyState == HIGH) && (currKeyState == LOW)) {
         keyPress();
      }
      else if ((prevKeyState == LOW) && (currKeyState == HIGH)) {
         keyRelease();
      }
      else if (currKeyState == LOW) {
         longKeyPressCount++;
      }

      prevKeyState = currKeyState;
   }
}

I've rewritten the code entirely. Not that yours was terrible, it was just easier for me to start from scratch. You are left with a very empty loop(), which I always prefer.

The code contains three 'colours' and an OFF state. You can add as many other colours as you wish: add an enumeration to _LED_STATE and then add a corresponding case(<NEW_COLOUR>) statement in LEDcontrol(). I haven't included any analogWrite() functions - or in fact any declarations for the LED pins at all - because I'm a little too lazy but it should be obvious where to put them within the case statement.

Note that in the final case() statement, the LED state is changed from green to off. This means that a short press will turn the LED off after it has cycled through all the other colours, but will stay off until a long press. If you only want long pressed to switch off/on, change line 103 to eLED_STATE = _LED_STATE_RED;, or whichever the first colour is.

#define btn 3   // button pin

#define SHORT_PRESS 100     // useful for debouncing, can be changed
#define LONG_PRESS  2000    // defines how long a 'long press' is
#define CYCLE       false
#define SHOW        true

//--// You can add new colours in this enum block
enum _LED_STATE
{
    _LED_STATE_OFF,
    _LED_STATE_RED,
    _LED_STATE_BLUE,
    _LED_STATE_GREEN
};

_LED_STATE eLED_STATE = _LED_STATE_OFF;

void setup()
{
    pinMode(btn, OUTPUT);
    LEDcontrol(SHOW);
}

void loop()
{

    if (digitalRead(btn))
        btnPressed();
}

void btnPressed()
{
    unsigned long tStart = millis();

    //--// Loop continuously while button is pressed
    while (digitalRead(btn))
    {
        //--// If LONG_PRESS is exceeded...
        if (millis() > tStart + LONG_PRESS)
        {
            //--// If LED is off, turn it on
            if (eLED_STATE == _LED_STATE_OFF)
                eLED_STATE = _LED_STATE_RED;        // Choose 'starting' colour
            //--// If LED is on, turn if off
            else
                eLED_STATE = _LED_STATE_OFF;
            //--// Update LED to display new eLED_STATE
            LEDcontrol(SHOW);
            //--// Now loop here until button is released
            while (digitalRead(btn));
        }
    }

    //--// If button is released in between the two press times
    if ((millis() > tStart + SHORT_PRESS) && (millis() < tStart + LONG_PRESS))
    {
        //--// Ignore if LED is off         ////// REMOVE ////////////////////
        if (eLED_STATE == _LED_STATE_OFF)   ////////// IF ////////////////////
            return;                         ///////////// NECESSARY //////////

        //--// Change the LED colour
        LEDcontrol(CYCLE);
        //--// Update LED to display new eLED_STATE
        LEDcontrol(SHOW);
    }

    //--// This helps to debounce; experiment with it
    delay(10);
}

void LEDcontrol(bool SHOW_OR_CYCLE)
{
    switch (eLED_STATE)
    {
        case(_LED_STATE_RED) :
        {
            if (SHOW_OR_CYCLE)
            {
                // paint it red
                return;
            }
            eLED_STATE = _LED_STATE_GREEN;
            return;
        }
        case(_LED_STATE_GREEN) :
        {
            if (SHOW_OR_CYCLE)
            {
                // paint it green
                return;
            }
            eLED_STATE = _LED_STATE_BLUE;
            return;
        }
        case(_LED_STATE_BLUE) :
        {
            if (SHOW_OR_CYCLE)
            {
                // paint it blue
                return;
            }
            //--// What happens after last colour? Next colour or OFF?
            eLED_STATE = _LED_STATE_OFF;
            return;
        }
        case(_LED_STATE_OFF) :
        {
            if (SHOW_OR_CYCLE)
            {
                // paint it black
                return;
            }
            eLED_STATE = _LED_STATE_RED;
            return;
        }
    }
}


Cannot open file with underscores using the SD library So I'm trying to create a new file that has underscores in its name. However, when I try this, no file is created.

This works

String fileName = "NMEA.txt";
mySensorData = SD.open(fileName.c_str(), FILE_WRITE);

This does not work

String fileName = "NMEA__23_33_3__16_7_29.txt";
mySensorData = SD.open(fileName.c_str(), FILE_WRITE);

Does anyone know why?

[The SD library] uses short 8.3 names for files.

source


How to code multiple conditions inside if statement? I have a system that checks the value of a moisture sensor and will also check the time

if (t.hour == 7 && t.min == 00 && moistureOneSensorValue >= 700) {
  RelayOne();
  RelayTwo();
}

When moistureOneSensorValue is greater than or equal to 700 it means the soil is DRY, so when all conditions inside the if statement are true the relayOne and relayTwo functions will be called.

My problem is that when moistureOneSensorValue is still moist the above if statement will result in false and the relayOne and relayTwo functions will not be called. I want Arduino to execute and call the relayOne and relayTwo functions and disregard the time. I use time so that the system will only call the relayOne and relayTwo functions in the morning at exactly 7 AM every day, but it needs to check/make sure that the soil is DRY...

Example

First thing in the morning the system will check the time and sensor value; if the if statement results in false the system will keep monitoring and try the if statement until the soil is DRY. But I think when that happens it will be over 7 AM.

Sorry for the messy explanation.

I'm not sure how quickly you soil could get dry, but I suspect what you want to do is to periodically check the dryness throughout the day. Say like every two hours:

// Check every 2 hrs (when hr is even)
if ( t.hour % 2 == 0 && moistureOneSensorValue >= 700 ) {...}

You could also bound it to only during the day time:

if ( t.hour >= 7 // after 7a
  && t.hour <= 19 // before 7p
  && t.hour % 2 == 1 // every 2 hrs (when hr is odd)
  && moistureOneSensorValue >= 700 // soil is dry
) {...}


Does a graphical driver chip exist for this project? I need some expert advice. I'm using an Arduino Leonardo, which I have got working with a Nokia 3310 monochrome screen. I wrote some code to draw any graphics to the screen.

What I want to know is, can I buy a chip from somewhere that will offload most of the CPU usage (for graphics from the Leonardo) that draws numbers and letters to the screen and basic graphics (different types of polygons and lines)? So I'm looking for a chip designed to do the graphical work and a data sheet reference for the chip.

I have no idea if there is a chip or not, but I doubt it.

But then, why do you need one?

You already know how to communicate with the screen, so why not off-load those functions on to another Arduino (make your own small ATMega328P based board to do it) and then communicate with that through whatever means you like from your Leonardo?

You don't need a dedicated chip to do what you can quite easily program an Arduino to do.


Ultrasonic HC-SR04 echo and trig pins I am doing a watch with GPS tracker project. I am using an Ultrasonic HC-SR04 sensor. I don't know where to connect the Echo and trig pins with my Arduino. Please let me know how to connect it.

To any 2 free IO pins.

To quote sparkfuns datasheet:

  (1) Using IO trigger for at least 10us high level s ignal,
  (2) The Module automatically sends eight 40 kHz and  detect whether there is a pulse signal back.
  (3) IF the signal back, through high level , time of high output IO duration is  the time from sending ultrasonic to returning.
  Test distance = (high level time×velocity of sound (340M/S) / 2,

In other words you send a short pulse to trigger pin and then wait for the echo pulse and measure how long it was high. Divide the number of microseconds it was high by 58 and you have the distance in centimetres ( use 148 for inches)


Joy-IT RS232 Shield and RS232 voltage levels First of all, sorry if this is a dumb question, but I'm pretty new to the whole Serial RS232 concepts.
I do have an Arduino Board that, from what I read about, is not able to communicate via RS232 because of different levels.
My question now is: If the Joy-IT RS232 Shield will make up for that. So is this shield handling the RS232 level shift? I don't really know what to look for so I am asking here.
Thanks!

Yes, that shield will handle the level shifting for you. If you look closely at the images of the shield, you see the MAX232 chip, which is a commonly used chip for getting UART (which is the Serial interface of the Arduino) to speak over RS232.
And yes, RS232 uses different voltage levels. The UART on a microcontroller usually uses the voltages 0V and 5V (or 3.3V depending on  it's supply voltage), which is also called TTL levels (Transistor-Transistor Logic), while RS232 mostly works with +-10V (though different voltages are also inside the standard). You see, that this is a symmetrical voltage around ground (0V).


STM32YYXX chip series is not defined in boards.txt The STM32YYXX chip series is not defined in boards.txt? How can I solve this? I am using Windows 10 with Arduino IDE 1.6.6

Overview

Following the guide Getting Started on the STM32 page on Github: Arduino core support for STM32 based boards:

  This repo is available as a package usable with Arduino Boards
  Manager.

  Use this link in the "Additional Boards Managers URLs" field:

  https://github.com/stm32duino/BoardManagerFiles/raw/master/STM32/package_stm_index.json

  For full instructions on using the "Boards Manager", see the Getting
  Started page.

Thanks to Juraj's comment for the tip

  this is not the current STM boards package. ST Microelectronic took over the development github.com/stm32duino/Arduino_Core_STM32 stm32duino.com/viewtopic.php?f=16&t=4671

Step by Step

The process is as follows (screenshots from OS X, but on Windows/Linux the process is the same):

Adding the URL in the preferences dialog (one URL per line)

Boards Manager menu

Boards Manager dialog

Boards Manager dialog - STM32 Core Boards installed

Boards Manager dialog - Boards installing

Boards Manager dialog - Boards installed

Here are the newly installed boards in the menu

As a comparison, these are the boards installed using the deprecated manual process described below:

Deprecated method

From STM32 - installation

  Prerequisites

  If your STM32 board does not have a bootloader yet and you want to be able to program it over USB, you'll have to upload
  the STM32duino bootloader to flash memory. See Burning the
  bootloader.

  Arduino and Arduino_STM32

  Download and install the official Arduino IDE. Versions 1.6.10 till 1.8.5 have been reported to work fine.

  If you already have the Arduino IDE installed and it's a newer version, see the Boards Manager package method of installation.

  Note: this method is deprecated and not supported in forum!

  Run Arduino IDE, and open the menu Tools -> Boards -> Boards Manager. Install the "Arduino SAM Boards" package (includes the
  Arduino Due) from the list of available boards. This installs compiler
  support for ARM Cortex-M3.
  Download a zip file containing the Arduino STM32 files from here.
  Unzip the content of the zip file, and place the Arduino_STM32 folder to [Arduino sketches folder]/[hardware]/[Arduino_STM32].
  Create the 'hardware' folder if it does not exist yet.

  Example how the path should look like:
  C:\Users\<user>\Documents\Arduino\hardware\Arduino_STM32

As an aside, for anyone using OS X, from Installation on OSX

  Installation on OSX

  Arduino_STM32 folder must be placed inside
  ~/Documents/Arduino/hardware (note. if the hardware folder doesn't
  exist you will need to create it)
  So you should get ~/Documents/Arduino/hardware/Arduino_STM32
  Note.  DFU util binaries
  have now been added to the repo, in tools/macosx/dfu-util, so there is
  no longer a need to install Homebrew to then install dfu-util, or to
  compile dfu-util from source.


Access I2C sensor from Arduino Uno as slave I connected Raspberry Pi 3 to an Arduino Uno through I2C. The Arduino Uno uses the I2C as slave.

When I connect AM2320 sensor (temperature and humidity) to the Arduino Uno, I am getting the response that the sensor is offline.

I tested the sensor on Raspberry Pi 3 and it is working fine. On the Raspberry Pi the address is 0x5c. On most libraries, the address is 0xb8. I have the same result when I tried these 2 addresses.

Do I have problem because Arduino Uno is working as slave?

Indeed, I2C slaves cannot communicate with one another.

There are some obscure capabilities for devices to switch role, but that is likely to introduce lots of complications.

You might look at using bit-banged (or "soft") I2C on other digital pins and move the peripheral's I2C lines there instead o the hardware I2C pins connected to the pi.  For example, a web search quickly found something that claims to do this at:

https://github.com/felias-fogg/SoftI2CMaster

No idea if that particular one will work for you, but there are others as well.

Or you can re-design your scheme so that the pi reads the sensor, and if necessary writes the values of interest to the Arduino.