text:
Using CD74HC4067 16-Channel Analog Multiplexer Demultiplexer is not working as expected
I am working on a project that needs multiple digital signals and I am considering the CD74HC4067 (on a break-board) to work as a multiplexer. More specifically i am trying to build a keypad with multiple ttp123 break-boards. Each ttp123 signal is connected to one of the 0-15 pins of the CD74HC4067. The S0-S3 pins are connected to digital Pins D6 to D9 on a pro mini. Signal is on A0 and EN is on A1. A1 and EN have a 4K7 resistor to ground. I power the setup with a separate 5v and the arduino is connected on a pc usb port.
I expect when a ttp123 is pressed to trigger a HIGH and this event to be passed to SIG pin. Here is my code:
//Using CD74HC4067 16-Channel Analog Multiplexer
//Mux control pins

int s0 = 6;
int s1 = 7;
int s2 = 8;
int s3 = 9;

//Mux in "SIG" pin
int SIG_pin = A0;
int EN_pin  = A1;

void setup(){
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(EN_pin, OUTPUT);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  digitalWrite(EN_pin, LOW);

  Serial.begin(9600);
  Serial.println("keypad interfacing_CD74HC4067 starting...");
}

void loop(){
  String a;
  //digitalWrite(EN_pin, HIGH);
  Serial.println(" press any key to continue ...");
  //digitalWrite(EN_pin, LOW);
  while (!Serial.available());
  while(Serial.available()) {

  //Loop through and read all 16 values
  for(int i = 0; i < 16; i ++){
    //Serial.print("Value at channel ");
    //Serial.print(i);
    //Serial.print("is : ");
    //Serial.println(readMux(i));

      float volts = readMux(i);

      Serial.print("Value at channel ");
      Serial.print(i);
      Serial.print(" is : ");
      Serial.print(volts);
      Serial.println();

    //delay(1000);
  }
  a= Serial.readString();// read the incoming data as string
}
}
float readMux(int channel){
  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };

  //loop through the 4 sig

  for(int j = 0; j < 4; j ++){
    digitalWrite(controlPin[j], muxChannel[channel][j]);
  }
  //read the value at the SIG pin
  int val = analogRead(SIG_pin);

  //return the value
  float voltage = (val * 5) / 1024.0;
  return voltage;
}

Just for simplicity, I have connected only one ttp123 on the system, ttp123 signal to channel12 on 74HC4067. With ttp123 touched, I would expect to get a high on SIG when I write {0,0,1,1}, to S0-S3. All other channels should be LOW. However here is what I get:
On my first run after a boot:
press any key to continue ...
Value at channel 0 is : 2.53
Value at channel 1 is : 2.58
Value at channel 2 is : 2.53
Value at channel 3 is : 2.60
Value at channel 4 is : 2.51
Value at channel 5 is : 2.55
Value at channel 6 is : 2.50
Value at channel 7 is : 2.52
Value at channel 8 is : 2.42
Value at channel 9 is : 2.47
Value at channel 10 is : 2.43
Value at channel 11 is : 2.50
Value at channel 12 is : 2.40
Value at channel 13 is : 2.43
Value at channel 14 is : 2.38
Value at channel 15 is : 2.44

and then after each sample run all channels seem to get lower values...
press any key to continue ...
Value at channel 0 is : 1.70
Value at channel 1 is : 1.76
Value at channel 2 is : 1.71
Value at channel 3 is : 1.78
Value at channel 4 is : 1.70
Value at channel 5 is : 1.76
Value at channel 6 is : 1.72
Value at channel 7 is : 1.77
Value at channel 8 is : 1.67
Value at channel 9 is : 1.72
Value at channel 10 is : 1.69
Value at channel 11 is : 1.76
Value at channel 12 is : 1.69
Value at channel 13 is : 1.73
Value at channel 14 is : 1.67
Value at channel 15 is : 1.74

and I get no HIGH on channel 12 as I should.
Is there a need for a pullup or pulldown resistors in this setup? Should I connect a resistor to each S0-S3 with ground? Why is this not working?
Edit:
When the system is resting I measure 4.93V at the ttp's Vs to GND and 0V TTP_SIGNAL to GND. When ttp's are touched TTP_SIGNAL to GND i measure a 3.94-3.88v. But the strange thing is that when i touch the ttp's I measure 2.xx Volts at all the mux channels. I think that there must be some kind of short circuit somewhere but it is not visible. The problem is that I can't test another CD74HC4067 since i  have only one right now. Unless there is another suggestion I will look for a couple of these (CD74HC4067)  as soon as possible.
Edit2:
I got hold of a new CD74HC4067 and connected just one capacitive touch pad. When nothing is touched/pressed, i get the following:
press any key to continue ...
Value at channel 0 is : 1.01
Value at channel 1 is : 0.90
Value at channel 2 is : 0.81
Value at channel 3 is : 0.62
Value at channel 4 is : 0.44
Value at channel 5 is : 0.42
Value at channel 6 is : 0.43
Value at channel 7 is : 0.43
Value at channel 8 is : 0.31
Value at channel 9 is : 0.28
Value at channel 10 is : 0.24
Value at channel 11 is : 0.18
Value at channel 12 is : 0.15
Value at channel 13 is : 0.23
Value at channel 14 is : 0.22
Value at channel 15 is : 0.13

When i touch the pad (connected to c0) i get:
press any key to continue ...
Value at channel 0 is : 4.15
Value at channel 1 is : 3.74
Value at channel 2 is : 3.75
Value at channel 3 is : 3.54
Value at channel 4 is : 3.76
Value at channel 5 is : 3.33
Value at channel 6 is : 2.88
Value at channel 7 is : 2.64
Value at channel 8 is : 3.77
Value at channel 9 is : 3.52
Value at channel 10 is : 3.07
Value at channel 11 is : 2.76
Value at channel 12 is : 2.04
Value at channel 13 is : 1.83
Value at channel 14 is : 1.67
Value at channel 15 is : 1.51

I measure volts between signal and ground at the capacitive touch pad, when touched i get 3.9v

You've mentioned separate supply, begginers loves to forgot ground connections. Anyway slowly changing adc readings somewhere far from 0 or 5 usually indicates floating input. You have to measure everything, test that mux separately...

@KIV thank you for your comment. The grounds of the two separate sources are connected. I will measure everything again and will come back.

Posting a schematic of how you have it wired will help a lot. Even a hand drawn schematic is better than a frizzy picture.

@Gil i edited the question as you suggested.

I got a new CD74HC4067 and tested it. I edited the post above. Any suggestions?

I finally managed to get a solution to my problem. There was a cabling and a software issue as well. Firstly, I pulled down the Signal with a 10K resistor. In this way I stopped having those random volt measurements.

Secondly, in the code, I had an elementary failure to initialize the A0 analog pin as:
pinMode(SIG_pin, INPUT);
Here is the final code:
// interfacing mux with tp223

//Mux control pins

const int s0 = 6;
const int s1 = 7;
const int s2 = 8;
const int s3 = 9;

//Mux in "SIG" pin
int SIG_pin = A0;
int EN_pin  = 10;

void setup(){
  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);
  pinMode(SIG_pin, INPUT);
  pinMode(EN_pin, OUTPUT);

  digitalWrite(s0, LOW);
  digitalWrite(s1, LOW);
  digitalWrite(s2, LOW);
  digitalWrite(s3, LOW);
  digitalWrite(EN_pin, LOW);

  Serial.begin(115200);
  Serial.println("keypad interfacing_CD74HC4067 starting...");
}

void loop(){

  //Loop through and read all 16 values
  for(int i = 0; i < 16; i ++){
      int val = readMux(i);

      if (val > 0) {
        Serial.print(i);
        Serial.print(" pressed ");
        Serial.print(val);
        Serial.println();
      }
  }

}
float readMux(int channel){
  int controlPin[] = {s0, s1, s2, s3};

  int muxChannel[16][4]={
    {0,0,0,0}, //channel 0
    {1,0,0,0}, //channel 1
    {0,1,0,0}, //channel 2
    {1,1,0,0}, //channel 3
    {0,0,1,0}, //channel 4
    {1,0,1,0}, //channel 5
    {0,1,1,0}, //channel 6
    {1,1,1,0}, //channel 7
    {0,0,0,1}, //channel 8
    {1,0,0,1}, //channel 9
    {0,1,0,1}, //channel 10
    {1,1,0,1}, //channel 11
    {0,0,1,1}, //channel 12
    {1,0,1,1}, //channel 13
    {0,1,1,1}, //channel 14
    {1,1,1,1}  //channel 15
  };

  //loop through the 4 sig
  for(int j = 0; j < 4; j ++){
    digitalWrite(controlPin[j], muxChannel[channel][j]);
  }
  //read the value at the SIG pin
  int val = digitalRead(SIG_pin);
  //return the value
  return val;
}


text:
Wirelessly (but fast) transfer STEP and DIR output from Arduino to stepper driver
Very short version:
Looking for a way to wirelessly get STEP and DIR signals (only those two signals) from an Arduino to a DRV8825 stepper driver about a meter away:
Arduino -> STEP and DIR IO pins -> transmitter ) ) ( ( receiver -> DRV8825

edit Jan. 2024: Just to follow up on this; in the end I decided to simplify the whole setup I had, and moved all electronics, except for the power supply, to the moving part. A custom slip ring connects a PSU that is on the floor to the rotating platform that holds the Arduino, steppers, etc.
Long version:
For a project I've mounted an Arduino to a wooden board. The Arduino has a GRBL shield (basically a breakout board to four motor drivers for stepper motors (in my case the DRV8825)). Connected to this setup is a stepper motor. The power supply (NOT on the wooden board) for the motor is 24v, and I'm using a buck converter to take it down to 5v for the Arduino.
This whole board is rotating and the 24v gets passed to it using a custom sliding-contact with two contacts (24v and gnd).
Now this all works fine, but the problem is this: I have a second motor which I want to control from the same GRBL shield. But this motor is NOT on the rotating board.
If I place the motor driver next to this motor and power it from the same power supply (parallel to the sliding-contact) I have everything I need, except for the STEP and DIR signals from the Arduino.
Because there is no way I can add 2 more contacts to the sliding-contact (plus the signal would probably be too noisy anyway) I'm looking for a way to basically add a wireless bridge between the STEP and DIR output pins on the Arduino, and the STEP and DIR input pins on the motor driver. The motor and driver are about a meter away from the Arduino, so signal strength shouldn't be a problem.
I believe those well known 433Mhz transmitters are too slow for something like this, but I read most nRF24L01 modules are faster. Before I order some for a test setup, I was wondering if anyone already knows if this could work or not, knows a useful alternative, or has some suggestions for keywords to search for when trying to find another solution. I can find a lot of 'wireless' motor drivers online, but most are completely standalone units where the microcontroller is on the board, it's just controllable over wifi/bluetooth.

(Moved to "answer" for space; it's definitely not an answer. Sorry all!)
Minor points:

It's a motor controller shield; the GRBL is on the Arduino.
You'll need a motor controller at each motor; not clear if that's understood.
I'd also consider optical comms, although it has a different set of problems.

Ultimately I might approach this in a different way: instead of a single GCode box attempting to synchronize and control itself and an (essentially) independent system, I'd consider having a single GCode box (GBOX) controlling two independent systems (M1, M2).
GBOX would be a laptop/RPi/whatever that processes the "real" GCode. Based on the GCode commands, which in the end just tell motors what to do, I'd send each GCode command to its associated M1/M2 system.
How well this works depends a lot on the GCode, however; diagonals, arcs, etc. require motor cooperation, so a command like G02 X2Y0 R2 might cause problems, even though we can pull out the X and Y data. How the GCode is generated matters, but note that GBOX could also interpolate "tricky" commands to break them into something a dual-target system might be able to understand.
The "meaning" of the moves also matters: there's "getting from one place to another" and "getting from one place to another while drawing a line": the former may (or may not) have requirements around what that actually means, while the latter requires coordinated motion, and even if you're splitting the commands up correctly, even a fraction of a second difference in receive/action time will matter. Of course, you could also transmit both motors' commands to both motors and rely on timing or cross-Mn synch for starting their respective commands.
In the end it may be the only real way to make this work would be to have the "independent" systems be able to synchronize with each other, so that they know they're (a) ready to start, and (b) starting at the same time. GBOX could also potentially handle that synchronization as a "Go!!!" command is about as deterministic as it gets, especially if M1/M2 can receive a broadcast signal at the same time.
https://www.zikodrive.com/motor-control-case-studies-and-applications-2/a-remote-controlled-and-synchronised-stepper-motor-controller/ (very) briefly discusses the issues around synchronizing remote motors where their relative positions matter.

Not that I've given things like this any thought :p We had a similar approach to a similar, but non-wireless, project, but the motion control required was limited in scope, and synchronization was trivial, because the second system was limited in scope, and required no simultaneous cooperation with the primary system.

This GO signal sounds like a great idea. I can create two setups, have them use the same GCode but only connect their relevant motors. This should ensure they use the right timing (so motor X will wait for motor Y)
I have a lot of straight movements in my GCode so I could even execute them line by line with a GO in between to prevent a slowly increasing offset.
I borrowed a couple of NRF24L01's so I'm going to give the IO bridge idea a quick try, but could also use them to sync up the two setup. Thanks for the suggestion!

source: Stack Exchange

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

sort: votes


text:
Where is random defined with no arguments?
I can't seem to find void random() (with no arguments) defined in the library and yet my sketches seem to compile just fine when calling random() with no arguments.
I've found random with 1 argument and random with 2 arguments but no cases of random with no arguments.
Is random() defined in the library with no arguments?
If so, where is it defined?
If it isn't, what could explain how my code compiles despite me not providing any arguments?

It's defined in stdlib.h

@sempaiscuba Sadly Ignacio got there 8 minutes sooner, but that is indeed correct.

Sorry about that. The question came up in review, so I added the comment rather than an answer. :)

It's defined in the libc, in stdlib.h.

That explains why I couldn't find it in the Arduino github's source code.

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


text:
Charging Li ion cell using arduino
2days back I opened my cousin brothers laptop battery as it was a spare one left unused over a year.
I disintegrated it and found 6x 18650 batteries when I checked them with voltmeter individually I found that 2 were dead I.e.0V and 2 read 2.15 V and the last two read 1.5V. I thought of making a power bank using them individually. The battery are ideal for a power bank because they have 2200ah capacity. I need a circuit to charge it. I thought of chraging it with arduino. But how?
To get the datasheet just search "lr1865ah" in google and click the one and only pdf link that is the cell's datasheet. I need the charing circuit using arduino.

2.15v is way too low. The cell might be damaged due to this. Damaged lithium cell can burst into fire. I personally wouldn't risk it. Just toss them in the trash.

There is a far easier (and safer) way to charge them without using an Arduino. Over-voltage is an issue and another crucial factor with the 18650 batteries is to not let the voltage drop below 2.5 volts when you are dis-charging them. There is a simple "Charge/Discharge Board Module for 18650 Lithium Batteries" that sell for approx. $1 US:
http://www.ebay.ca/itm/2in1-1A-USB-Charge-Discharge-Board-Module-for-18650-Lithium-Battery-Phone-Bank-/302039028674?hash=item4652edd3c2:g:bDkAAOSw9NdXrBoE.
The board has a "fast charge" current of 1000 mA until the battery reaches 4.2 volts, then it switches to a "trickle charge mode". The circuit board also stops current flowing out of the battery once the voltage drops to 2.5 volts. Most of the older charger boards do not have this feature and it's almost as important. It also has a "over-current" protection current of 3.0 amps in case you try to draw too much power from it.
The circuit board has a mirco USB connection on it but be VERY careful before you plug it into a computer USB port. My old MacBook only provides up to 500 mA at each USB port, half of what's required.
The circuit board is 0.700" X 1.050". Here is a picture of it:

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


text:
Adafruit CC3000 Wifi Shield on IRQ 2?
I'm using an AdaFruit CC3000 Wifi shield as an HTTP server with an Arduino Uno.
I have a script which works fine -- logs into my Wifi and listens for connections as it should.
However, I want to use an infrared library which writes to the CC33000 default IRQ 3, so to avoid conflict I change the following setting:
#define ADAFRUIT_CC3000_IRQ   3  // MUST be an interrupt pin!

to the only other Interrupt pin
#define ADAFRUIT_CC3000_IRQ   2  // MUST be an interrupt pin!

The device hangs at "Initializing" .. or at least I see neither of the subsequent lines in the following code on my serial monitor:
Serial.println(F("\nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
  }

  Serial.print(F("\nAttempting to connect to ")); Serial.println(WLAN_SSID);
  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
    Serial.println(F("Failed!"));
    while(1);
  }

I've stripped everything back down to just the example code for HTTPServer to ensure it's not a conflict with my own code or the IR Library. I've changed the setting from 2 to 0 and 1 thinking there was some confusion over literal IRQs vs Pins, but those settings generate the "Couldn't begin" error trap.
Is there any other setting that I need to vary in order to get the CC3000 to opearate on IRQ 2 or is this a hardware bug and I'm out of luck if I want to use Pin 3?

It is a "hardware bug" as you so aptly put it. As far as I know, the only way to get the CC3000 board to use pin 2 as the IRQ is to physically rewire the connections. I did exactly that on my board and it works without a problem, leaving pin 3 free to use for whatever else you want. You can see what I did here.
It basically involves cutting the trace wire and running a jumper cable between the holes next to the pins.
The important thing to understand perhaps is that pins 2 and 3 are available to use for IRQ on the Mega and Uno, but it is an actual dedicated pin on the CC3000, hence why you have to go to this effort to change it. Also remember that once you have cut the trace to pin 3 it becomes an open/free pin and is no longer connected to the wifi shield. By the sounds of your requirements this shouldn't matter, but it is still useful to know.
If you haven't already, I recommend that you read the documentation for the CC3000 board, as it really helped me understand the irritating intricacies.
But yeah, if you choose to follow this and reroute the pin, it works perfectly. Hope this helps, even if it is a bit late.

Thanks, bladepanthera! I ended up figuring out how to switch the IR Library I was using to another pin, and that solved the immediate problem for me, but it's really good to know this for future reference and I hope it saves others some hair-pulling.


text:
Differing behaviour from Arduino Nano when plugged into laptop vs power source
Well here's a weird one. I'm monitoring a mic on an analog pin of an Arduino Nano and using the variation in voltage to control and LED.
When plugged in to my Laptop (USB 3, 500ma available, the nano only pulls 90) the detection is flawless. When plugged into an external power source, I get no variation at all or a random, non-responsive pattern of variation. Could be I'm getting voltage values that are out of range, but of course I can't monitor them on the serial port when I'm not plugged into the laptop.
I've got a potentiometer on the circuit to increase or decrease sensitivity by changing the trigger value. I can play poke-and-try at changing the trigger values to higher and lower ranges to try and find the sweet spot, but does anybody have an explanation of why I'd see a difference in the first place? I've tried a variety of external supplies, 500ma 1a, 2a - but if it's only pulling 90 (as reported by my Macbook System Report) this shouldn't matter, right? What else could account for differing behaviour?
Here's the code:
    void loop()
{
   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(0);
      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 * 5.0) / 10;  // convert to volts
   val = analogRead(potPin);
   if (val > 0) triggervoltage = 10;
   if (val > 500) triggervoltage = 11;
   if (val > 800) triggervoltage = 12;
   if (val > 1000) triggervoltage = 15;

   Serial.println(val);
   Serial.println(triggervoltage);
   Serial.println(volts);
//triggervoltage =
//Serial.println(volts);
//Serial.println(val);
//THIS IS the trigger mechanism for the effect. Vary the volts value to adjust sensitivity.

   if (volts > triggervoltage) [LED RESPONSE HERE]

noisy external power source, perhaps ..... how is the external power source connected?  ..... try using a battery

Hmm. Indeed, it works on a battery. But I guess that means my entire house's supply is noisy -- I tried different supplies in different rooms.

which supply are you using? .... what are the specs?

You could make a small sketch to send the value of analogRead to the serial plotter (instead of the serial monitor), then you can try a few things and see what the noise is doing. The laptop running at battery power is probably the best. As soon as you connect the laptop to a charger and a external power supply to the circuit, that is when the trouble begins. How is your microphone connected to the arduino? Please add extra information to your question. Could you add a photo of the arduino with microphone?

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


text:
At what level does low dynamic memory effect performance?
I have a few Arduino sketches that take 70-90% of dynamic memory. It seems that over 70%, the compiler gives the warning:
Low memory available, stability problems may occur.

but otherwise I wasn't noticing any problems.
Then I uploaded a sketch that took 89%, which logged String data to the serial port, and found that only newlines were being written out. When I commented out some global variables so that dynamic memory usage got to 88%, then it started printing out the data.
Is there any hard/fast rule on when this problem occurs? I was surprised by this problem, because the global variables I removed weren't even being used in the sketch, so I had thought the compiler would have removed or optimized them so they didn't waste any space. Are there any ways to automatically improve compilation efficiency and detect wasteful variables?

The typical build memory statistics is:
Global variables use XXX bytes (X%) of dynamic memory,
leaving YYY bytes for local variables.
Maximum is ZZZ bytes.

What is all this about? First, the maximum number of bytes SRAM depends on the MCU. Arduino Uno is ATmega328 based and has 2K byte SRAM. Arduino Mega2560 has 8K byte. "Dynamic memory" in the print out is SRAM. It is not the heap (malloc/free). To avoid confusion I will use "data memory" below.
The compiler allocates memory for all global variable (objects, struct, etc). It also allocates memory for literal strings (character vectors). These are copied from program memory to data memory at startup. All static variables in functions are also allocated. The sum of all these allocations are the "Global variables".
To execute the sketch data memory is used for the stack. It contains the function parameters, local variables in called functions (that are not allocated to registers), saved registers such as return address to the caller, etc. The size of the frame is known by the compiler and may be found in the assembly listing of a sketch. The maximum stack size required is tricky to calculate as it is the call chain with the largest frame size sum. This is not necessarily the deepest call chain. Also the compiler does to a fair amount of inlining.
The heap (malloc/free) is used by classes such as String. The heap starts directly after the global variables in data memory and grows towards the stack. The heap is blocks of memory allocated and deallocated during the execution of the sketch. This behavior may give heap fragmentation.
Interrupt Service Routines (ISR) need to be able to execute "on top of" any function call. The ISRs are typically called on hardware events such as USART data received. The compiler has to generate code that stores the machine state on stack to execute the ISR. Depending on how many registers the ISR needs more or less of the machine state (registers) need to be stored. The worst case is all 32 registers.
The warning at 30% of SRAM is at approx. 600 bytes left (Arduino Uno, 2K byte). That has to cover the stack and possible heap usage together with ISRs. With a stack heap limit of 32-128 byte, ISR frame of 32-64 byte, that actually leaves worst case approx. 400 bytes for local variables in functions and possible usage of the heap (such as String).
Cheers!

The problems occur when you run out of memory. That all depends on what you are doing with the memory that is available.
String objects are not good and are wasteful of memory. They really should be avoided, since they use dynamic memory allocation, which uses the "spare" memory that is what's left over from what the compiler says is used.
There is no rule, other than "don't run out of memory", and tracking dynamic usage can be very hard, so try to avoid using it if you can.


text:
How to stop Arduino from reseting after serial connection lost
If I connect to an Arduino Uno via a serial console to read debugging statements and then disconnect, the Arduino appears to reset. How do I stop this from happening?
I'm trying to program an Arduino to receive a "shutdown" signal from a Raspberry Pi via serial, which will make the Arduino cut the RPi's power. However, this will also cut the serial connection, and if it causes the Arduino to reset, it'll reactivate power.

There is a link on the Uno marked RESET-EN which links the Atmega16U2 (or 8U2) which handles incoming serial data to the main chip, the Atmega328P. If you cut that link (eg. with a knife) then it won't reset. However uploading new sketches will be harder because you will have to manually press the Reset button when the IDE starts to upload a new sketch.

Board:

Schematic:

One thing that people do is put a 10 µF capacitor between RESET and GND. That holds enough current to "weather" the reset pulse, and that stops the board resetting. You can always remove the capacitor to reprogram the board.

I have seen this on the Schematic and never understood what it was for. I gather the diagram is meant to indicate a pad with a cutable link.

So you're saying the serial connection is hard-wired to perform a reset after disconnect? I can understand it resetting after a sketch upload, but why also reset after a non-programming serial connection?

No it's not. However if your operating system brings DTR low when you disconnect, then that will generate the reset pulse. Do you physically disconnect, or drop the connection?

Tried to put 10uF ecap in my Uno, seems to be not working at all. in fact any data written to serial does not go thru at all.

I found the solution to my problem was this answer, which works for me on both a normal laptop and Raspberry Pi without having to modify any Arduino hardware.


text:
How to select a 0.1" header in Fritzing
Does Fritzing support the standard 0.1" break-away header?
When I search for "header" in its parts database, I see several examples, and some even seem to reference 0.1 headers, but I can't actually seem to select the physical part.
For example, if I select the "Header 3" part, the description specifically refers to 0.1 break away headers, but the "package" field references a completely different part, causing it to render incorrectly. If I click that dropdown to try and select a different package, there are dozens listed, but none look like a 0.1 header.


text:
How to confirm a pin is fried
How do you confirm a pin has been damaged and is unable to work as a digital input?
I tried detecting a pushbutton (connecting ground to pin 11 with a pullup resistor enabled) on a fresh Arduino Uno and digitalRead() always registers 0, regardless of the pushbutton state.
To confirm it wasn't my pushbutton's wiring, I tested it on some other pins, and they register the button press perfectly. I then tested pin 11 as an output, and it was able to blink and LED just fine.
The Arduino's pretty new, and I don't remember doing anything with it that would have damaged anything, much less pin 11, but is it fair to say that pin has somehow been damaged? As far as I can tell, everything else on the Arduino works perfectly.

Try using an external pull-up. It might just be that the internal pull-up is fried, and not the input logic.

Check your breadboard if you are using one. I thought that my pin was fried one time, but it turned out that the breadboard wasn't working in that area(no connection).

Yes, it sounds like that pin is fried.
You seem to have done all the things I would recommend:

Try your circuit on a different pin (works fine)
Try your circuit on the same (faulty) pin on a different microcontroller (works fine)

If you get different results between two chips that should be the same with the same code running on them then one of them is most likely faulty in some way, or has some other setting in it (fuse setting) that could be affecting it.  I am not aware of any settings like that on the '328P, certainly none that you would change without knowing you had changed them.


text:
Smooth servo control library
Is anyone aware of an Arduino library for smoothly controlling a servo?
I have an especially fast servo, which is trivial to control using Arduino's built-in Servo library. However, the library doesn't support proportional control. You specify a position, and the servo immediately goes to that position as fast as it can. With my servo, that creates incredibly fast jerky motion.
I've found some algorithms for interpolating a smooth servo motion by generating small incremental changes to the signal over time. I've been able to translate this to some Arduino code, and although the motion is much slower, it's still very jittery.
I've search for pure Arduino implementations, but I've not found anything. Does anyone know of an implementation? I find it hard to believe no one else has faced this type of servo control problem with an Arduino before.

After searching via a different angle (using "easing" as a keyword), I found this excellent library. Apparently this task is more commonly known as "servo easing", not smoothing. I've tested it with a hobby servo, and it does exactly what I was looking for.

Infortunately, I did not find any library but I found that the method shown below could work quite well for small projects. By adding a small delay, it helps the servo run a little smoother. It is not really ideal but it should work if your goal is to minimize the roughness of the servo.
Also by adding a 100uF capacitor between 5V and GND, the capacitor will help calm the sudden rush you might get when the servo first starts to turn. That rush is caused by the servo asking for more current when the servo is not moving.
#include <Servo.h>   //servo library
Servo myservo;       //servo object
int previousAngle = 0;

const int potPin = A3; //sensor pin

void setup() {
  myservo.attach(9);  //data pin of the servo
  pinMode(potPin, INPUT); //sensor pin as an input
}

void loop() {
  int val = analogRead(potPin);
  int angle = map(val, 0, 1023, 0, 180);

  if(angle>previousAngle)
  {
    for(int i=previousAngle; i<=angle; i++)
    {
      myservo.write(i); //turn servo by 1 degrees
      delay(10);        //delay for smoothness
    }
  }

  if(angle<previousAngle)
  {
    for(int i=previousAngle; i>=angle; i--)
    {
      myservo.write(i); //turn servo by 1 degrees
      delay(10);        //delay for smoothness
    }
  }

  previousAngle = angle;
}

I think this code should work with an else if. I made a thread myself, where I will make a 4 servo code for a robotic arm, working right, giving credit to you for the original code of course. Still you get +1 for this and the capacitor suggestion.

Searching the net for smooth servo movement I found this entry one year ago.
In the end I built a new library for this task called ServoEasing.


text:
Arduino Uno Rev3 Internal Quartz
I'm using an Arduino Uno Rev3 Board and need to send a trigger signal at a certain frequency (20-50Hz).
This trigger signal should be as accurate as possible (+/- 0.01 ms).
The Arduino site states that the arduino uno has a 16MHz Quartz Crystal, but I'm measuring a frequency accuracy of about 0.35% (which would be typical for a ceramic resonator) instead of what i could expect from a quartz (0.001%).
I'm using the micros() function to measure time.
Am I doing something wrong? How is my frequency so inaccurate?
Thanks for your help! :)

Edit: Indeed when I have a look at the schematics, I see the ceramic resonator (Blue circle). However, there seems to be another 16 MHz part (red circle). could that be a quartz oscillator?

Can you please provide the measurement code by editing your question?

I don't know why they say it has a quartz crystal - it doesn't - it has a ceramic resonator.  This one: https://uk.farnell.com/murata/cstce16m0v53-r0/resonator-ceramic-16mhz-smd/dp/2443265

@Majenko omg are you sure? My whole project relies on this accuracy. Why would they make a false statement on the official website? Is there even an arduino board (alternative) with a quartz crystal?

Yes, I am sure. That is the part from the schematic. I have emailed the webmaster to try and get the error corrected on the product page. There are plenty of other better boards with crystals - more powerful boards generally, such as Teensy, chipKIT, etc.

alright. Thank you :)

All the boards I make with 328P, 1284P, 2560, all use quartz crystals.  0.01mS = 10uS, yes? You can get down to 4uS with micros(), but you have to write code that runs within loop() and doesn't have jitter introduced by loop() background code.  For example, I needed to load 45 shift registers with 8 MHz SPI; to do so I had to disable interrupts and write 45 discrete SPI.transfer lines (spdr = array[0]; 15 no-ops, then spdr = array[1]); 15 no-ops, etc.)  If interrupts were on, I could see (on logic analyzer) that the micros() interrupt would disrupt the timing flow. loop() made is worse.

The Arduino Uno Rev3 has an ATmega328P.
@Majenko as far as I can interpret the schematic, there are two components, the one you sent (ceramic resonator) and another one, possibly the quartz? I try to attach the image

@MarayJay The Uno R3 has a quartz crystal to run the ATMega16U2, not the ATMega328P. It's the one for the ATMega328P that you care about.  Quartz is required for USB for the accuracy, but not for UART since it's more forgiving.

Ok so there is no possibility to get the accuracy of the quartz to control an output pin with this board?

@MarayJay No, I'm afraid not.

The ATMega328P chip is, indeed, clocked by a ceramic resonator. The website is misleading in stating that it has a crystal (I have emailed the webmaster to try and get this corrected, though I don't hold out much hope).
The 16MHz crystal in the schematics is part of the USB interface circuitry and has nothing to do with the timing of your running code. It is purely used to clock the ATMega16U2 chip which provides USB connectivity (USB requires a higher accuracy for stable communication).
There are other boards available with better crystals - most often boards that have native USB connections, such as the Arduino Due or Leonardo, or any of the myriad of boards by other manufacturers, like Teensy or chipKIT.

Thank you very much for the clarification!
I struggle finding an alternative that provides the following specs:

5V Output (I need a 5V signal)
Quartz crystal
RS-232 communication possible
USB connection to connect computer

Would you have a suggestion?

@MarayJay The Arduino Leonardo may be your best bet.

do i understand this right: The leonardo just has one quartz oscillator, because there is no second processor for the usb communication? And you are 100% sure that this is a quartz oscillator, right? I don't trust the arduino page anymore, so i trust you. (you're saving my day btw)

@MarayJay The Leonardo has a direct ("native") USB connection. It comprises the functionality of both the chips on the Uno in one. USB requires the accuracy of a quartz crystal. You can also use the Arduino Micro if you want a smaller footprint. Same chip, just a smaller board.

Thank you so much :)


text:
Multiple Time-Sensitive Tasks
I'm using an Arduino Leonardo and need to perform two time-sensitive tasks like this:
// Task 1 - Gets executed once a second (1Hz)
// Execution of task needs approx 70ms
   task1(); //Sending a message via Serial

// Task 2 - Gets executed 50 times a second (50Hz)
// Execution of task need a few micros
   task2(); //digitalWrite

As you can see, the problem is, that task one needs very long for execution and therefore task2 is executed too late to send a 50Hz signal. I'm not sure how, but I think there must be a way to give task 1 higher priority to interrupt task 2?
Thanks in advance! :)
Just for completion, here is my (not so clean) code:
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 6); //232_TX,232_

int triggerFreq = 10;
unsigned long timestamp_pps;
unsigned long timestamp;
unsigned long triggerStartTime;
const unsigned long dt_pps = 1000000; //micros
const unsigned long dt_trig = 1000000/triggerFreq; //micros
unsigned long ts_pps_high;
unsigned long ts_pps_low;
unsigned long ts_msg_high;
unsigned long ts_msg_low;

unsigned long i_pps = 0;
unsigned long i_trig = 0;

int hh = 04;
int mm = 51;
int ss = 00;
unsigned int pos = 2307;
bool msg;
bool trigMsgSent;

void setup() {
  // put your setup code here, to run once:
  pinMode(11, OUTPUT); // PPS
  pinMode(12, OUTPUT); // Indicator of msg_sent
  pinMode(13, OUTPUT); // FPS
  Serial.begin(9600);
  mySerial.begin(9600);
  triggerStartTime = micros();
}

void loop() {
  // ================== Part for the GPS Simulation ==================
  timestamp_pps = micros()-triggerStartTime;
  if (timestamp_pps>= dt_pps*i_pps+350000)
  {
    pos += 1;
    digitalWrite(12,HIGH);
    i_pps +=1;
    if (ss == 59)
    {
      ss=0;
      if (mm==59)
      {
        mm=0;
        hh+=1;
      }
      else mm+=1;
    }
    else ss+=1;

    ts_msg_high = micros();
    mySerial.print("$GPRMC,");
    if (hh<10) mySerial.print(F("0"));
    mySerial.print(hh);
    if (mm<10) mySerial.print(F("0"));
    mySerial.print(mm);
    if (ss<10) mySerial.print(F("0"));
    mySerial.print(ss);
    mySerial.print(".000,A,3015.");
    mySerial.print(pos);
    mySerial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");

    // Print Debug Messages
    digitalWrite(12,LOW);
    ts_msg_low=micros();
    Serial.print("PPS at: ");
    Serial.print(ts_pps_high);
    Serial.print("\t PPS low after: ");
    Serial.print(ts_pps_low-ts_pps_high);
    Serial.print("\t MSG high after: ");
    Serial.print(ts_msg_high-ts_pps_high);
    Serial.print("\t MSG low after: ");
    Serial.print(ts_msg_low-ts_pps_high);
    Serial.print("$GPRMC,");
    if (hh<10) Serial.print(F("0"));
    Serial.print(hh);
    if (mm<10) Serial.print(F("0"));
    Serial.print(mm);
    if (ss<10) Serial.print(F("0"));
    Serial.print(ss);
    Serial.print(".000,A,3015.");
    Serial.print(pos);
    Serial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");
  }
  else if (timestamp_pps>=dt_pps*i_pps+100000)
  {
    digitalWrite(11,LOW);
    if (msg==true)
    {
      msg = false;
      ts_pps_low = micros();
    }

  }
  else if (timestamp_pps>=dt_pps*i_pps)
  {
    digitalWrite(11,HIGH);
    if (msg==false)
    {
      msg = true;
      ts_pps_high = micros();
    }
  }
  // ================== Part for the FPS Trigger ==================
  timestamp = micros()-triggerStartTime;
  if (timestamp>= dt_trig*i_trig+2000)
  {
    digitalWrite(13,LOW);
    i_trig +=1;
    trigMsgSent = false;
  }
  else if (timestamp >=dt_trig*i_trig)
  {
    digitalWrite(13,HIGH);
    if (trigMsgSent == false)
    {
      Serial.print("FPS at: ");
      Serial.println(micros());
      trigMsgSent = true;
    }
  }

}

Update: So i implemented it with an interrupt according to this example. I just programmed the interrupt for the 50Hz signal, because that one must be accurate. The code is at the end. However, I'm still experiencing the 50Hz signal to be late when the serial is sent. It's now in the dimensions of half a millisecond, but that's not negligible in my project (Sensor fusion computer vision). The output of my post-processing-tool shows:
Trigger Nr. 25 is 646.912us late!
Trigger Nr. 28 is 434.176us late!
Trigger Nr. 75 is 653.056us late!
Trigger Nr. 78 is 429.056us late!
Trigger Nr. 125 is 646.912us late!
Trigger Nr. 128 is 434.944us late!
Trigger Nr. 175 is 646.912us late!
Trigger Nr. 178 is 439.04us late!
Trigger Nr. 225 is 646.912us late!
Trigger Nr. 228 is 440.064us late!
Trigger Nr. 275 is 647.168us late!
Trigger Nr. 278 is 434.944us late!
Trigger Nr. 325 is 611.84us late!
Trigger Nr. 328 is 462.08us late!
Trigger Nr. 375 is 612.864us late!
Trigger Nr. 378 is 475.136us late!
Trigger Nr. 425 is 619.008us late!
Trigger Nr. 428 is 473.856us late!
Trigger Nr. 475 is 613.888us late!
Trigger Nr. 478 is 467.968us late!
Trigger Nr. 525 is 612.864us late!
Trigger Nr. 528 is 474.88us late!
Trigger Nr. 575 is 613.12us late!

Does anyone know how I could improve my code?
Code:
//GPS DEFINITIONS
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 6); //232_TX,232_

int triggerFreq = 50;
unsigned long timestamp_pps;
//unsigned long timestamp;
unsigned long triggerStartTime;
const unsigned long dt_pps = 1000000; //micros
//const unsigned long dt_trig = 1000000/triggerFreq; //micros
unsigned long ts_pps_high;
unsigned long ts_pps_low;
unsigned long ts_msg_high;
unsigned long ts_msg_low;

unsigned long i_pps = 0;
//unsigned long i_trig = 0;

int hh = 04;
int mm = 51;
int ss = 00;
unsigned int pos = 2307;
bool msg;
bool trigMsgSent;

void setup() {

  cli();//stop interrupts
  //set timer1 interrupt at 1Hz
  TCCR1A = 0;// set entire TCCR1A register to 0
  TCCR1B = 0;// same for TCCR1B
  TCNT1  = 0;//initialize counter value to 0
  // set compare match register for 1hz increments
  //OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
  OCR1A = 19999; // = (16*10^6) / (100 * 8) -1 (must be <65536)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // Set CS11 bit for 8 prescaler
  TCCR1B |= (1 << CS11);
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  sei();//allow interrupts

  // GPS SETUP
  pinMode(11, OUTPUT); // PPS
  pinMode(12, OUTPUT); // Indicator of msg_sent
  pinMode(13, OUTPUT); // FPS
  Serial.begin(9600);
  mySerial.begin(9600);
  triggerStartTime = micros();

}

ISR(TIMER1_COMPA_vect){  //change the 0 to 1 for timer1 and 2 for timer2
   //interrupt commands here
   digitalWrite(13,!digitalRead(13));
}

void loop() {
  // ================== Part for the GPS Simulation ==================
  timestamp_pps = micros()-triggerStartTime;
  if (timestamp_pps>= dt_pps*i_pps+350000)
  {
    pos += 1;
    digitalWrite(12,HIGH);
    i_pps +=1;
    if (ss == 59)
    {
      ss=0;
      if (mm==59)
      {
        mm=0;
        hh+=1;
      }
      else mm+=1;
    }
    else ss+=1;

    ts_msg_high = micros();
    mySerial.print("$GPRMC,");
    if (hh<10) mySerial.print(F("0"));
    mySerial.print(hh);
    if (mm<10) mySerial.print(F("0"));
    mySerial.print(mm);
    if (ss<10) mySerial.print(F("0"));
    mySerial.print(ss);
    mySerial.print(".000,A,3015.");
    mySerial.print(pos);
    mySerial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");

    // Print Debug Messages
    digitalWrite(12,LOW);
    ts_msg_low=micros();
    Serial.print("PPS at: ");
    Serial.print(ts_pps_high);
    Serial.print("\t PPS low after: ");
    Serial.print(ts_pps_low-ts_pps_high);
    Serial.print("\t MSG high after: ");
    Serial.print(ts_msg_high-ts_pps_high);
    Serial.print("\t MSG low after: ");
    Serial.print(ts_msg_low-ts_pps_high);
    Serial.print("$GPRMC,");
    if (hh<10) Serial.print(F("0"));
    Serial.print(hh);
    if (mm<10) Serial.print(F("0"));
    Serial.print(mm);
    if (ss<10) Serial.print(F("0"));
    Serial.print(ss);
    Serial.print(".000,A,3015.");
    Serial.print(pos);
    Serial.println(",N,09749.2872,W,0.67,161.46,030913,,,A*7C");
  }
  else if (timestamp_pps>=dt_pps*i_pps+100000)
  {
    digitalWrite(11,LOW);
    if (msg==true)
    {
      msg = false;
      ts_pps_low = micros();
    }

  }
  else if (timestamp_pps>=dt_pps*i_pps)
  {
    digitalWrite(11,HIGH);
    if (msg==false)
    {
      msg = true;
      ts_pps_high = micros();
    }
  }

}

You may try to run task2 from a timer interrupt: this way it will be able to interrupt task1. Do a web search for “Arduino timer interrupt”.

Here lies your ≈ ½ ms problem:

#include <SoftwareSerial.h>

SoftwareSerial is very time sensitive. It generates the serial stream by
bit-banging, with interrupts disabled. For each byte sent, interrupts
are disabled just before sending the start bit, and re-enabled just
after the stop bit has been written. At 9600 bps, interrupts are
thus disabled for a little more than 9 bit times on each byte, i.e.
936 µs.
Do not use SoftwareSerial if you need short interrupt latency. Use a
hardware serial port instead. This can be problematic on the Uno, where
you would loose the ability to send debugging info, but it is fine on
the Leonardo.
Alternatively, if the only thing your ISR has to do is toggle a pin,
you can instead configure the timer to generate that as PWM. This way
the CPU is not involved at all in the pin toggling, and you get
cycle-accurate signal timing irrespective of interrupt latency.

Edit: Answering your comment.
About the hardware serial ports: on the Uno you just have Serial, so
you are out of luck if you want one port for outputting NMEA sentences
and another one for debugging information. However, on the Leonardo,
Serial is a virtual serial port emulated over USB. The real hardware
serial port is called Serial1, and you should use it in preference to
a SoftwareSerial instance.
About “more than just toggle the pin”: You may still be able to use PWM
if whatever other stuff task2 has to perform is less time-critical than
toggling the pin. In this case, you use PWM to toggle the pin on the
TIMER1_COMPA event, and ISR(TIMER1_COMPA_vect) to do the other
stuff. Then, each time the timer hits TIMER1_COMPA, it will
immediately toggle the pin and, at the same time, rise an interrupt
request. The CPU may take some time to service the request, but this
delay could be acceptable if only the toggling needs extra-accurate
timing.

What do you mean by "Use a hardware serial port instead"? How would you implement this?
I will need to to more than just toggle the pin. It's just not implemented yet

@MarayJay: See amended answer.

Two possible solutions:

Split the serial string in small pieces so it's (comfortably) less than 50 ms and send the string in 'pieces' … you could even send it until e.g. 45 ms has been reached and continue in the next round. Use the Blink Without Delay mechanism to switch between the tasks.
More robust solution: Make Task 2 an interrupt... This is probably much easier, since you can keep sending the serial string and the MCU takes care of automatically starting the interrupt each 50 ms. Make sure the interrupt code is very short. When it is finished, it will automatically resume with the normal code (sending serial data). I have not checked this library, but it seems very simple to use: https://playground.arduino.cc/Code/Timer/ .

Thanks! I implemented it with an interrupt. I'm not sure where I should post my solution code? Should i edit your answer or update my question?

It's not mandatory but it may help others, so it's always good... I would create a new answer. Good luck with your project.


text:
Quiescent Current Analog Input ESP8266
I'm planning an ESP8266 project, where I connect a soil moisture sensor to an ESP8266 chip (only the chip, not a board like the NodeMCU) (Analog Input). Since the whole setup will be battery-powered, I'm trying to minimize the quiescent current as much as possible. Now my question is: is there a quiescent current through the analog input pin of the ESP8266? and if yes, how large is this current approximately?
Thanks in advance

If your moisture sensor uses dc, consider watching this video: https://www.youtube.com/watch?v=udmJyncDvw0

That depends on if you're using a NodeMCU or a "naked" ESP8266.
The NodeMCU has a fixed voltage divider with 220K/100K resistors to ground, contributing about 10 µA to quiescent current (plus the much smaller current caused by the ADC input impedance).
If you're using a NodeMCU you also have to worry about the USB-to-Serial chip and the on-board voltage stabilizer.
The input impedance of the ADC input of a "naked" ESP8266 is (probably) a lot higher, 1 or more MΩ, although it is almost impossible to find definitive numbers.

Thanks for your answer. I was also looking for definitive numbers, but couldn't find any. I'm currently switching from the NodeMCU to the naked ESP8266, so your answer fits perfectly :) However if anyone finds out the definitive numbers, please post them here :)


text:
Arduino GPS Simulator: SoftwareSerial Issues
For my project, i need my Arduino Uno to simulate a GPS. To do this, I need to:

Generate a 5V Pulse once a second (no problem)
Send a $GPRMC NMEA sentence with the current time over RS-232 (i've got an RS-232 shield)

The GPRMC message i need to send is the following:
$GPRMC,075832.293,A,4042.695,N,07400.796,W,,,080120,000.0,W*63
Where the first part is the time, and needs to change.
I basically implemented it as:
// Setup
String prefix = "$GPRMC,";
String gprmc  = "075832.293";
String suffix = ",A,4042.695,N,07400.796,W,,,080120,000.0,W*63";
String all = prefix + gprmc + suffix;
char* buff = (char*) malloc(sizeof(char)*all.length()+1);

Then, in the loop-code i update the time and want to send the message:
//...inside the condition that gets executed once a second
gprmc = String(gprmc.toFloat()+1);
all = prefix+gprmc+suffix;
all.toCharArray(buff, all.length()+1);
mySerial.write(buff);

I'm using an RS-232 shield, which shows me when a message is being sent by blinking an LED.
However, is only seems to work, if i shorten the all string, i.e.:
Works:
all = prefix+gprmc;

Does not work:
all = prefix+gprmc+suffix;

Is it possible that the message is just too long to send? Is there a way I can fix this? Because it's crucial to send the whole message.
Note: I'm currently working on an Arduino Uno, but I'm switching to an arduino Leonardo today. I currently have low memory available (77% used). could this add to the problem?
Thank you so much for your help!! :)

What do you mean with "does not work"? What did you expect and what actually happens?

On the RS-232 Shield, an LED blinks if a message is sent. By "doesn't work" i mean, no message is sent (led no blinking)

First off, some comments about your code:

Never use String unless it is absolutely unavoidable
Unless you have a free() to balance your malloc() you will run out of memory almost immediately
There is never any need to concatenate strings to send through serial like that.

Instead of what you are currently doing, just scrap the String usage and your buf variable completely.  There is no need to concatenate things together - serial sends data one character at a time, so you're gaining nothing by concatenating and only causing yourself more problems.
How you should be doing it:
// The changing value as a float
float gprmc=75832.293;
// Print the prefix
mySerial.print(F("$GPRMC,"));
// Pad the value with zeroes
if (gprmc < 10) mySerial.print(F("0"));
if (gprmc < 100) mySerial.print(F("0"));
if (gprmc < 1000) mySerial.print(F("0"));
if (gprmc < 10000) mySerial.print(F("0"));
if (gprmc < 100000) mySerial.print(F("0"));
// Print the value with 3 decimal places
mySerial.print(gprmc, 3);
// Finally print the suffix
mySerial.println(F(",A,4042.695,N,07400.796,W,,,080120,000.0,W*63"));

Note the use of the F() macro to further reduce RAM usage by keeping the string constants in flash memory.

Thank you! Is there any difference on how the message will be transmitted by using mySerial.print(...) or mySerial.write(...)? somehow, the example uses the .write() command, which introduced my problems.

No. print just calls write but accepts more parameter types.


text:
Pressure Switch 4-20mA
Im working on a project trying to read the pressure value from an Allen Bradley Pressure Transmitter 836P-D2NFGB20PA-D4 Ser.A

However the pin configuration that comes on the description along with the schematics its way different that the one i used before

And the circuit im using is like this one, on the top its the circuit from the pressure documentation, and the bot one it the one im wiring on my Arduino Uno.
However on arduino im reading a constant value of 230 that does not increase nor decrease when i apply pressure to mi sensor even when the lcd on my sensor displays the correct psi value.

#include <LiquidCrystal.h> //libreria
int V0 = 3;
int RS= 4;
int E = 5;

int D4 = 6;
int D5 = 7;
int D6 = 8;
int D7 = 9;
LiquidCrystal lcd(RS, E, D4, D5, D6, D7); //Indicar los pins de la interfaz

//Variables globales
int SensorPin= 0; //Variable del pin de entrada del sensor
int indice; //posicion del array de textos
int presion; //variable para almacenar el valor obtenido del sensor(0 a 1023)
int outputValue = 0;
int state = 0;
int prv_state = -1;

#define ARRAYTXT 4 //Numero de textos a escribir

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

Serial.begin(9600);
analogWrite(V0, 50);

//lcd.begin(16, 2);
//lcd.clear();
//lcd.begin(Cols, Rows);
}

void loop() {

 //Configuramos un comando de textos
  String textos[ARRAYTXT] = {"Baja presion", "Presion normal", "Alta presion", "Apagar Maquina"};

  presion = analogRead(SensorPin); //obtenemos datos del sensor
    outputValue = map(presion, 175, 1023, 0, 367);

//Indicamos los textos que se definieron en el comando texto al principio("Baja presion" = 0)
  if(outputValue < 50){
    indice = 0;
  } else{
    if(outputValue >=50 && outputValue < 100){
      indice = 1;
    }else{
      if(outputValue >=100 && outputValue < 200){
        indice = 2;
      }else{
        if(outputValue >=200 && outputValue < 350){
          indice= 3;
        }
      }
    }
  }
  //lcd.clear(); // se borran pantallas
  //lcd.setCursor(0, 0); //Escribimos en la fila de abajo
  Serial.print("PRESION: "); // escribimos mensaje en el lcd
  Serial.print(outputValue,DEC);
  Serial.println(" PSI");
  //lcd.setCursor(0, 1); //Escribimos en la fila de abajo
  Serial.println(textos[indice]); // Indicamos que imprima los indices
  //Serial.print("Psi ");
  //Serial.println(outputValue);
  delay(200); //Tiempo para repetir el mensaje(1 segundo)
  //lcd.clear();
}

Try disconnecting pin 4.

I tried disconnecting the pin4 (OUT) and there is no difference, the serial port on arduino ide is -75psi or 270psi but it does not increment or decrement.

pin 4 appears to be a voltage output ... disconnect the current loop (pin 2) .... or put a resistor between pin 2 and pin 4 and measure the voltage across the resistor

Here is a similar situation, at the very least it has useful information for you.
Search for "reading-4-to-20ma-pressure-sensor-using-uno" here at stackexchange.

Your drawing is different from the drawing in the wiring diagram of that sensor: the resistor has to be connected right like the "4-20mA"-block in the drawing, (-) goes to ground. Measure the voltage directly at pin 2.
When reading the sensor's analog signal you can probably leave pin 4 floating.

I changed the "4-20mA" block for a 250k ohm resistor and measured the current just before the resistor and it still 0

250k or 250? And where is "before" the resistor?

My mistake, 250ohms, still no change at all, the votlage on pin2 (suposedly the output for 4-20ma) its constantly 3v

3V corresponds to a current of 12mA and in the comment above you wrote that you measured 0mA...?

So you must be doing sth wrong or didn‘t tell us everything


text:
How to configure 8*8 Dot Matrix LED display with this particular code?
I'm making a cryptocurrency ticker using NodeMCU ESP8266 and have this code so far,  I don't know how to configure a dot matrix led 4 segments of 8*8 each with this particular code. The only thing I need is correction is the initialization of the display.
Here's the code:
/*******************************************************************
    A project to display crypto currency prices using an ESP8266

    Main Hardware:
    - NodeMCU Development Board (Any ESP8266 dev board will work)
    - dot matrix led 4 segments of 8*8

    Written by Brian Lough
    https://www.youtube.com/channel/UCezJOfu7OtqGzd5xrP3q6WA
 *******************************************************************/

// ----------------------------
// Standard Libraries - Already Installed if you have ESP8266 set up
// ----------------------------

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <Wire.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#define MATRIX32
#include  <SPI.h>

// ----------------------------
// Additional Libraries - each one of these will need to be installed.
// ----------------------------

#include <CoinMarketCapApi.h>
// For Integrating with the CoinMarketCap.com API
// Available on the library manager (Search for "CoinMarket")
// https://github.com/witnessmenow/arduino-coinmarketcap-api

//#include "SH1106.h"
// The driver for the OLED display
// Available on the library manager (Search for "oled ssd1306")
// https://github.com/squix78/esp8266-oled-ssd1306

#include <ArduinoJson.h>
// !! NOTE !!: When installing this select an older version than V6 from the drop down
// Required by the CoinMarketCapApi Library for parsing the response
// Available on the library manager (Search for "arduino json")
// https://github.com/squix78/esp8266-oled-ssd1306

// ----------------------------
// Configurations - Update these
// ----------------------------

char ssid[] = "rum1";       // your network SSID (name)
char password[] = "@@mywifi34@@";  // your network key

// Pins based on your wiring
#define MAX_DEVICES 4
#define CLK_PIN 13
#define DATA PIN 11
#define CS_PIN 10

//#define SCL_PIN D5
//#define SDA_PIN D4

// CoinMarketCap's limit is "no more than 10 per minute"
// Make sure to factor in if you are requesting more than one coin.
// We'll request a new value just before we change the screen so it's the most up to date
unsigned long screenChangeDelay = 10000; // Every 10 seconds

// Have tested up to 10, can probably do more
#define MAX_HOLDINGS 10

#define CURRENCY "eur" //See CoinMarketCap.com for currency options (usd, gbp etc)
#define CURRENCY_SYMBOL "E" // Euro doesn't seem to work, $ and £ do

// You also need to add your crypto currecnies in the setup function

// ----------------------------
// End of area you need to change
// ----------------------------

WiFiClientSecure client;
CoinMarketCapApi api(client);

display.begin(CS_PIN, MAX_DEVICES);

MD_Parola P = MD_Parola(CS_PIN, MAX_DEVICES);

//MD_Parola.h display(0x3c, SDA_PIN, SCL_PIN);

unsigned long screenChangeDue;

struct Holding {
  String tickerId;
  float amount;
  bool inUse;
  CMCTickerResponse lastResponse;
};

Holding holdings[MAX_HOLDINGS];

int currentIndex = -1;
String ipAddressString;

void addNewHolding(String tickerId, float amount = 0) {
  int index = getNextFreeHoldingIndex();
  if (index > -1) {
    holdings[index].tickerId = tickerId;
    holdings[index].amount = amount;
    holdings[index].inUse = true;
  }
}

void setup() {

  Serial.begin(115200);

  // ----------------------------
  // Holdings - Add your currencies here
  // ----------------------------
  // Go to the currencies coinmarketcap.com page
  // and take the tickerId from the URL (use bitcoin or ethereum as an example)

  addNewHolding("bitcoin");
  addNewHolding("dogecoin");
  addNewHolding("ethereum");

  // ----------------------------
  // Everything below can be thinkered with if you want but should work as is!
  // ----------------------------

  // Initialising the display
  display.init();
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_16);
  display.drawString(64, 0, F("HODL Display"));
  display.setFont(ArialMT_Plain_10);
  display.drawString(64, 18, F("By Brian Lough"));
  display.display();

  // Set WiFi to station mode and disconnect from an AP if it was Previously
  // connected
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);

  // Attempt to connect to Wifi network:
  Serial.print("Connecting Wifi: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  IPAddress ip = WiFi.localIP();
  Serial.println(ip);
  ipAddressString = ip.toString();
}

int getNextFreeHoldingIndex() {
  for (int i = 0; i < MAX_HOLDINGS; i++) {
    if (!holdings[i].inUse) {
      return i;
    }
  }

  return -1;
}

int getNextIndex() {
  for (int i = currentIndex + 1; i < MAX_HOLDINGS; i++) {
    if (holdings[i].inUse) {
      return i;
    }
  }

  for (int j = 0; j <= currentIndex; j++) {
    if (holdings[j].inUse) {
      return j;
    }
  }

  return -1;
}

void displayHolding(int index) {

  CMCTickerResponse response = holdings[index].lastResponse;

  display.clear();

  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.setFont(ArialMT_Plain_16);
  display.drawString(64, 0, response.symbol);
  display.setFont(ArialMT_Plain_24);
  double price = response.price_currency;
  if (price == 0) {
    price = response.price_usd;
  }
  display.drawString(64, 20, formatCurrency(price));
  display.setFont(ArialMT_Plain_16);
//  display.setTextAlignment(TEXT_ALIGN_CENTER);
//  display.drawString(64, 48, " 1h:" + String(response.percent_change_1h) + "%");
  display.setTextAlignment(TEXT_ALIGN_CENTER);
  display.drawString(64, 48, "24h: " + String(response.percent_change_24h) + "%");

  display.display();
}

void displayMessage(String message){
  display.clear();
  display.setFont(ArialMT_Plain_10);
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawStringMaxWidth(0, 0, 128, message);
  display.display();
}

String formatCurrency(float price) {
  String formattedCurrency = CURRENCY_SYMBOL;
  int pointsAfterDecimal = 6;
  if (price > 100) {
    pointsAfterDecimal = 2;
  } else if (price > 1) {
    pointsAfterDecimal = 4;
  }
  formattedCurrency.concat(String(price, pointsAfterDecimal));
  return formattedCurrency;
}

bool loadDataForHolding(int index) {
  int nextIndex = getNextIndex();
  if (nextIndex > -1 ) {
    holdings[index].lastResponse = api.GetTickerInfo(holdings[index].tickerId, CURRENCY);
    return holdings[index].lastResponse.error == "";
  }

  return false;
}

void loop() {
  unsigned long timeNow = millis();
  if ((timeNow > screenChangeDue))  {
    currentIndex = getNextIndex();
    if (currentIndex > -1) {
      if (loadDataForHolding(currentIndex)) {
        displayHolding(currentIndex);
      } else {
        displayMessage(F("Error loading data."));
      }
    } else {
      displayMessage(F("No funds to display. Edit the setup to add them"));
    }
    screenChangeDue = timeNow + screenChangeDelay;
  }
}

And here's the error:
crytodisplayDraft1:82:1: error: 'display' does not name a type

 display.begin(CS_PIN, MAX_DEVICES);

 ^

C:\Users\SUDU0005\Documents\Arduino\crytodisplayDraft1\crytodisplayDraft1.ino: In function 'void setup()':

crytodisplayDraft1:130:3: error: 'display' was not declared in this scope

   display.init();

   ^

crytodisplayDraft1:131:28: error: 'TEXT_ALIGN_CENTER' was not declared in this scope

   display.setTextAlignment(TEXT_ALIGN_CENTER);

                            ^

crytodisplayDraft1:132:19: error: 'ArialMT_Plain_16' was not declared in this scope

   display.setFont(ArialMT_Plain_16);

                   ^

crytodisplayDraft1:134:19: error: 'ArialMT_Plain_10' was not declared in this scope

   display.setFont(ArialMT_Plain_10);

                   ^

C:\Users\SUDU0005\Documents\Arduino\crytodisplayDraft1\crytodisplayDraft1.ino: In function 'void displayHolding(int)':

crytodisplayDraft1:191:3: error: 'display' was not declared in this scope

   display.clear();

   ^

crytodisplayDraft1:193:28: error: 'TEXT_ALIGN_CENTER' was not declared in this scope

   display.setTextAlignment(TEXT_ALIGN_CENTER);

                            ^

crytodisplayDraft1:194:19: error: 'ArialMT_Plain_16' was not declared in this scope

   display.setFont(ArialMT_Plain_16);

                   ^

crytodisplayDraft1:196:19: error: 'ArialMT_Plain_24' was not declared in this scope

   display.setFont(ArialMT_Plain_24);

                   ^

C:\Users\SUDU0005\Documents\Arduino\crytodisplayDraft1\crytodisplayDraft1.ino: In function 'void displayMessage(String)':

crytodisplayDraft1:212:3: error: 'display' was not declared in this scope

   display.clear();

   ^

crytodisplayDraft1:213:19: error: 'ArialMT_Plain_10' was not declared in this scope

   display.setFont(ArialMT_Plain_10);

                   ^

crytodisplayDraft1:214:28: error: 'TEXT_ALIGN_LEFT' was not declared in this scope

   display.setTextAlignment(TEXT_ALIGN_LEFT);

                            ^

Multiple libraries were found for "Wire.h"
 Använd: C:\Users\SUDU0005\Documents\ArduinoData\packages\esp8266\hardware\esp8266\2.6.3\libraries\Wire
Oanvänd: C:\Users\SUDU0005\Documents\Arduino\libraries\Wire
exit status 1
'display' does not name a type

So, how do I configure the display?

does the display library include an example sketch? ... if it does, then use it to figure out how to drive the display

//#include "SH1106.h" this is a comment

Isn't it used only for OLED displays? I have a dot matrix led.

then why do you ask about error: 'display' does not name a type?

That is the error thrown by the compiler, and it is asking for the display's type as I haven't mentioned it - which is part of my question.

First and major point, is that if you want to repeat existing device, then you have wrong hardware. Comments in the code tell us:
 Main Hardware:
- NodeMCU Development Board (Any ESP8266 dev board will work)
- **OLED I2C Display (SH1106)**

You have dot matrix display with MAX7219 chip (most likely), which uses completely different library to work with. Microcontrollers are not like PCs, if you change a display, you should seriously rework the code. All code like display.something() has to be re-written. MD_Parola seems to be a library for interfacing your dot matrix display. You instantiate an object of that library: MD_Parola P = MD_Parola(CS_PIN, MAX_DEVICES); but then never use created object P anywhere (also, this a bad name for an object. display or matrix are much better). Instead, code uses object display, which is never created - that's exactly what compiler is trying to tell you:
error: 'display' was not declared in this scope

So. to summarize: in order to change your code, you have to study MD_Parola lib, and seriously change all functions related to display. Obviously, that's beyond a scope of a simple question...

I see your point. Could you link me to some documents where I can learn how to configure dot matrix display with MD_Parola or MAX7219, I tried many google links but they don't seem to lead me toward anything useful.

This lib is hosted here: https://github.com/MajicDesigns/MD_Parola. It seems to be well documented, and have a lot of examples. Start with them, see if you understand a wiring and major functions correctly. Alternatively, try this lib from famous Nick Gammon: https://github.com/nickgammon/MAX7219. Or consider buying OLED display, they look very nice, even Chinese ones. Anyway, don't try to create huge program at once, instead test it point by point (WiFi, display, etc - all separately. If you think my answer was useful, please tick it as accepted.

It is informative but not useful to me. I just read all of this - https://majicdesigns.github.io/MD_MAX72XX/index.html and can only think of replacing the existing code pertaining to the same functions such as a display.setFont(); Also, I only want to make this using dot matrix led, the OLED looks nice but it is pretty small and the big one is just not worth it.

Well, you can't expect someone to write a firmware for you) On this site you can get a hint or a direction where to look further, but probably not a turnkey solution. Have a good luck!


text:
How to Set the Control Register on the DS3231 RTC module for Arduino UNO R3?
I am using the DS3231 RTC connected to an Arduino UNO R3 for a project. I won’t go into detail, but I need to save power, therefore I am using the DS3231 Alarm Interrupt to wake the Arduino from sleep. The Alarm Interrupt works fine when the Arduino is sleeping and connected to the 5V and GND pins of the Arduino, however it turns out that the DS3231 won’t fire a square wave interrupt when on battery power. In order to turn it on, I need to set bit 7 of the Control Register (0Eh) to logic 1, and bit 6 to logic one. I can’t find any documentation on how to do this, except for a few forums talking about it. What is the specific code to do this, and where would I place the code?
DS3231 Data Sheet (Control Register on p.13)
#include <Wire.h>
#include <RTClibExtended.h>
#include <LowPower.h>

#define wakePin 2    //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
#define ledPin 13    //use arduino on-board led for indicating sleep or wakeup status

RTC_DS3231 RTC;      //we are using the DS3231 RTC

byte AlarmFlag = 0;
byte ledStatus = 1;

//-------------------------------------------------

void wakeUp()        // here the interrupt is handled after wakeup
{
}

//------------------------------------------------------------

void setup() {
  //digitalWrite(wakePin,HIGH);
  //Set pin D2 as INPUT for accepting the interrupt signal from DS3231
  pinMode(wakePin, INPUT);

  //switch-on the on-board led for 1 second for indicating that the sketch is ok and running
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  delay(1000);

  //Initialize communication with the clock
  Wire.begin();
  RTC.begin();
  RTC.adjust(DateTime(__DATE__, __TIME__));   //set RTC date and time to COMPILE time

  //clear any pending alarms
  RTC.armAlarm(1, false);
  RTC.clearAlarm(1);
  RTC.alarmInterrupt(1, false);
  RTC.armAlarm(2, false);
  RTC.clearAlarm(2);
  RTC.alarmInterrupt(2, false);

  //Set SQW pin to OFF (in my case it was set by default to 1Hz)
  //The output of the DS3231 INT pin is connected to this pin
  //It must be connected to Arduino D2 pin for wake-up
  RTC.writeSqwPinMode(DS3231_OFF);

  //Set alarm1 every day at 18:33
  RTC.setAlarm(ALM1_MATCH_HOURS, 16, 19, 0);   //set your wake-up time here
  RTC.alarmInterrupt(1, true);
}

//------------------------------------------------------------

void loop() {

  //On first loop we enter the sleep mode
  if (AlarmFlag == 0) {
    attachInterrupt(0, wakeUp, LOW);                       //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW
    digitalWrite(ledPin, LOW);                             //switch-off the led for indicating that we enter the sleep mode
    ledStatus = 0;                                         //set the led status accordingly
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);   //arduino enters sleep mode here
    detachInterrupt(0);                                    //execution resumes from here after wake-up

    //When exiting the sleep mode we clear the alarm
    RTC.armAlarm(1, false);
    RTC.clearAlarm(1);
    RTC.alarmInterrupt(1, false);
    AlarmFlag++;
  }

  //cycles the led to indicate that we are no more in sleep mode
  if (ledStatus == 0) {
    ledStatus = 1;
    digitalWrite(ledPin, HIGH);
  }
  else {
    ledStatus = 0;
    digitalWrite(ledPin, LOW);
  }

  delay(500);
}

Also, how would I set it to go to sleep after the alarm?
Thanks!
P.s sorry about that Thomas, I'm a bit new here.

What RTC library are you using? Do you know how to directly address an I2C device using the Wire library?

You have a pullup resistor on the line also, yes?

I took a look at the FabioCuomo-DS3231 library, as I
guess that is what you are using, and I saw nothing related to setting
those two bits. However, you can take inspiration from the code in the
library to implement the functionality yourself.
I would try this:
void enableAlarmInLowPower(void) {
    // Read the control register.
    Wire.beginTransmission(DS3231_ADDRESS);
    Wire.write(DS3231_CONTROL);
    Wire.endTransmission();
    Wire.requestFrom((uint8_t)DS3231_ADDRESS, (uint8_t)1);
    uint8_t value = Wire.read();
    Wire.endTransmission();

    // Update it.
    value |= bit(6) | bit(7);  // set bits 6 and 7

    // Write it back.
    Wire.beginTransmission(DS3231_ADDRESS);
    Wire.write(DS3231_CONTROL);
    Wire.write(value);
    Wire.endTransmission();
}

Warning: not tested.


text:
HTTP Post data from Arduino uno using WiFi
Please help me to post data from arduino uno to a webpage using wifi(ESP-01) module. I try with AT commands it didn't give the response from my webpage

#include <SoftwareSerial.h>
#include <ArduinoJson.h>
#define DEBUG true

#define RX 10
#define TX 11
String WIFI_SSID = "*****";       // Your WiFi ssid
String PASSWORD = "*****";         // Password
//String DEVICE_SECRET_KEY  = "**";

//String PATH = "/v1/events";
//String PORT = "8000";
//String HOST = "http://10.**.***.66:8000/data";

String HOST = "10.**.240.**";
String PATH = "/data";
String PORT = "8000";

String response;
int countTrueCommand;
int countTimeCommand;
boolean found = false;

SoftwareSerial esp8266(RX, TX);
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();

void setup()
{
  Serial.begin(115200);
  esp8266.begin(115200);
  esp8266.println("AT");
  Serial.println(esp8266.read());
  sendCommandToESP8266("AT", 5, "OK");
   sendCommandToESP8266("AT+CWMODE=3", 5, "OK");
  sendCommandToESP8266("AT+CWJAP=\"" + WIFI_SSID + "\",\"" + PASSWORD + "\"", 20, "OK");
}

void loop()
{
  root["key"] =  "sdfsdfsd";
  String key;
  root.printTo(key);
  String postRequest =   "POST " + PATH  + " HTTP/1.1\r\n" +
                         "Host: " + HOST + "\r\n" +
                         "Accept: *" + "/" + "*\r\n" +
                         "Content-Length: " + key.length() + "\r\n" +
                         "Content-Type: application/json\r\n"
                         "\r\n" + key;
  Serial.print("pst:" + postRequest);
  sendCommandToESP8266("AT+CIPMUX=1", 5, "OK");
  sendCommandToESP8266("AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT, 15, "OK");
  String cipSend = "AT+CIPSEND=0," + String(postRequest.length());//GET /test.php?Data=2\r\nHost:192.168.1.13\r\n\r\n
  sendCommandToESP8266(cipSend, 4, ">");
  sendData(postRequest);

  while (esp8266.available())
  {
    if (esp8266.find("+IPD,"))
    {
//      String msg;
      esp8266.find("?");
//      msg = esp8266.readStringUntil(' ');
      response = esp8266.readStringUntil(' ');
      Serial.print(response);
      Serial.println();
    }
  }
  printResponse;

  //  sendCommandToESP8266("AT+CIPCLOSE=0", 5, "OK");
}

void sendCommandToESP8266(String command, int maxTime, char readReplay[]) {
  Serial.print(countTrueCommand);
  Serial.print(". at command => ");
  Serial.print(command);
  Serial.print(" ");
  while (countTimeCommand < (maxTime * 1))
  {
    esp8266.println(command);
    if (esp8266.find(readReplay))
    {
      found = true;
      break;
    }

    countTimeCommand++;
  }

  if (found == true)
  {
    Serial.println("Success");
    countTrueCommand++;
    countTimeCommand = 0;
  }

  if (found == false)
  {
    Serial.println("Fail");
    countTrueCommand = 0;
    countTimeCommand = 0;
  }

  found = false;
}

void sendData(String postRequest) {
  Serial.println(postRequest);
  Serial.println();
  esp8266.println(postRequest);
  delay(15000);
  countTrueCommand++;
}

void printResponse() {
  while (esp8266.available()) {
    Serial.println();
    Serial.println(esp8266.readStringUntil('\n'));
  }
}

Please help me to get the response from the webpage using this code.

SoftwareSerial doesn't work at 115200 baud. change the baud rate in AT firmware and for SoftwareSerial to 9600 baud.

@Juraj i try by changing the baud rate but still there is no response from my webpage

@Juraj Or please let me know that if there is any another way to post data from arduino uno by using wifi.(ESP01 module).   I see many programs that are using ethernet and anothehr wifi modules.

if you want something like Ethernet library you can use my WiFiEspAT library. but it requires to change the AT firmware in esp-01 to version 1.7 https://github.com/jandrassy/WiFiEspAT/blob/master/README.md

@Juraj can i use the above mentioned library with arduino uno and esp01?   Iam a beginner in arduino programming that's why asking about these questions.

the WiFiEspAT library handles the AT commands for you. the wiring is same has you have now

@Juraj I just want to know how to change the version of esp-01 to versio 1.7. Is esp-01 works when version is not changed?

with old AT firmware you can use the old WiFiEsp library.

@Juraj https://github.com/bportaluri/WiFiEsp/blob/master/examples/ConnectWPA/ConnectWPA.ino I try to use this code but it shows as wifi shield is not present.

set 9600 baud in AT firmware. the libraries are in Library Manager in IDE

@Juraj when i use the library   i got the below output on serial monitor.                                                                      [WiFiEsp] Initializing ESP module [WiFiEsp] >>> TIMEOUT >>> [WiFiEsp] >>> TIMEOUT >>> [WiFiEsp] >>> TIMEOUT >>> [WiFiEsp] >>> TIMEOUT >>> [WiFiEsp] >>> TIMEOUT >>> [WiFiEsp] Cannot initialize ESP module [WiFiEsp] >>> TIMEOUT >>> [WiFiEsp] No tag found WiFi shield not present

did you set the baud rate to 9600 baud in firmware and in sketch?

@juraj Sorry!! I forget to change the baud rate. Now wifi is getting connected using esp library. And can you please help me to post data from arduino using this library and how to get the response back from the server.

@juraj when i try to post data from arduino to webpage it will not sending the data and not connecting to server serial monitor shows as :
`Starting connection to server...
[WiFiEsp] Connecting to xxx.xx.xxx.xx
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] No tag found
Disconnecting from server...
`

Step 1) Upload software serial from example and send AT, you should get reply as AT OK if your connections are correct.
Step 2) Once your connections are correct and if you are uploading the given code then make sure you put your SSID, password, and Server IP which would be the three Strings: HOST, PATH and PORT.
You could alternatively check your server first by sending it a GET or POST using your browser or another software for testing API's(I personally use POSTMAN).
Proceed further once you perform these checks.

I tried this and still not getting response from the webpage. Also API have no problems when i check it.

Did you try the AT command check? Upload software serial and you can manually enter AT commands and check where you are going wrong.

I have 2 esp-01 modules with me. I think one of my esp is corrupted. But other one is working when check by AT command.

Now you can check each command that is being used via Software Serial. For example according to your code if u send "AT+CWMODE=3" u will get a reply OK. You can do a complete post request just using software serial by inputting commands one after the other. Its a good practice to do this as it will help you understand at what point your code is going wrong.

I tried by sending all the AT commands and i stop where AT+CIPSTART=0,"TCP","xx.xxx.xxx.xx","port" from this command i got error message. what can i do to make it correct?

Try this command AT+CIPSTART="TCP","192.168.3.116",8080 Change the server ip and port accordingly. The 0 indicates id of the connection in AT+CIPSTART=0,"TCP","xx.xxx.xxx.xx","port" . I found the id being used only for a UDP connection in the espressif at command example. I referred this link. Did you execute the AT commands in the sequence given in your question?

I check with the AT commands. But   AT+CIPSTART="TCP","192.168.3.116",8080 this command is not working. I didin't understand what the problem is. All the other commands before AT+CIPSTART is working with the module.


text:
POST request using WiFiEsp.h library
I'm using an arduino uno and ESP8266 (esp01) with the WiFiEsp library to connect to WiFi and POST data, connecting to WiFi works just fine.
I need to send a POST request, but I can't get it to work as I want.
 #include "WiFiEsp.h"
 // Emulate Serial1 on pins 7/8 if not present
 #ifndef HAVE_HWSERIAL1
 #include "SoftwareSerial.h"
 SoftwareSerial Serial1(6, 7); // RX, TX
 #endif
 char ssid[] = "Innovating-Guest"; // your network SSID (name)
 char pass[] = "wireless"; // your network password
 int status = WL_IDLE_STATUS; // the Wifi radio's status

 char server[] = "10.66.240.66";//http://10.66.240.66:8000/loadimage
 WiFiEspClient client; // Initialize the Ethernet client object

 void setup()
 {
 // initialize serial for debugging
 Serial.begin(9600);
 // initialize serial for ESP module
 Serial1.begin(9600);
 // initialize ESP module
 WiFi.init(&Serial1);
 // check for the presence of the shield
 if (WiFi.status() == WL_NO_SHIELD)
 {
 Serial.println("WiFi shield not present");
 // don't continue
 while (true);
 }

 // attempt to connect to WiFi network
 while ( status != WL_CONNECTED) {
 Serial.print("Attempting to connect to WPA SSID: ");
 Serial.println(ssid);
 // Connect to WPA/WPA2 network
 status = WiFi.begin(ssid, pass);
 }
 // you're connected now, so print out the data
 Serial.println("You're connected to the network");
 printWifiStatus();
 Serial.println();
 Serial.println("Starting connection to server...");
 // if you get a connection, report back via serial
 if (client.connect(server, 8000)) {
 Serial.println("Connected to server");
 String temp= "12.22";
 String humd= "23.33";
 String batt= "100";

 String content ="{\"temperature\": + temp +,\"humidity\":+ humd +,\"batteryPer\": + batt + }";
 client.println("POST /loadimage HTTP/1.1");
 client.println("Host: 10.66.240.66:8000");
 client.println("Accept: */*");
 client.print("Content-Length: ");
 client.println(content.length());
 client.println("Content-Type: application/json");
 client.println();
 client.println(content);
 }
 }
 void loop()
 {

 while (client.available()) {
 char c = client.read();
 Serial.write(c);
 }
 // if the server's disconnected, stop the client
 if (!client.connected()) {
 Serial.println();
 Serial.println("Disconnecting from server...");
 client.stop();
 // do nothing forevermore
 while (true);
  }
 }

 void printWifiStatus()
 {
 // print the SSID of the network you're attached to
 Serial.print("SSID: ");
 Serial.println(WiFi.SSID());

 // print your WiFi shield's IP address
 IPAddress ip = WiFi.localIP();
 Serial.print("IP Address: ");
 Serial.println(ip);

 // print the received signal strength
 long rssi = WiFi.RSSI();
 Serial.print("Signal strength (RSSI):");
 Serial.print(rssi);
 Serial.println(" dBm");
 }

Can anyone help me to know that why this error is coming.
Thanks in advance.

POST /loadimage HTTP/1.1, with a space between POST and the uri.

@hcheung there is no change when use a space between POST and uri

Nevertheless, POST /uri HTTP/1.1 is the correct syntax for http POST command.

@hcheung I update with correction but POST is not happens by that. Is there any chnage in my server uri?? can you please help me

it looks like the server disconnects. if you can update the AT firmware to AT 1.7 (SDK 3), I recommend my WiFiEspAT library. in debug mode it shows all communication  with the AT firmware so it would be simpler to troubleshoot

Also change client.println("Content-Length: "); to client.print("Content-Length: ");

@Juraj `AT version:1.3.0.0(Jul 14 2016 18:54:01)
SDK version:2.0.0(5a875ba)

@hcheung I also try changing to client.print("Content-Length: "); It s not working now also.

I suspect, the problem is on the server side. So, you may use Wireshark or server logs to see, what exact query you are sending.

@gbg thanks for the reply. But the server side is done by another one and only duty i have is to post data obtained in arduino to the server. And when i try to send with nodemcu board it is working. So i think there is no problem with server side.

Okay, anyway, you can use the Wireshark to see, what exact bytes sends ESP to the server. To do this, your PC must be in the same WiFi network with the ESP

@gbg thanks for the help. Sorry but i can't post data now also.

Host should contain the port. So Host: 10.66.240.66:8000 should be Host: 10.66.240.66. Secondly; I think the JSON string isn't generated properly. I think it should be:  String content ="{\"temperature\":"+ temp +",\"humidity\":"+ humd + ",\"batteryPer\":" + batt + "}";

@Gerben thanks for the reply but by changing the host also there is no chnage. It shows as disconnecting from server now also. I don't have any idea what the problem is.

Is there even a problem? You'd expect the server to close the connection once it has received your request and send back a response. The only thing is that you'd expect to get back some response. Try temporarily removing the while (true); at the end of the loop and replace it with a delay(100);. Then see what happens

@Gerben, this is based on the Arduino WebClient example and the loop() works as it is to receive the HTTP response. but the client doesn't connect here at all

@Gerben I try by removing while(true); but same result cames.

@Juraj your are absolutely correct. Can you make any solutions other  than changing the esp version and library?

do you have an USB to TTL Serial adapter? wire the RX pin of the adapter to TX pin of the esp8266 additionally to the wire to Arduino. this way you can see everything the AT firmware sends to Arduino.

@Juraj I dont have an USB to TTL converter with me.