text:
Issue with Indenting the Serial Print data in the Serial Monitor
I have a question with Serial Print. I want the Sensor reading values to fall under 3 columns, and each column should have the readings from the same sensor.
Raw Value |    Sensor 1 |   Sensor 2  |   Sensor 3
how can I modify this code do this?
Below I have posted my code and what I currently see using the Serial Monitor
    void loop(){

  RawValue0 = analogRead(analogIn0);
  Voltage0 = (RawValue0 / 1023.0) * 5000; // 5000 to get millivots.
  tempC0 = (Voltage0-500) * 0.1; // 500 is the offset
  tempF0 = (tempC0 * 1.8) + 32; // conver to F
  Serial.print("Raw Value = " );  // shows pre-scaled value
  Serial.print(RawValue0);
  Serial.print("\t milli volts = "); // shows the voltage measured
  Serial.print(Voltage0,0); //
  Serial.print("\t Sensor 1: Temperature in C = ");
  Serial.print(tempC0,1);
  Serial.print("\t Sensor 1: Temperature in F = ");
  Serial.println(tempF0,1);
  delay(500);

you have no code for dealing with sensor 2 and sensor 3 ..... there is no way to modify non-existent  code

is this schoolwork?

you already know how to print in column format .... it is entirely unclear what you are having a problem with

think  very carefully about this .... do you really want Raw Value | Sensor 1 | Sensor 2 | Sensor 3?

Columns with lines?
The sprintf function can fill data with spaces to align them. However, the Arduino sprintf function does not support floating point variables. The dtostrf function has already a fixed output width by itself.
The sketch below is a combination of UTF-8 characters and the dtostrf and sprintf functions.
void setup() {
  Serial.begin(9600);

  Serial.println();
  Serial.println("┏━━━━━━┳━━━━━━━━┳━━━━━━━━┓");
  Serial.println("┃  raw ┃   °C   ┃   °F   ┃");
  Serial.println("┣━━━━━━╋━━━━━━━━╋━━━━━━━━┫");
}

void loop() {
  int raw = random(0, 1024);
  float c = random(-1000, 1000) / 10.0;
  float f = random(-500, 1500) / 10.0;

  char buffer_c[20];
  char buffer_f[20];

  dtostrf(c, 6, 1, buffer_c);
  dtostrf(f, 6, 1, buffer_f);

  char buffer[80];
  sprintf(buffer, "┃ %4d ┃ %s ┃ %s ┃", raw, buffer_c, buffer_f);
  Serial.println(buffer);

  delay(500);
}

The strlen() function can not be used before printing a floating point number to the serial port, since its length is determined while printing characters to the serial port. The final number of bytes that is written is the return value.
There is a way to use that return value, by using a dummy write to a dummy serial port. After that the number of spaces to align the floating point number can be calculated.
That reduces the code size from 6160 to 4708 for an Arduino Uno.
class DummyClass : public Stream
{
  int available() {return 0;}
  int read() {return 0;}
  int peek() {return 0;}
  void flush() {return;}
  size_t write(uint8_t) {return 1;}
  using Print::write;
};

DummyClass Dummy;

const int width_r = 4;
const int width_c = 6;
const int width_f = 6;

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

  Serial.println();
  Serial.println("┏━━━━━━┳━━━━━━━━┳━━━━━━━━┓");
  Serial.println("┃  raw ┃   °C   ┃   °F   ┃");
  Serial.println("┣━━━━━━╋━━━━━━━━╋━━━━━━━━┫");
}

void loop() {
  int raw = random(0, 1024);
  float c = random(-1000, 1000) / 10.0;
  float f = random(-500, 1500) / 10.0;

  int i;
  Serial.print("┃ ");
  Spaces(width_r - Dummy.print(raw));
  Serial.print(raw);
  Serial.print(" ┃ ");
  Spaces(width_c - Dummy.print(c,1));
  Serial.print(c,1);
  Serial.print(" ┃ ");
  Spaces(width_f - Dummy.print(f,1));
  Serial.print(f,1);
  Serial.print(" ┃");
  Serial.println();

  delay(500);
}

void Spaces(int n)
{
  for(int i=0; i<n; i++) {
    Serial.print(' ');
  }
}

I advise not to use this "Dummy" trick. It is mere a coding exercise. I can not find a problem with this trick, but I'm not 100% sure that it is okay.

use dtostrf for raw too and and save 1kB flash on sprintf

@Juraj I can do better than that. After reading your answer here: https://arduino.stackexchange.com/questions/62783/create-new-serial-class-inheriting-from-stream I tried a dummy class. To my surprise it worked.

Here is a sketch that uses a different approach than Jot uses in his answer. There is no question that Jot's answer is excellent and takes very few lines of code to accomplish.
I thought it would look nice if the Raw Value, an integer, was centered under the "Raw Value" column when it was at it's maximum value of 1023. A value of 1 would be right-ish justified, but still aligned with the center in mind.
The floating point numbers, which could be positive or negative, should be right justified I thought, so I wrote a second function to deal with those numbers.
int RawValue0;
float Voltage0, tempC0, tempF0;

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

  Serial.println();
  Serial.println("Raw Value | Sensor 1 | Sensor 2 | Sensor 3");
  Serial.println("------------------------------------------");

  RawValue0 = 1023; //analogRead(analogIn0);
  Voltage0 = 11.0; //(RawValue0 / 1023.0) * 5000; // 5000 to get millivots.
  tempC0 = -100.0; //(Voltage0-500) * 0.1; // 500 is the offset
  tempF0 = 1212.0; //(tempC0 * 1.8) + 32; // conver to F
}

void loop(){

  // Increment the variables to simulate test data.
  RawValue0 += 51;
  if(RawValue0 > 1023){RawValue0 = 0;}
  Voltage0 += 99.99;
  if(Voltage0 > 9999.99){Voltage0 = 0.0;}
  tempC0 -= 99.99;
  if(tempC0 < -9999.99){tempC0 = 0.0;}

  // Print out the data in columns.
  printNumber(RawValue0);
  Serial.print("   | ");
  printNumber(Voltage0);
  Serial.print(" | ");
  printNumber(tempC0);
  Serial.print(" | ");
  printNumber(tempF0);
  Serial.println();
  delay(250);
}

long printNumber(int number){
  Serial.print("   ");
  int spaces = 0;
  if(number < 1000){spaces = 1;}
  if(number < 100){spaces = 2;}
  if(number < 10){spaces = 3;}
  for(int i = 0; i < spaces; i++){
    Serial.print(" ");
  }
  Serial.print(number);
}

float printNumber(float number){
  int spaces = 0;
  if(number > -1000.00){Serial.print(" ");}
  if(number < 1000){spaces = 1;}
  if(number < 100){spaces = 2;}
  if(number < 10){spaces = 3;}
  if(number < 0){spaces = 0;}
  if(number == -99.99){spaces = 1;}
  for(int i = 0; i < spaces; i++){
    Serial.print(" ");
  }
  Serial.print(number);
}

When I compile Jot's sketch, it's 6640 bytes. If you remove his "fancy" header, it drops to 6414 bytes. My sketch is 5124 bytes. There is a certain amount of "overhead" involved when using sprintf().
The question you have to ask yourself is, "Does saving 1000 bytes matter?".


text:
Send big amouts of data to PHP script via gsm module SIM800L
I'm looking for a way to get lots of sensory data from my Arduino Micro to a PHP script.
My current attempt is using the following AT-commands:
Sent: [AT+HTTPPARA=URL,www.example.com/newData.php?data=t0_20.75,l_0.00,m_584,h_42,td_22,d_21x44x54]
Res: [AT+HTTPPARA=URL,www.example.com/newData.php?data=t0_20.75,l_]

As you can see I send a long GET-parameter to my server with shortened parameter Names like t0 for temperature sensor number zero, l for light and so on.
In the response from my SIM800l I get back a string with exactly 63 characters, so I assume there's some lenght limitation there on the SIM-module.
After that command when it tries to finish the HTTP request I get a lot of errors as AT-command responses and no GET data arrives on my script.

I check wheter or not data has arrived with the following function on my server:
ob_start();
echo "Var_dump of GET\n";
var_dump($_GET);

echo "Var_dump of POST\n";
var_dump($_POST);
$vd_res = ob_get_clean();

file_put_contents('postdump.log', $vd_res."\n",FILE_APPEND);

When typing some data directly into the browser it saves my sent data in postdump.log so I'm pretty sure the SIM-module can't handle the given amount of data.
Do you have any idea how I can send bigger amounts of data all at once? For energy saving purposes I would prefer if it would be possible in only a single request.

I get back a string with exactly 63 characters, - I guess you're using SoftwareSerial, and using the silly delay(1000) way of waiting for a response that I see all over the place...?

Do you have any idea how I can send bigger amounts of data all at once? For energy saving purposes I would prefer if it would be possible in only a single request.

Do a POST request. You can send huge amounts of data in the body.

In the response from my SIM800l I get back a string with exactly 63 characters, so I assume there's some lenght limitation there on the SIM-module.

Nope.
I guess you're doing something like:
sendCommand("AT+HTTPPARA=URL,www.example.com/newData.php?data=t0_20.75,l_0.00,m_584,h_42,td_22,d_21x44x54");
delay(1000);
printResponse();

The problem there is that you're relying on the internal buffer of SoftwareSerial (or HardwareSerial if you use a real serial port). You wait for a predefined time for characters to arrive, and then after that time print them out.  The serial code has a 64 byte buffer.
I see that kind of code all over the place, and it's the worst possible way of reading serial. Whoever posted the first instance of such code and started this chain of evil should be taken outside and shot.
Instead you must read the serial properly. Being lazy like that doesn't work.
Read this blog post to learn more about reading serial data properly.

Thank you very much. My problem was in fact the buffer limit. I made a workaround where I would add every GET paramater seperatly in a function and only at the end I made a commit by writing \r\n so it gets interpreted as one big command.

@The_javascript_King, the answer was not about TX buffer

With "buffer limit" I meant the limit given by SoftwareSerial

source: Stack Exchange

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

sort: votes


text:
Can i use Arduino IDE with the Wemos D1 R2 AND also use its ESP8266 module to send AT commands?
I have recently started digging into ESP8266 and learned a little about AT commands and i would really like to add the Wi-Fi functionality in my electronics project, which already uses an Arduino UNO R3. I think it would be much easier to use the Wemos D1 R2 since it is basically an UNO + ESP8266. Here is a link to the official product information page: https://wiki.wemos.cc/products:d1:d1 and its schematic: https://wiki.wemos.cc/_media/products:d1:d1_v2.0.0.pdf
I would like to know if it's possible to use the Arduino IDE to program on the Wemos D1 as i do with the normal UNO but also at the same time, be able to send AT commands using its on-board ESP8266?

A year ago I ported my project from Uno with esp8266 (Uno WiFi Dev Ed) to Wemos D1 R2.
Wemos D1 R2 board has esp8266 as the only MCU. The AT firmware is an application running in the esp8266. An Arduino sketch with esp8266 boards package is an application too, so it replaces the AT firmware.
Instead of AT commands you will use for networking the WiFi library of the esp8266 arduino package. It is much simpler and there are many examples.
The esp8266 and the D1 R2 board have 3.3 V logic level on pins. So be careful with inputs and check if your devices will read the 3.3 V as HIGH.
In code use Dx constants matching the labels on the board. D1 R2 has less pins then Uno. I recommend to use I2C devices if possible. I had a Grove Base shield on D1 R2, so I have a mapping of D1 R2 pins to 'Uno' pins.
Some of the esp8266 pins are read at boot as boot configuration. Pins D3 (io 0)
and D4 (io 2) have pull-up on board and pin D8 (io 15) has pull-down on board. Not all devices will work on this pins. Here is a pin overview of the NodeMcu and Wemos boards.
The esp8266 has only one ADC pin. The A0 of the esp8266 can read 0 to 1 V. Wemos boards have a voltage divider on A0 so the board's pin can read 0 to 3.3 V. Don't read A0 in every loop. WiFi part of the esp8266 uses the ADC hardware too and continuous reading of A0 interferes with WiFi operations.
The Wemos D1 R2 has a strong power regulator 7 to 20 V for Vin and power jack. You can power devices from 5V and 3.3V pin. I use Grove relay modules powered from 5V pin and controlled by logic signal at 3.3 V.

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


text:
conflict with different i2c devices
I am trying to communicate with two i2c components using an arduino nano - some ADS1115s and some i2c flow sensors each connected to a different i2c multiplexer, but they seem to be conflicting.
Some of the ADS1115s are 0x49 addresses, the same as all the flow sensors. The full code works, including constructing and initialising the ads1115s, but if I then try to read from them also, I don't get almost any data from the flow sensors (they just read 0 or close to when they should be reading around 8192 for zero flowrate). Any help or suggestions much appreciated!
I've put the full code at the bottom as its quite long and I keep changing it anyway but the important parts are here:
ADS1115:
Adafruit_ADS1115();  //Construct an instance of an ADS1115 with the default address (0x48)
ads1115.begin();  // Initialize ads1115
int16_t readADC_Differential_0_1(void);  //Perform a differential analog to digital conversion on the voltage between channels 0 and 1.

tca9548a multiplexer:
#define TCAADDR 0x70

void tcaselect(uint8_t i) {
  if (i > 7) return;

  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << i);
  Wire.endTransmission();
}

tcaselect(i);

Zephyr flow sensors:
void getflows (int sensor, float range, float flowreading) {
Wire.requestFrom(0x49, 2);
while (Wire.available())   // slave may send less than requested
  {
    int flowdata = Wire.read();    // receive a byte as character
    //Serial.println(flowdata);
    flowdata = flowdata << 8;
    flowdata |= Wire.read();    // receive a byte as character
    //Serial.println(flowdata);
    flowreading = range * ((flowdata / 16384.0) - 0.5) / 0.4;
    //Serial.print("sensor 3 flow = "); Serial.println(flow3);
    //Serial.println();         // print the character
    //Serial.println();
  }
  delay(20);

}
The full code:
#include <ModbusRtu.h>
#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <SPI.h>
#include <PID_v1.h>
#include <math.h>

//modbus
#define ID          1
#define TXEN        2

//valve TTL and DAC CS pins - nos correspond to valve driver numberings in rig box
//Current connections - O2high = 1 = A, CO2 = 2 = B, O2low = 3 = C
#define ATTL       5
#define CTTL       4
#define BTTL       3

#define BCS         7
#define CCS         8
#define ACS         9

#define tempfreq    5
#define tempnum     3
///////////////////////////////////////////
//Sensor ranges - USER DEFINED
float DACrange = 3500.0; //ml/min

int POutrange = 2000; //mbar abs
int PInrange = 2000; //mbar abs
///////////////////////////////////////////

//ADC multiplexer
#define TCAADDR      0x70
#define TCA2ADDR      0x77

//Input resistor values
float         T1R2  =  2320.0;
float         FPR1  =  3090.0;
float         FPR2  =  12010.0;

//max variation from setpoint before PID cycle
int maxdif    =  5;
//max variation from setpoint at end of PID cycle
int PIDdif    =  1;

///////////////////////////////////////////
//MATHS
//scale factor
long FPscale = 10000000;
long flowscale = 10000000;
//vrefs - with scale factors applied
float vref   = 2.5; //tscaled
float Tref   = 1.0; //tscaled
long FPref  = 20000000; //FPscaled
//divisions - integrated to sensor range in long format for calculations
float FPdiv = (FPR1 + FPR2) / FPR2;
int Vmax = 5;

int Poutfac = (int)((POutrange / Vmax) * FPdiv);
int Pinfac = (int)((PInrange / Vmax) * FPdiv);

//ADC mv/bit
float Tbit = 0.00003125;
long FPbit = 625; //- with scale factor of 10,000,000

//temp sensor steinhart constants
double sA = 0.001462146;
double sB = 0.0002393355;
double sC = 0.0000000963049;

//declare holding constants
int16_t hT1 = 0;
int16_t hT2 = 0;
int16_t hT3 = 0;
int16_t hT4 = 0;
int16_t hT5 = 0;
int16_t hT6 = 0;
int16_t hT7 = 0;
int16_t hT8 = 0;

int16_t hFP1 = 0;
int16_t hFP2 = 0;
int16_t hFP3 = 0;
int16_t hFP4 = 0;
int16_t hFP5 = 0;
int16_t hFP6 = 0;
int16_t hFP7 = 0;
int16_t hFP8 = 0;

//intermediates
int i = 0;
int j = 0;
int b[3];
int loopnum = tempfreq;
float tres = 0.0;
double treslog = 0.0;
long lconv = 0;
int16_t O2dif = 0;
int16_t CO2dif = 0;
int16_t N2dif = 0;
int16_t gasdif = 0;
int gasreading = 0;
int hFP = 0;
uint16_t val = 0;
bool truePID;
bool trueAPID = false;
bool trueBPID = false;
bool trueCPID = false;
int (*gasreadfunc)();

int flowdata = 0;
float flow3 = 0.0;
float flow2 = 0.0;
float flow4 = 0.0;
float flow5 = 0.0;
long reading = 0;

uint16_t Setpt;
int CS;
int TTL;

//initialise nested functions
//void eachPID(int16_t (*)(), int16_t, int, bool);

enum
{
  Error1,    //CHANNEL 0  //0
  Error2,    //CHANNEL 1
  FP2a,      //CHANNEL 2  //1
  FP2b,      //CHANNEL 3
  T1a,       //CHANNEL 4  //2
  T1b,       //CHANNEL 5
  T2a,       //CHANNEL 6  //3
  T2b,       //CHANNEL 7
  T3a,       //CHANNEL 8  //4
  T3b,       //CHANNEL 9
  T4a,       //CHANNEL 10 //5
  T4b,       //CHANNEL 11
  Flow2a,    //CHANNEL 12 //6
  Flow2b,    //CHANNEL 13
  Flow3a,    //CHANNEL 14 //7
  Flow3b,    //CHANNEL 15
  Flow4a,    //CHANNEL 16 //8
  Flow4b,    //CHANNEL 17
  Flow5a,    //CHANNEL 18 //9
  Flow5b,    //CHANNEL 19
  A_set,     //CHANNEL 20
  B_set,     //CHANNEL 21
  C_set,     //CHANNEL 22
  HOLDING_REGS_SIZE
};

unsigned int holdingRegs[HOLDING_REGS_SIZE];

/**
    Modbus object declaration
    u8id : node id = 0 for master, = 1..247 for slave
    u8serno : serial port (use 0 for Serial)
    u8txenpin : 0 for RS-232 and USB-FTDI
                 or any pin number > 1 for RS-485
*/
Modbus slave(1, 0, TXEN); // this is slave @1 and RS-485

//Construct ADCs at addresses
Adafruit_ADS1115 adcOne(0x48);
Adafruit_ADS1115 adcTwo(0x49);
Adafruit_ADS1115 adcThree(0x4B);
Adafruit_ADS1115 adcFour(0x4A);

// SPI - set up the speed, data order and data mode
SPISettings settings(4000000, MSBFIRST, SPI_MODE0);

//PID
//Define Variables we'll be connecting to
double Output, Setpoint, Input;

//Define the aggressive and conservative Tuning Parameters
double aggKp = 4, aggKi = 0.2, aggKd = 1;
double consKp = 1, consKi = 0.05, consKd = 0.25;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint, aggKp, aggKi, aggKd, DIRECT);

///////////////////////////////////////////////////////////////////////////////////////////////
void tcaselect(uint8_t i, int address) {
  if (i > 7) return;

  Wire.beginTransmission(address);
  Wire.write(1 << i);
  Wire.endTransmission();
}

void setup() {
  ///////////////////////////////////////////////////////////////////////////////////////////////
  //DAC
  pinMode (BCS, OUTPUT);
  digitalWrite(BCS, HIGH);
  pinMode (CCS, OUTPUT);
  digitalWrite(CCS, HIGH);
  pinMode (ACS, OUTPUT);
  digitalWrite(ACS, HIGH);

  pinMode (ATTL, OUTPUT);
  digitalWrite(ATTL, LOW);
  pinMode (CTTL, OUTPUT);
  digitalWrite(CTTL, LOW);
  pinMode (BTTL, OUTPUT);
  digitalWrite(BTTL, LOW);
  ///////////////////////////////////////////////////////////////////////////////////////////////
  //ADC
  adcOne.begin();
  adcTwo.begin();
  adcThree.begin();
  adcFour.begin();

  // 2/3x gain +/- 6.144V  1 bit = 0.1875mV (default)
  // ads1015.setGain(GAIN_ONE);     // 1x gain   +/- 4.096V  1 bit = 0.125mV
  // ads1015.setGain(GAIN_TWO);     // 2x gain   +/- 2.048V  1 bit = 0.0625mV
  // ads1015.setGain(GAIN_FOUR);    // 4x gain   +/- 1.024V  1 bit = 0.03125mV
  // ads1015.setGain(GAIN_EIGHT);   // 8x gain   +/- 0.512V  1 bit = 0.015625mV
  // ads1015.setGain(GAIN_SIXTEEN); // 16x gain  +/- 0.256V  1 bit = 0.0078125mV

  //////////////////////////////////////////////////////////////////////////////////////////////
  //Flow sensor serial number readouts
  getflows(2, 750.0, flow2);
  getflows(3, 400.0, flow3);
  getflows(4, 50.0, flow4);
  getflows(5, 400.0, flow5);

  //////////////////////////////////////////////////////////////////////////////////////////////
  //PID
  //initialize the variables we're linked to
  Input = 0;
  Setpoint = 0;

  //Define the aggressive and conservative Tuning Parameters
  float aggKp = 4, aggKi = 0.2, aggKd = 1;
  float consKp = 1, consKi = 0.05, consKd = 0.25;

  //turn the PID on
  myPID.SetMode(AUTOMATIC);
  //////////////////////////////////////////////////////////////////////////////////////////////
  // start modbus communication
  slave.begin(115200);

  // initialize SPI:
  SPI.begin();

  //Serial.begin(115200);
  gettemperatures();

  holdingRegs[Error2] = 0;
}

void loop() {
  //each tempfreq no of loops, it reads the temp sensors also
  loopnum++;
  if (loopnum > tempfreq) {
    gettemperatures();
    loopnum = 0;
  }

  holdingRegs[Error1] = 0;//set to 0 for normal operation, 65535 = PID control
  //Serial.print("Holding Regs Error1 "); Serial.print(holdingRegs[Error1]); Serial.print(", holdingRegs[Error2]"); Serial.println(holdingRegs[Error2]);

  //flow and pressure sensors
  tcaselect(0, TCAADDR);
  adcOne.setGain(GAIN_TWO);
  //adcTwo.setGain(GAIN_TWO);
  //adcThree.setGain(GAIN_TWO);
  //adcFour.setGain(GAIN_TWO);

  //hFP1 = adcOne.readADC_Differential_0_1();
  hFP2 = adcOne.readADC_Differential_2_3();
  //hFP3 = adcTwo.readADC_Differential_0_1();
  //hFP4 = adcTwo.readADC_Differential_2_3();
  //hFP5 = adcThree.readADC_Differential_0_1();
  //hFP6 = adcThree.readADC_Differential_2_3();
  //hFP7 = adcFour.readADC_Differential_0_1();
  //hFP8 = adcFour.readADC_Differential_2_3();

  //FPconv(hFP1, &holdingRegs[FP1a], &holdingRegs[FP1b], Pinfac);
  //Serial.print("hFP1: "); Serial.println(hFP1);
  FPconv(hFP2, &holdingRegs[FP2a], &holdingRegs[FP2b], Poutfac);
  //Serial.print("hFP2: "); Serial.println(hFP2);
  //FPconv(hFP3, &holdingRegs[FP3a], &holdingRegs[FP3b], CO2fac);
  //Serial.print("hFP3: "); Serial.println(hFP3);
  //FPconv(hFP4, &holdingRegs[FP4a], &holdingRegs[FP4b], O2fac);
  //Serial.print("hFP4: "); Serial.println(hFP4);
  //FPconv(hFP5, &holdingRegs[FP5a], &holdingRegs[FP5b], Finfac);
  //Serial.print("hFP5: "); Serial.println(hFP5);
  //FPconv(hFP6, &holdingRegs[FP6a], &holdingRegs[FP6b], N2fac);
  //Serial.print("hFP6: "); Serial.println(hFP6);
  //FPconv(hFP7, &holdingRegs[FP7a], &holdingRegs[FP7b], Finfac);
  //Serial.print("hFP7: "); Serial.println(hFP7);
  //FPconv(hFP8, &holdingRegs[FP8a], &holdingRegs[FP8b], Finfac);
  //Serial.print("hFP8: "); Serial.println(hFP8);
  //Serial.println("");

  getflows(2, 750.0, flow2);
  getflows(3, 400.0, flow3);
  getflows(4, 50.0, flow4);
  getflows(5, 400.0, flow5);

  flowconvert();

  //modbus communication
  slave.poll( holdingRegs, HOLDING_REGS_SIZE );

  checkgasflow(1);
  checkgasflow(2);
  checkgasflow(3);

  //delay(1000);
}

void gasread(int gastoread) {
  switch (gastoread) {
    case 1: //O2high
      getflows(3, 400.0, flow3);
      gasreading = flow2;
      Setpt = A_set;
      CS = ACS;
      TTL = ATTL;
      truePID = trueAPID;
      //return gasreading;
      break;
    case 2: //CO2
      getflows(4, 50.0, flow4);
      Setpt = B_set;
      CS = BCS;
      TTL = BTTL;
      truePID = trueBPID;
      //return gasreading;
      break;
    case 3: //O2low
      getflows(5, 400.0, flow5);
      Setpt = C_set;
      CS = CCS;
      TTL = CTTL;
      truePID = trueCPID;
      //return gasreading;
      break;
  }
}

void checkgasflow(int gastoread) {
  gasread(gastoread);
  Input = (double)gasreading;
  Setpoint = (double)Setpt;
  gasdif = Input - Setpoint;
  if (abs(gasdif) < PIDdif) {
    truePID = 1;
    return;
  }
  else {
    GasPID();
  }
}

void GasPID() {
  holdingRegs[Error1] = 65535; //set to 0 for normal operation, 65535 = PID control

  //modbus communication
  slave.poll( holdingRegs, HOLDING_REGS_SIZE );

  do {
    eachPID(1);
    eachPID(2);
    eachPID(3);
  } while (!trueAPID || !trueBPID || !trueCPID);

  holdingRegs[Error1] = 0;
}

void eachPID(int gastoread) {
  gasread(gastoread);
  Input = (double)gasreading;
  Setpoint = (double)Setpt;
  gasdif = Input - Setpoint;
  if (abs(gasdif) < PIDdif) {
    truePID = 1;
    return;
  }
  else if (abs(gasdif) < 10)
  { //we're close to setpoint, use conservative tuning parameters
    truePID = 0;
    myPID.SetTunings(consKp, consKi, consKd);
  }
  else
  {
    //we're far from setpoint, use aggressive tuning parameters
    truePID = 0;
    myPID.SetTunings(aggKp, aggKi, aggKd);
  }
  myPID.Compute();
  val = (uint16_t)Output;
  DACspi(CS, val, TTL);
}

void FPconv (int16_t FPin, uint16_t *hRega, uint16_t *hRegb, int FPfac) {
  lconv = (FPfac * (FPref + (long)(FPbit * FPin)));
  memcpy((uint8_t *)hRega, (uint8_t *)&lconv, 2);
  memcpy((uint8_t *)hRegb, (uint8_t *)&lconv + 2, 2);
}

void Flowconv (float FPin, uint16_t *hRega, uint16_t *hRegb) {
  lconv = (long)(FPin*flowscale);
  memcpy((uint8_t *)hRega, (uint8_t *)&lconv, 2);
  memcpy((uint8_t *)hRegb, (uint8_t *)&lconv + 2, 2);
}

void Tconv (int16_t Tin, uint16_t *hRega, uint16_t *hRegb) {
  tres = T1R2 * ((vref / (Tref + (Tbit * Tin))) - 1.0);
  treslog = log(tres);
  lconv = lround(10000000.0 * ((1.0 / (sA + sB * treslog + sC * (pow(treslog, 3.0)))) - 273.15));
  memcpy((uint8_t *)hRega, (uint8_t *)&lconv, 2);
  memcpy((uint8_t *)hRegb, (uint8_t *)&lconv + 2, 2);
}

void DACspi(uint16_t CS, uint16_t val, int TTL) {
  digitalWrite(CS, LOW);
  if (val > 0) {
    digitalWrite(TTL, HIGH);
  }
  else {
    digitalWrite(TTL, LOW);
  }
  SPI.transfer16(val);
  digitalWrite(CS, HIGH);
}

void gettemperatures() {
  tcaselect(6, TCAADDR);
  adcOne.setGain(GAIN_FOUR);
  adcTwo.setGain(GAIN_FOUR);
  adcThree.setGain(GAIN_FOUR);
  adcFour.setGain(GAIN_FOUR);
  //temp sensors - 2 consecutive readings to allow pins to warm up first
  for (i = 0; i < tempnum; i++) {
    hT1 = adcOne.readADC_Differential_0_1();
  }
  for (i = 0; i < tempnum; i++) {
    hT2 = adcOne.readADC_Differential_2_3();;
  }
  for (i = 0; i < tempnum; i++) {
    hT3 = adcTwo.readADC_Differential_0_1();
  }
  for (i = 0; i < tempnum; i++) {
    hT4 = adcTwo.readADC_Differential_2_3();
  }
  //for (i = 0; i < tempnum; i++) {
  //  hT5 = adcThree.readADC_Differential_0_1();
 // }
  //for (i = 0; i < tempnum; i++) {
  //  hT6 = adcThree.readADC_Differential_2_3();
  //}
  //for (i = 0; i < tempnum; i++) {
  //  hT7 = adcFour.readADC_Differential_0_1();
  //}
  //for (i = 0; i < tempnum; i++) {
  //  hT8 = adcFour.readADC_Differential_2_3();
  //}

  Tconv(hT1, &holdingRegs[T1a], &holdingRegs[T1b]);
  //Serial.print("hT1: "); Serial.println(hT1);
  Tconv(hT2, &holdingRegs[T2a], &holdingRegs[T2b]);
  //Serial.print("hT2: "); Serial.println(hT2);
  Tconv(hT3, &holdingRegs[T3a], &holdingRegs[T3b]);
  //Serial.print("hT3: "); Serial.println(hT3);
  Tconv(hT4, &holdingRegs[T4a], &holdingRegs[T4b]);
  //Serial.print("hT4: "); Serial.println(hT4);
  //Tconv(hT5, &holdingRegs[T5a], &holdingRegs[T5b]);
  //Serial.print("hT5: "); Serial.println(hT5);
  //Tconv(hT6, &holdingRegs[T6a], &holdingRegs[T6b]);
  //Serial.print("hT6: "); Serial.println(hT6);
  //Tconv(hT7, &holdingRegs[T7a], &holdingRegs[T7b]);
  //Serial.print("hT7: "); Serial.println(hT7);
  //Tconv(hT8, &holdingRegs[T8a], &holdingRegs[T8b]);
  //Serial.print("hT8: "); Serial.println(hT8);
}

void getflows (int sensor, float range, float flowreading) {
  tcaselect(sensor, TCA2ADDR);
  Wire.requestFrom(0x49, 2);

  while (Wire.available())   // slave may send less than requested
  {
    int flowdata = Wire.read();    // receive a byte as character
    //Serial.println(flowdata);
    flowdata = flowdata << 8;
    flowdata |= Wire.read();    // receive a byte as character
    //Serial.println(flowdata);
    flowreading = range * ((flowdata / 16384.0) - 0.5) / 0.4;
    //Serial.print("sensor 3 flow = "); Serial.println(flow3);
    //Serial.println();         // print the character
    //Serial.println();
  }
  delay(20);
}

void flowconvert (){

  Flowconv(flow2, &holdingRegs[Flow2a], &holdingRegs[Flow2b]);
  //Serial.print("hFP1: "); Serial.println(hFP1);
  Flowconv(flow3, &holdingRegs[Flow3a], &holdingRegs[Flow3b]);
  //Serial.print("hFP1: "); Serial.println(hFP1);
  Flowconv(flow4, &holdingRegs[Flow4a], &holdingRegs[Flow4b]);
  //Serial.print("hFP1: "); Serial.println(hFP1);
  Flowconv(flow5, &holdingRegs[Flow5a], &holdingRegs[Flow5b]);
  //Serial.print("hFP1: "); Serial.println(hFP1);
}

/*void FPconv (int16_t FPin, uint16_t *hRega, uint16_t *hRegb, int FPfac, long FPcal) {
  lconv = (FPfac * (FPcal + FPref + (long)(FPbit * FPin)));
  memcpy((uint8_t *)hRega, (uint8_t *)&lconv, 2);
  memcpy((uint8_t *)hRegb, (uint8_t *)&lconv + 2, 2);
  }*/

/*void GasPID() {
  holdingRegs[Error1] = 65535; //set to 0 for normal operation, 65535 = PID control

  //modbus communication
  slave.poll( holdingRegs, HOLDING_REGS_SIZE );

  tcaselect(0);

  do {
    eachPID(O2read, O2_set, BCS, trueAPID);
    eachPID(CO2read, CO2_set, CCS, trueBPID);
    eachPID(N2read, N2_set, ACS, trueCPID);
  } while (!trueAPID || !trueBPID || !trueCPID);

  trueAPID = !trueAPID;
  trueBPID = !trueBPID;
  trueCPID = !trueCPID;
  }*/

/*
  void eachPID(int16_t gasReadfunc(), int16_t Setpt, int CS, bool truePID, int TTL) {
  Setpoint = (double)Setpt;

  for (i = 0; i < 3; i++) {
    hFP = (*gasreadfunc)();
  }
  Input = (double)hFP;
  gasdif = Input - Setpoint;
  if (abs(gasdif) < PIDdif) {
    truePID = 1;
    return;
  }
  else if (abs(gasdif) < 10)
  { //we're close to setpoint, use conservative tuning parameters
    myPID.SetTunings(consKp, consKi, consKd);
  }
  else
  {
    //we're far from setpoint, use aggressive tuning parameters
    myPID.SetTunings(aggKp, aggKi, aggKd);
  }
  myPID.Compute();
  val = (uint16_t)Output;
  DACspi(CS, val, TTL);
  }*/

/*//Connections
  int16_t O2read() {
  gasread = adcOne.readADC_Differential_0_1();
  return gasread;
  }
  int16_t CO2read() {
  gasread = adcOne.readADC_Differential_2_3();
  return gasread;
  }
  int16_t N2read() {
  gasread = adcTwo.readADC_Differential_0_1();
  return gasread;
  }*/

/*// SPI communication with DAC
  DACspi(BCS, holdingRegs[CO2_set], BTTL); //CO2 controller
  DACspi(CCS, holdingRegs[N2_set], CTTL); //N2 controller
  DACspi(ACS, holdingRegs[O2_set], ATTL); //O2 controller*/

did you run the I2CScanner sketch?

@juraj no, just did! That's it! I'm opening the first multiplexer then opening the second and not closing the first - many thanks

@OliverWalters Please write an answer to your question, so that other can profit from this.

You have another question on that topic, this is solved now as well, I guess?

@SimSon The other topic is different, relating to one multiplexer which isn't functioning

You pass flowreading to void getflows (int sensor, float range, float flowreading) as a value and therefore changing flowreading has no effect on the variable you pass to that function.
Instead, you need to do void getflows (int sensor, float range, float *flowreading).

I had not realised that once opened, the tca9548a channels stay open until either POR or the RESET pin is brought low. Hence when using two multiplexers I just needed to use an extra wire to the RESET pin on each from the nano.


text:
Arduino Mega with SIM800L running Modbus TCP/IP
I'm trying to set up an Arduino Mega with a SIM800L module and trying to get Modbus TCP running on said Mega. I've set Modbus TCP over wifi and serial before but I used libraries for those. The problem is, I can't find a suitable library for SIM800L that has Modbus support in it. The project is supposed to get Modbus TCP to places without wifi, using a static IP enabled sim card. My question here is, am I missing something? While working with ESP8266 and Serial, I was able to find a ton of libraries to work with, but SIM800 series returns nothing for me.
Thanks!

In 99% of cases, problems with SIM800L came for voltage supply. With wrong voltage supply of without enough power, it doesn't work at all, or (worst case!!) it works for sending or receving 2 or 3 sets of data then start to loose data...

It's already working. Voltage supply isn't the problem. I suppose you didn't exactly read the question. My problem is that I can't find a library that supports Modbus and SIM800 module. Thanks for the tip anyways!

Well the problem for me is Modbus TCP libraries I have been using requires you to have a MAC ID or an IP adress in their implementation while I don't need any of those while using a SIM800 if I am correct. How am I going to get past that?


text:
Arduino Nano 3.0 CH340G clone cannot upload sketch from Arduino IDE
I connected my brand new Arduino Nano 3.0 clone with CH340G and installed the drivers. It detects in Device Manager as USB-SERIAL CH340 (COM6). Under the Tools menu, i selected the correct board, the processor set to ATmega328P and the COM port. I couldn't upload my sketch so i tried uploading an example Blink sketch from Arduino IDE. The uploading is stuck. I keep waiting and nothing happens. I have read somewhere else that i should enable verbose output for compilation and upload, which i did and here is the output for trying to upload the basic Blink sketch.
Arduino: 1.8.9 (Windows 7), Board: "Arduino Nano, ATmega328P"

C:\Program Files (x86)\Arduino\arduino-builder -dump-prefs -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\admin\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\admin\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\admin\Documents\Arduino\libraries -fqbn=arduino:avr:nano:cpu=atmega328 -vid-pid=1A86_7523 -ide-version=10809 -build-path C:\Users\admin\AppData\Local\Temp\arduino_build_747566 -warnings=none -build-cache C:\Users\admin\AppData\Local\Temp\arduino_cache_890158 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\5.4.0-atmel3.6.1-arduino2 -prefs=runtime.tools.avr-gcc-5.4.0-atmel3.6.1-arduino2.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\5.4.0-atmel3.6.1-arduino2 -prefs=runtime.tools.avrdude.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14 -prefs=runtime.tools.avrdude-6.3.0-arduino14.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14 -prefs=runtime.tools.arduinoOTA.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.2.1 -prefs=runtime.tools.arduinoOTA-1.2.1.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.2.1 -verbose C:\Program Files (x86)\Arduino\examples\01.Basics\Blink\Blink.ino
C:\Program Files (x86)\Arduino\arduino-builder -compile -logger=machine -hardware C:\Program Files (x86)\Arduino\hardware -hardware C:\Users\admin\AppData\Local\Arduino15\packages -tools C:\Program Files (x86)\Arduino\tools-builder -tools C:\Program Files (x86)\Arduino\hardware\tools\avr -tools C:\Users\admin\AppData\Local\Arduino15\packages -built-in-libraries C:\Program Files (x86)\Arduino\libraries -libraries C:\Users\admin\Documents\Arduino\libraries -fqbn=arduino:avr:nano:cpu=atmega328 -vid-pid=1A86_7523 -ide-version=10809 -build-path C:\Users\admin\AppData\Local\Temp\arduino_build_747566 -warnings=none -build-cache C:\Users\admin\AppData\Local\Temp\arduino_cache_890158 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.avr-gcc.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\5.4.0-atmel3.6.1-arduino2 -prefs=runtime.tools.avr-gcc-5.4.0-atmel3.6.1-arduino2.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\5.4.0-atmel3.6.1-arduino2 -prefs=runtime.tools.avrdude.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14 -prefs=runtime.tools.avrdude-6.3.0-arduino14.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14 -prefs=runtime.tools.arduinoOTA.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.2.1 -prefs=runtime.tools.arduinoOTA-1.2.1.path=C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\arduinoOTA\1.2.1 -verbose C:\Program Files (x86)\Arduino\examples\01.Basics\Blink\Blink.ino
Using board 'nano' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Using core 'arduino' from platform in folder: C:\Program Files (x86)\Arduino\hardware\arduino\avr
Detecting libraries used...
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\variants\\eightanaloginputs" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\sketch\\Blink.ino.cpp" -o nul
Generating function prototypes...
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\variants\\eightanaloginputs" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\sketch\\Blink.ino.cpp" -o "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\preproc\\ctags_target_for_gcc_minus_e.cpp"
"C:\\Program Files (x86)\\Arduino\\tools-builder\\ctags\\5.8-arduino11/ctags" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\preproc\\ctags_target_for_gcc_minus_e.cpp"
Compiling sketch...
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-g++" -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_NANO -DARDUINO_ARCH_AVR "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\cores\\arduino" "-IC:\\Program Files (x86)\\Arduino\\hardware\\arduino\\avr\\variants\\eightanaloginputs" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\sketch\\Blink.ino.cpp" -o "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\sketch\\Blink.ino.cpp.o"
Compiling libraries...
Compiling core...
Using precompiled core: C:\Users\admin\AppData\Local\Temp\arduino_cache_890158\core\core_arduino_avr_nano_cpu_atmega328_0c812875ac70eb4a9b385d8fb077f54c.a
Linking everything together...
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.elf" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566\\sketch\\Blink.ino.cpp.o" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/..\\arduino_cache_890158\\core\\core_arduino_avr_nano_cpu_atmega328_0c812875ac70eb4a9b385d8fb077f54c.a" "-LC:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566" -lm
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.elf" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.eep"
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-objcopy" -O ihex -R .eeprom "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.elf" "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.hex"
"C:\\Users\\admin\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2/bin/avr-size" -A "C:\\Users\\admin\\AppData\\Local\\Temp\\arduino_build_747566/Blink.ino.elf"
Sketch uses 930 bytes (3%) of program storage space. Maximum is 30720 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/bin/avrdude -CC:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf -v -patmega328p -carduino -PCOM6 -b115200 -D -Uflash:w:C:\Users\admin\AppData\Local\Temp\arduino_build_747566/Blink.ino.hex:i
An error occurred while uploading the sketch

avrdude: Version 6.3-20171130
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Users\admin\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino14/etc/avrdude.conf"

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

avrdude done.  Thank you.

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

I have had cheap nano clones come from China without a bootloader installed. Try reinstalling the bootloader.

I searched and found that i would need a working Arduino Nano in order to transfer its working bootloader onto the non-working one. Is it possible to do it if i don't have another Arduino Nano?

Get yourself a USBASP off eBay/AliExpress/Amazon.

select "Old bootloader" in Tools menu

I followed these guides and i got it to work: https://www.instructables.com/id/How-To-Burn-a-Bootloader-to-Clone-Arduino-Nano-30/ and https://www.arduino.cc/en/tutorial/arduinoISP#toc2

so you burned the "new" bootloader

Yes, i assumed that the new bootloader is better and also that's what was recommended in the tutorial. What are the reasons for using or preferring the old bootloader?

if you can't burn the 'new' :-). The 'new' bootloader is the bootloader of Uno (so not really new). It is Arduino version of Optiboot 4. Really new is Optiboot 8.

OK, but i'm wondering what difference does it make? Does the 'old' bootloader enable faster compiling/upload/execution? Or does it make the board less power hungry??

https://arduino.stackexchange.com/questions/51866/arduino-nano-atmega328p-bootloader-difference/51874#51874

You normally just have to press 'reset' on the board button 1 sec before clicking 'Upload'.
I had to do this with cheap Nano clone.

MCU on Nano doesn't have native USB and has a different bootloader.


text:
How I can connect module GSM SIM800L?
I bought a GSM module, and I want to connect it with Arduino but I have a problem.
I linked GSM SIM800L with regular LM2596 12 V 2 VA I changed tension to 5 V, So far the GSM is working but if I connect TX_ARDUINO with RX_GSM the module enters in the loop of the restart.
The picture explains the montage.

How are you providing power to arduino?

I connect Arduino with my pc.

And your code...?  Also, you shouldn't be using GSM in modern designs. Many carriers are turning off GSM services. You should be using (at least) an LTE modem.

You should separate the ground of external power supply and GND of arduino.

@Vaibhav How is that going to help matters? All that will do is break things further.

@Vaibhav  how I can do it ??

@ÀbdóBougaà your module must have gnd terminal use it for supply as well.

@Majenko what I think Hardware connections are not right.

Follow this tutorial on how to connect your Sim800l with Arduino.


text:
SD.h causing constant reboot
I have a nice sketch running which monitors a few things and displays output on an OLED display. Now I want to save the data to an SD card, but with or without the card module attached I'm getting constant reboots when I add 1 single line of code:
#include <SD.h>

Any idea what may be happening?

Uno? you run out of SRAM. what is the memory usage report before Upload?

On an Uno or similar small board just including the SD library consumes a quarter of your memory.

Yep that's it, far out :)
I'm also running an SSD1306 display. TIme to optimise. Thanks

Ah. Common situation. There's loads of questions here about "SSD1306 and SD unable to allocate buffer"

There is a "text only" SSD1306 library somewhere that doesn't need an internal buffer to save memory. Can't do graphics, of course...

The following libraries are probably used:

SD Card, using a buffer of 512 bytes (see also the comment of DataFiddler below).
SSD1306 OLED library, using a buffer of 1,024 bytes
Serial, using a buffer of 128 bytes (64 for RX, 64 for TX, see comment of Majenko below)

Since there is only 2,048 bytes of SRAM in an Arduino, this leaves 384 bytes. If you actually READ a file you are already above the maximum.
Your own global variables also will consume a considerable amount of SRAM.
Than, if you execute your sketch, parameters and local variables are stored on the stack (in SRAM), so even if your program starts well, it might/will run in problems when calling functions.

Don't forget 128 bytes for Serial (64 TX, 64 RX) if Serial is being used...

@Majenko Thanks ... I updated my answer.

SD needs 512 bytes for the directory structure, and another 512 bytes later, when it opens a file.

Ta. I've been doing a lot of reading around memory usage and restructured a little to reduce the number and length of string literals. What I find surprising is that the Uno only has 2k but the Nano has 8k. That's a little counter intuitive. Unfortunately my brand new Nano has a broken Micro SD port and overloads my PC and bus shuts down. Gotta get a replacement under warranty so I can finish this project off. Will still optimise the code though.

What was really doing my head in about it is I'm using Visual Micro add for Visual Studio to do my coding and it's not as obvious about the warnings. I switched to Arduino IDE and the warnings were far more obvious.

The percentage is only the percentage BEFORE running, while running more memory is needed.

Btw, also consider using an STM32F103C8T6 (ARM) development board, they are dead cheap, they run Arduino Uno (check if your needed libraries are supported); they have 20 KB SRAM. Also you can consider using external SRAM but you need to either rewrite your own code using that SRAM or rewrite libraries (probably even more time consuming).


text:
Arduino as ISP - program is being uploaded on Arduino, not breadboard
I am following this tutorial, and have wired Arduino using this diagram:

This is what it looks like:

These options are selected in Arduino IDE:

This is the program I'm uploading:
// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(9, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(9, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

When I upload it, it's uploaded on the Atmega on arduino board, not the one on breadboard. Both chips are ATMEGA328P.
I also tried to put 10μF capacitor between GND and RESET pins of the arduino board, which led to following errors:
Sketch uses 936 bytes (3%) of program storage space. Maximum is 30720 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.
C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\hardware\tools\avr/bin/avrdude -CC:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf -v -patmega328p -carduino -PCOM4 -b115200 -D -Uflash:w:C:\Users\Jakub\AppData\Local\Temp\arduino_build_319338/BlinkTestAtmega.ino.hex:i

avrdude: Version 6.3-20171130
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         System wide configuration file is "C:\Program Files\WindowsApps\ArduinoLLC.ArduinoIDE_1.8.21.0_x86__mdqgnx93n4wtt\hardware\tools\avr/etc/avrdude.conf"

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

avrdude done.  Thank you.

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

Note that I have a homemade ATTINY programmer shield for this arduino board and it works without problems.

Do you have a capacitor on the RESET pin of the Arduino? From you image I'm not sure. You need it for preventing the Arduino to reset and start the bootloader, when the serial port is opened

I tried to put 10uF and 22nF capacitors there. With 10uF, I get a bunch of avrdude: stk500_getsync() attempt 10 of 10: not in sync errors, the 22nF cap has no effect.

@Juraj I don't understand. Are you saying the tutorial I am following is wrong? When I select "Burn bootloader" it finishes without errors, but I don't know if it actually does anythinh.

@Juraj I am running arduino IDE, I don't know how to access output other than what's available in the IDE.

sorry. Use the "Upload using programmer" in Sketch menu to upload a sketch over ISP

after uploading the bootloader, you have to remove the chip from the arduino and wire the tx/rx lines from the arduino to your bread board chip. Its mentioned in the second part of the link you have provide. Did you do that..?

@Juraj Awesome, it works fine. The older versions of Arduino IDE used the same button to upload using ISP. It kinda made sense in my opinion. After all, I already selected Arduino as ISP.

Use the "Upload using programmer" in Sketch menu to upload a sketch over ISP

warning, it deletes the bootloader


text:
Arduino not recognised by windows after using a lot of the storage
I made a script for my Arduino Pro Micro that was very large (Global variables were 98% of the intended storage). The Arduino was not recognised by Windows after loading the script and I don't know how to fix this issue.

reset it while it attempts to upload, to start the bootloader. try double reset if simple reset doesn't work

Not recognized means, it was not recognized at the corresponding COM port or don't you simply get any communication on the serial port while the sketch is (should be) running?

on Micro the MCU (32u4)  has native USB handled by your sketch (the part from Arduino core), so if the sketch doesn't run, the USB is not handled. the IDE can reset the MCU only if it listens on USB (with 1200 baud connection). if you activate the bootloader with reset, it will handle USB while it is active


text:
Adafruit Feather 32u4 BLE compatible with Software SPI?
Let me preface by saying that I am not super experienced with electronics. I have an Adafruit Feather 32u4 that is using Hardware SPI to communicate over Bluetooth. Unfortunately, I'm also hoping to use the SD library, which also uses Hardware SPI. I am hoping to change the board to use Software SPI instead, so that the two may work together.
The Bluefruit code by default has the following commented out:
/* ...software SPI, using SCK/MOSI/MISO user-defined SPI pins and then user selected CS/IRQ/RST */
Adafruit_BluefruitLE_SPI ble(BLUEFRUIT_SPI_SCK, BLUEFRUIT_SPI_MISO,
                             BLUEFRUIT_SPI_MOSI, BLUEFRUIT_SPI_CS,
                             BLUEFRUIT_SPI_IRQ, BLUEFRUIT_SPI_RST);

Which leads me to believe I could use SW SPI but simply uncommenting this and commenting out the HW SPI doesn't seem to work.
I am just not sure if it's not compatible with the board, or I need to do more than this...?

SPI is a bus. you can wire more devices only use different  CS pin. some SD modules make problems on bus. the Adafruit SD module is OK

my comment applies to hardware SPI. two different sw SPI or sw SPI with hw SPI can't work together on the same pins

Read SparkFun's guide, Serial Peripheral Interface (SPI), especially the multiple slaves section:

Multiple slaves
There are two ways of connecting multiple slaves to an SPI bus:

In general, each slave will need a separate SS line. To talk to a particular slave, you'll make that slave's SS line low and keep the
rest of them high (you don't want two slaves activated at the same
time, or they may both try to talk on the same MISO line resulting in
garbled data). Lots of slaves will require lots of SS lines; if you're
running low on outputs, there are binary decoder chips that can
multiply your SS outputs.

On the other hand, some parts prefer to be daisy-chained together, with the MISO (output) of one going to the MOSI (input) of the next.
In this case, a single SS line goes to all the slaves. Once all the
data is sent, the SS line is raised, which causes all the chips to be
activated simultaneously. This is often used for daisy-chained shift
registers and addressable LED drivers.

Note that, for this layout, data overflows from one slave to the next,
so to send data to any one slave, you'll need to transmit enough data
to reach all of them. Also, keep in mind that the first piece of data
you transmit will end up in the last slave.
This type of layout is typically used in output-only situations, such
as driving LEDs where you don't need to receive any data back. In
these cases you can leave the master's MISO line disconnected.
However, if data does need to be returned to the master, you can do
this by closing the daisy-chain loop (blue wire in the above diagram).
Note that if you do this, the return data from slave 1 will need to
pass through all the slaves before getting back to the master, so be
sure to send enough receive commands to get the data you need.


text:
Shield SIM808 EVB V3.2 charge a Lithium battery?

hello friends do you know if, can this shield (SIM808 EVB V3.2) charge a lithium battery directly or i need additional hardware?, I know that module has conection for battery but it can charge it?

The module does not include a charging circuit for Lithium-ion cells.

EDIT
According to the SIM808 Hardware Design document, Page 28, the SIM808 module does integrate Lithium-ion cell charging.
It states that the battery should have it's own overcharge, over discharge, over current protection, and reverse-polarity protection.

When I connect the power supply, at the  "Li-ion" terminals there is a voltage of 3.88 v, I think it may be enough to charge lithium cells without problem and the SIM808 shield has an AT command "AT + CBC" which provides information about the battery charging, that is why my question, if I need additional hardware? (protection circuit for Li-ion cells)

It would seem I am incorrect and will correct my answer. Documentation on this module was hard to find, but I have now find this document: https://seeeddoc.github.io/Mini_GSM-GPRS_Plus_GPS_Breakout-SIM808/res/SIM808_Hardware_Design_V1.00.pdf#page=28 which documents lithium-ion battery charging.

attached image about
AT+CBC Command https://www.dropbox.com/s/2gaid1urp8wvk2j/Screenshot_2019-04-17-11-09-26.png?dl=0

@CarlosBravo every LI-ION Battery comes with protection circuit that protects it from overcharge and over discharge

@Vaibhav this is not true. It is possible, and rather easy to purchase raw cells, either in LiPo packs or 18650 cylindrical form which have no protection circuitry. You can/should never assume any LiIon cell has any protection unless you can verify that it's present. It should be readily visible in some way.


text:
PWM Control, How to stop LED from Flickering?
What is required is controlling the brightness of an LED using both Buttons and a Potentiometer,
Button A: Increase
Button B: Decrease /Dim
Potentiometer: Increase and Decrease,
This however must happen on 1 single circuit and must display the results on an LCD.
If I do this separately, meaning buttons without potentiometer and visa versa, I win, the moment I combine the two. I get flickering when working the buttons, due to the potentiometer.
Alternative Research:https://www.instructables.com/id/Smooth-Potentiometer-Input/
Code Below
#include <LiquidCrystal.h>
#include <Wire.h>
// ------------------------------------------------------------

int LED1          = 9;
int ButtonLeft    = 8;
int ButtonRight   = 7;
int brightness    = 0;

// ------------------------------------------------------------
byte buttonState1     = 0;
byte lastButtonState1 = 0;

byte buttonState2     = 0;
byte lastButtonState2 = 0;

unsigned long switchMillis;

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

int potValue1 = 0;
int potValue2 = 0;
int potPin= A0;
int readValue;
int writeValue;

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

// ------------------------------------------------------------
void setup() {

  lcd.begin(16, 2);
  pinMode (potPin, INPUT);
  pinMode(LED1,OUTPUT);
  pinMode(ButtonLeft,INPUT);
  pinMode(ButtonRight,  INPUT);
  lcd.clear ();
}

// ------------------------------------------------------------
void loop(){

    if (millis() - switchMillis >= 5)
  {
    switchMillis = millis();
    checkSwitches();
  }

   readValue = analogRead(potPin);
   writeValue = (255./1023.) * readValue;
   analogWrite(LED1, writeValue);

    potValue1 = analogRead(potPin) / 10;
    potValue2 = potValue1 / 1.02;

    lcd.setCursor(0,0);
    lcd.print("Potent=");
    lcd.print(potValue1);
    lcd.print("%");
    delay(100);
    lcd.print(" ");
    delay(1);
}

void checkSwitches() {

    analogWrite(LED1, brightness);
    delay(10);

  buttonState1 = digitalRead(ButtonLeft);

  if(buttonState1 == HIGH){
    brightness--;
    if(brightness < 0){
      brightness = 0;
    }
  }

  buttonState2 = digitalRead(ButtonRight);

  if(buttonState2 == HIGH){
    brightness++;
    if(brightness > 255){
      brightness = 255;
    }
  }

 lcd.setCursor (0,1);
 lcd.print ("Brightness=");
 lcd.print (brightness);
 lcd.print ("   ");
}

This is like having two players, play a single player game, by both of them pressing the buttons on the same single controller. Of course the game character is making weird moves. PS, I think a rotary encoder might be more appropriate to use here.

Your code doesn't make much sense.
You set the LED to 2 different brightness values that don't have anything to do with each other: The pot brightness and the button-based brightness. You only adjust the LED based on switches once every 5 mS. Thus the LED is going to flicker between 2 different brightness values.
What do you want it to do? How do you want to control the brightness based on input from both the pot and your switches? (What is the relationship between the buttons and the pot? Should the button input alter max/min value of the pot up and down? Should holding the button down change the brightness by 1 value per a specific time unit? Say 2 increments/decrements per second?)
Describe the user interface you want to achieve, and then think through how you would do that in code.

"Describe the user interface you want to achieve, and then think through how you would do that in code." +1.

Hi Duncan, the flickering only occurs upon addition of the pot, if I ran the code without the pot, everything works accordinging.
This is my second code, I could present you with the first but I still get the same problem.
Even if I removed the switchMillis section in the code. Even before I was told the arduino couldnt understand what to do because I didnt have buttonstates, but I added those to no success.
Bottom line is, I need to control the brightness of an LED using both Pot and Buttons, alone each I can do, but I dont know how to do it all within the same code.

@BoiG can you describe to us exactly how the buttons and pot interact? If I decrease the pot, then use the increase button, what should happen? If I then increase the pot? What if I’m at max via the button, then crank the pot up? Then back down? It’s not clear what you’re really trying to achieve.

You're trying to build something and don't have a clear idea of what it is. You need to define, in clear precise detail, what you want to do, and then think through how to achieve that in code. We can't help you unless you can be clear about how you want your program to behave.


text:
Why is my relay not triggering?
I have a 4 channel relay for my Arduino. Here's an image:

From what I can tell, it's rated for 5V direct current because of the big 05VDC at the bottom, but please tell me if I'm wrong? If I'm wrong, then that's the problem here.
I've tested out an LED on 5V DC to work and connected it to output side of the relay.
I've connected my Arduino to the input, programmed with the following code:
const int RELAY_PIN = 3;

void setup() {
  pinMode(RELAY_PIN, OUTPUT);
  Serial.begin(96000);

}

void loop() {
  Serial.println("Relay ON");
  digitalWrite(RELAY_PIN, LOW);
  delay(1000);

  Serial.println("Relay OFF");
  digitalWrite(RELAY_PIN, HIGH);
  delay(1000);
}

I can confirm that the corresponding LED on the relay for channel 4 does blink for 1 second and stay off for 1 second, which I'm expecting it's meant to do. I've never worked with an Arduino or a relay before.
However, the 5V DC LED on the other end never lights up. Why is my relay not switching on?
Edit: About the LED circuit. It is on and fully powered. If I bypass the relay and join the two wires, the LED lights up. If I plug the two wires into the relay, the LED never lights up.
Edit2: About the jumper: I have a secondary 5V power supply connected to the VCC for what I'm told is isolation. I've read a little on the matter, but am not fully aware of how it works.
Edit 3:
Connections
I have the following connections:

Output 3 (Arduino) to Input 4 (Relay)
5V (Arduino) to Input VCC (Relay) [The one next to the input pins]
Power supply positive/ground to GND (Relay)
Power supply negative/live to VCC (the one next to the JD-VCC)

This did not work. What did work was the following configuration:

Output 3 (Arduino) to Input 4 (Relay)
5V (Arduino) to Input VCC (Relay) [The one next to the input pins]
Jumper across VCC and JD-VCC on the Relay

Guessing (with out a schematic), you didn't add a power source to the relay to LED circuit?   I don't see any wires on that side of the board.  So I am not sure where the LED that is not lighting up is located.  Let me know here in a follow up comment and I'll post an appropriate answer you can accept so others who find your question with a similar problem will have an appropriate answer.

@st2000 I did. Sorry, I'm not a hardware person so I don't even know how to make a schematic. But let me edit the question.

oh, I see the problem.  You are missing the jumper on JD-VCC.  So, instead of a jumper - there is a blue wire - where is the blue wire going?

@st2000 secondary 5V power supply connected to VCC :) sorry, editing the question.

So, if the secondary power supply is 5V, then your setup will probably work if you move it to the other side of the pair of pins.  Also, you will need to connect the grounds of the 2 power supplies together.  See the schematic in my answer below.  But I think most people just put a jumper across J5 or JD

Note that driving your relay off of the 5V from your Arduino is a bad idea. If memory serves those relays draw about ≈200mA - 250mA per relay, so you could drive maybe 2 of them at the same time, but if you try to drive 3, you'll exceed the 500mA max output you should draw from the Arduino. If you're powering it from USB, it will trip the internal fuse and shut off. If you're running it from the barrel connector, you might get away with it, or you might overheat the Arduino's voltage regulator, depending on various factors. you should really drive your relay with a separate power supply.

Thanks @DuncanC, that's what I'm trying to do.

"Power supply negative/live to VCC (the one next to the JD-VCC)" the secondary power supply should power the relays over JD-VCC

From the image in the question, the jumper across pins J5 (in the
below schematic) or JD as on the silk screen on the PBC is missing.

Using the above schematic, a choice to power the Ardino and the relays off of one 5V power supply can be made.  This appears to be done by connecting the 5V to the VCC pin, Ground to the GND pin & placing a jumper across J5.  However, it appears that the relays can be isolated from the Arduino if desired.  This appears to be done by connecting the Arduino's 5V to pin 2 of J5.  That should be enough to light up the LED indicator and therefor the optical isolator when the Arduino's output to IN1, 2, 3 or 4 is low.  Then, connect the 2nd power source 5V to pin 1 of J5 and the ground from the 2nd power source to pin GND.  This last step should provide the power to close the relays when the Arduino takes IN1, 2, 3 or 4 low.
Lastly, make sure the polarity of the 2nd power supply (if one is used) is correct.  The output side of the optical coupler and the transistor driving the relay only work when the current is passing in the proper direction. Not to mention, the reverse bias flyback diode (D1, 2, 3 & 4) would short out the power supply if connected in the reverse direction.  However, this catastrophe is avoided here as the transistors (Q1, 2, 3 & 4) would not pass current in the reversed direction.

Hi, your suggestion to join the grounds and move the pin to the other side did not work. However, something else did, please see Edit 4 for the configuration that did. However, the Arduino is no longer isolated, what do you suggest?

(I only see an Edit 3.)  The option to drive the relays from a different power source than the Arduino is not necessary.  Especially if you are using a good 5V power supply with plenty of current capability.  What is important is the isolation the relays provide from what ever you are planning on connecting to the relay contacts.  If you want, you can continue using 2 independent power supplies.  Actually, looking at the schematic I found, you don't need to connect the grounds together (my bad).  I'll amend my question as I'm running out of room here in this comment.

The error was so dumb, I don't want to admit it. I had the external power supply connected in reverse because "negative ground" did not make sense to me. But I would never have caught it if not for your diagram.
Could you please add a suggestion to ensure that the connections are correct, and I'll mark yours as accepted? Thank you for your help.

Ah, good to know you've got it working.  And that you understand it. I'll see if I can add something.

A relay is an electromagnet-driven switch. It opens and closes that switch, but doesn't provide power.
Assuming it's like my relays, that relay can either power the relay coils AND the logic inputs, or (if you remove the jumper) use separate power for the relay coils and the logic signals.
Since you've removed the jumper, you need to provide 2 different 5V power sources to drive the relay - one high-current supply to the VCC, which runs the logic circuits and the relay coil. Another to the logic power in. Then you ground the input pin to activate one of the relay channels.
Finally, you need to wire the screw terminals on the left side into a circuit with separate power that controls something. For an LED, you'd need power, the LED, and a current-limiting resistor wired in series with the screw terminals on LED channel 1.
For an LED this is serious overkill. You could drive the LED directly (with a current limiting resistor) from the Arduino logic signal.

Hi Duncan, I have a secondary power supply on the VCC, and this setup is a test setup to learn how Arduinos and relays work. I plan on connecting replacing the LED with something higher powered later on.

In your picture you don't have anything connected to the switched side of the relay (the screw terminals on the left side.)

Yes, when I snapped the photo, I was testing the LED circuit to ensure it was working properly so I took them off. The LED circuit works fine and is inserted properly. I've managed to make the relay finally work with the jumper on. Please see Edit 3.

So who down-voted my answer, and why? It's fine if you think my answer is lacking, but please explain.

Have an upvote on me, since I think it's good. :)


text:
PPM of Wasabi Eco
I'm currently trying to control a brushless DC motor (EMAX 1806-2280Kv) with a ESC called Wasabi Eco 12A (Wasabi Eco specifications#1 , Wasabi Eco specifications#2)
I'm trying to control the motor via an Arduino Uno, and using their IDE to begin with. I have the following code:
#include <Servo.h>
Servo ESC;     // create servo object to control the ESC
void setup() {
  delay(1000);
  ESC.attach(9, 1000, 2000); // (pin, min pulse width, max pulse width in microseconds)
  delay(2000);
   ESC.write(180);
  delay(300);
  ESC.write(0);
  delay(2000);

}

void loop() {

  ESC.write(1800);    // Send the signal to the ESC
  delay(100);
}

I have tried various of combinations and non of them seems to work. The motor sometimes beeps, but not in the correct way. I have tried to look for the PPM width (which is 1000 - 2000 μS in the code) but can't seem to find it anywhere. Any suggestions of what I'm doing wrong?

Probably you do not have the correct arming sequence.  If your question is about probing you need to explain what you tried.

I did as the datasheet said; full throttle and then minimum. But nothing seems to happen

This is really buried in the details of things you have not documented, but you could check if your "ESC" library requires that you set the pin as an output first.


text:
Reading incoming/outgoing bytes from SIM card / ATR
I am trying to read data from a two-way I/O uart pin of a sim card on Arduino. It is attached to the GPRS Arduino shield (with SIM900 modem). I believe I have a baud rate issue.
I am supposed to receive ATR (Answer to Reset) bytes which should be easily recongnized but all I get is a almost-random stream of bytes.
I soldered a wire on the SIM I/O pin and attached it to arduino's software serial RX, I set the baud rate to the same baud rate of the modem which goes up to 115,2K and read. Here's my code
#include <SoftwareSerial.h>
SoftwareSerial IO(9, 10);
void setup() {
Serial.begin(115200);
IO.begin(115200); // my said wire on SIM card's I/O    enter code here
}
void loop() {
if (IO.available())
Serial.print(IO.read(),HEX);
}

and here's the output after a cold reset :

I also tried other baud rate within the SIM900 range of baud rates, still almost same.
Any idea why it's not showing bytes correctly? I appreciate it if anyone could help.

what is "GPRS Arduino shield (with SIM900 modem)"?

why do you print it as HEX and without spaces between? the print(,HEX) doesn't add leading zeros


text:
There is no PWM output
I recently made a project where output is coming from the differential between data reading and reference value. It works on my Proteus simulation but there is no PWM output on my real world device.
Here is my code listing
for (z = 0; z <= output2; z++)
  if (output2 >= 30) {
   toggle == HIGH;
   en = !en;
  }
if (en == true) {
  OCR1A = map(z, 0, 255, 0, ICR1); ;
  OCR1B = 0;
} else {
  OCR1A=0;
  OCR1B = map(z, 0, 255, 0, ICR1);
}
if (output2 < 30) {
  en = !en;
  analogWrite(9, 0);
  analogWrite(10, 0);
}

What do you want to achieve by calling map()? Do you know what OCR1A/B are and how the analogWrite() function works?

i saw from other program that is for setting up the carrier frequency, so if icr1=1600, 0-255 = 0-10khz, cmiiw,

I’m not sure what you’re trying to accomplish, but you’re writing a constant 0 to the analog output.

if (output2 < 30) {
  en = !en;
  analogWrite(9, 0);
  analogWrite(10, 0);
}

To quote the analogWrite() doc

Syntax
analogWrite(pin, value)
Parameters
pin: the pin to write to. Allowed data types: int.
value: the duty cycle: between 0 (always off) and 255 (always on). Allowed data types: int

If you want to see an output, you have to write a value between 0 and 255.

yes it is purposely gives 0 cycle when the output is less than 30


text:
Why does current flow along a wire instead of a resistor right next to it?
I am having trouble understanding exactly what is going on in a circuit where when a button is pressed an LED goes on. Also, I have the Arduino UNO.
The schematic can be seen at:
2:36 of this video: Arduino Tutorials: Control a LED with a Button.

So, the part that I don’t understand is, how come when the button is clicked and the current can pass through, the current doesn’t go through the pull down resistor and instead goes along the input wire?

I’m a beginner but do understand concepts like voltage, amps, resistors, Ohm’s law, etc. So answers don’t have to be super simple, but simple enough that I can understand them. Thanks!

You may have the arduino, but the question is off topic.  Please ask the question at Electrical Engineering SE.

The input pin has a very high resistance, so that nearly no current is flowing into it. Effectively the microcontroller is doing a voltage measurement. It measures the voltage over the pulldown resistor.

Some current is flowing though the pull-down resistor, but the power supply has no problem producing this little bit of current, so the voltage before the pull-down resistor will remain a stable 5 Volt. So the voltage at the Arduino input will be 5Volt while the button is pressed. Once the button is released any "stray" voltage will flow though the resistor, so the voltage at the input pin will become 0 Volt

Please, can you forget everything that you "learned" from that video. The explanation in that video is wrong and confusing. The way the video explains how the current flows is utter nonsense. You can start with the arduino examples, they are in the menu of the arduino program and also online: https://www.arduino.cc/en/Tutorial/BuiltInExamples Start for example with "Button" in section "2. Digital".

So, the part that I don’t understand is, how come when the button is clicked and the current can pass through, the current doesn’t go through the pull down resistor and instead goes along the input wire?

Simple: It does go through the pull down resistor. But  it also goes down the "input" wire.
For simplicity you can imagine that the input is simply a very large resistor. Say, 1MΩ.
The circuit can then be simplified as:

simulate this circuit – Schematic created using CircuitLab
Contrary to popular belief, current does not take the path of least resistance. It takes all possible paths. The quantity of current through each path is proportional to the resistance of the paths.
In this example we have two paths - one with 10kΩ and one with 1MΩ.  That's a ratio of 1:100, and the current will be split accordingly.
You can calculate the current that flows through each resistor simple using Ohm's Law because the wires and switch are (in an ideal world) just not there. The 5V is directly connected across each of the resistors.
So for the 10kΩ resistor the current through is is:
     V      5
I = --- = ----- = 0.0005 = 500µA
     R    10000

And for the 1MΩ it is of course 100x smaller (I'll let you do the maths for that if you want to check), so 5µA.
The full current that the circuit takes is 505µA, with it split between the two resistors.
With the Arduino instead of the 1MΩ resistor it's exactly the same (though the current values may vary somewhat).  500µA flows through the 10kΩ resistor, and "some tiny current" flows through the Arduino.
However, with all that said, the Arduino really doesn't care about the current. All it cares about is the voltage. With the button pressed both the input and the 10kΩ resistor are connected directly to the 5V supply - so the Arduino reads that as "HIGH". When you release the button the input is now connected to ground through the 10kΩ resistor, but there's no current to flow, so there's no voltage across the resistor (the voltage across a resistor is proportional to the current flowing through the resistor - Ohm's Law), so it's as if the input is connected directly to ground - and the Arduino reads that as "LOW".
To be more technically accurate the input of the Arduino is actually more akin to a tiny capacitor.  When you apply 5V to the input it charges that capacitor up. Once it reaches 60% of 5V the Arduino recognises it as a "HIGH" signal.
When you release the button that capacitor is then connected to ground through the resistor, and it discharges through that resistor. Once it drops to 30% of 5V the Arduino sees it as being "LOW".
If you don't have the pull-down resistor, when you remove the 5V from the input that capacitor is still charged. So the Arduino still sees it as a HIGH. The charge in the capacitor will slowly bleed away until it's low enough to be seen as low.
But, (and it's a big but), the capacitor is very sensitive and can be charged up again by ambient energy around the place (radio waves, static electricity, etc). It can harvest enough energy from the environment to get back up to the 60% of 5V and be seen as "HIGH" again. This is known as "Floating", and is something you do not want in your circuit. The input "flaps around" between HIGH and LOW with no control.  Which is why the pull-down resistor is absolutely essential.

I have one question about this answer, doesn’t the voltage drop across the LED or resistors or something like that, I just watched a video and it made me confused about this answer.

LEDs are a special case. They are in the "non linear" category, and you shouldn't worry about them at the moment. As for "voltage drop", yes, and it is. In simple terms: Ohm's Law has three variables. At any one time two of those variables are fixed, and you are calculating the third. In the circuit above the voltage is fixed and the resistance is fixed - so the current is what you would calculate. The voltage is 5V simply because it is 5V. The resistance is 10kΩ because it's a 10kΩ resistor. The combination of those two values causes 500µA to flow. ... cont ...

Of course, if you knew that there was 500µA flowing through a 10kΩ resistor then you could calculate that there was 5V being dropped across it.  The 5V in the circuit above is called a constant voltage supply. That is because it is always 5V (unless you overload it of course). The current that the supply gives out varies depending on the load (the values of the resistors in this example).

So, you are saying that the reason that it doesn’t drop is only because we already know that there are 5V? Could you please explain, sorry, I’m really trying to wrap my head around all of this.

It does drop. One side of the resistor is 5V. The other side is 0V (ground). The difference is 5V, and that is what is "dropped" across the resistor. The fact that the 5V is fixed in stone means that the current is determined by the resistance and the voltage in the formula I=V/R.

I promise I’ll try not ask another question, I’m really sorry. But how do you know that there are 0V on the other side of the resistor. Sorry. Is there a place I can understand this or figure out what is going on?

Because that is "ground" - a point in the circuit which we have chosen to measure all voltages against. The "reference" point of the circuit. "Ground" isn't anything special - it's simply a place we pick in the circuit to be that reference point. Typically it's the point of lowest potential, such as the - terminal of a battery, etc. Since "GND" has already been designated by the power supply that's connected (USB, for example), we just pick that as our refrerence point.  The 5V is not "5V" - it's "5V with respect to ground".

The "bottom" of the resistor is connected direct to ground. Ground is 0V different to Ground (how can something be different to itself?), so that point is 0V. The 5V is 5V higher than the potential at the ground point, so we say that is 5V with respect to ground. Since everything is always "with respect to ground" we never say "with respect to ground" and just take it as read.

To put it another way: A 9V battery isn't "9V" because the + terminal has 9V at it. It's 9V because the + terminal has 9V more potential than the - terminal. It only becomes 9V when you take that - terminal as the reference point. You could just as well take the + terminal as the reference point - at which moment the battery becomes a "-9V" battery, becuase the - terminal has 9V less potential than the + terminal. It's all relative. So when we pick a "ground" reference it makes sens to use one that gives the power supply a meaningful value.

I think we had a misunderstanding, I’m wondering why the voltage isn’t dropping across the resistors and 5V is still going into the input?

5V is dropping across the resistors. You have 5V (with respect to ground) on the top of it, and 0V (with respect to ground) at the bottom of it. That's 5V from one side to the other. Ergo 5V "dropped". But that doesn't mean that the top of the resistor will no longer be 5V. It has to be, for there to be 5V across the resistor.

Ok, this is the final part, I have done the math to clear up my question. Using the math shown here https://youtu.be/hqHvRCCsWU8 I made the resistance of the input wire be V(little r2, no way to format here) and assuming this is about 1 million ohms, and the 10k ohm wire be V(little r2, again no way to format here). Then doing the math I get that 4.95 volts are going into the input wire and .0495 volts are dropping across the 10k oh right resistor. Is this correct? If it is it is what I was trying to say and why I was questioning the fact that you said 5V went into the input wire.

No, that is not correct. You are looking at tutorial for series resistors. This is parallel resistors. There can be nothing but 5V going to the input, since the input is directly connected to 5V.

Oh! Thanks so much, one more thing, though if there is a 1 million ohm resistor (basically) at the input and the voltage drops to 0 (parallel circuit) then if the voltage is zero how does the arduino read that as HIGH? @Majenko

The voltage at the input is NOT zero. It is 5 Volts. It is zero at GROUND. The input is not connected to ground. It is connected to 5V.

Let us continue this discussion in chat.

the answer is within the question,
Electrons will quite happily travel along a wire until they hit resistence as in a resistor.
where there is less resistence too flow that is the path they will take.
The path of least resistence you might say.

That seems misleading, because the current will not flow only through the path with the least resistance. Instead the current is divided between all paths relative to their resistance.

agreed but at that level of understanding it seemed a fair answer

Sorry Jamie, but you are sending a beginner down the wrong path.

ok but please construct a clearer more concise answer

@Jot he's sending the user down the path of least resistance...


text:
Arduino Nano input voltage
Can I supply an Arduino Nano 5 V 1 A unregulated in pin 27?
It has a PIR sensor, a LDR sensor and switch drive high power MOSFET trigger module connected to it.

Probably not. Pin 27 is the 5V pin. That is the voltage at which the microcontroller runs. It is safer to use the VIN pin with 7.5v, although sometimes 5v is applied to the 5v pin, but that could destroy the voltage regulator. The most dangerous part is the word "unregulated". Does that mean that it can be anything between 4 and 7v? Do not apply that to the 5v pin.

Okay. Thank you!


text:
Reducing json upload time
I'm using an ESP32 WROOM board to capture some data in the field and send it over using arduino json. However, the complete process of sending and receiving confirmation takes up around 12 seconds and my ESP is frozen in that time. As a result, I lose the data in that time window. Is there a way to reduce the upload time of the ESP or maybe continue taking data while it is uploading?
Here is my data sending code for reference.

jsonBuffer.clear();
JsonObject &rootObject = jsonBuffer.createObject();
JsonObject &dataObject = rootObject.createNestedObject("data");
JsonArray &X1dataObject = dataObject.createNestedArray("X1");
JsonArray &Y1dataObject = dataObject.createNestedArray("Y1");
JsonArray &Z1dataObject = dataObject.createNestedArray("Z1");

if (wifiMulti.run() == WL_CONNECTED) {
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

if (send_flag) {
  send_flag = false;
  int connection_iterator = 0;
  int connection_iterator2 = 0;
  for (int iterator = 0; iterator < SAMPLE_SIZE; iterator++) {
    X1dataObject.add(X1dataArray[iterator]);
    Y1dataObject.add(Y1dataArray[iterator]);
    Z1dataObject.add(Z1dataArray[iterator]);
  }

  rootObject["coreid"] = String(low, HEX) + String(high, HEX);
  //rootObject["coreid_high"] = String(high, HEX);
  rootObject["sample_time"] = int(time_taken);
  rootObject["firmware_version"] = FIRMWARE_UPDATE_VERSION;
  rootObject.prettyPrintTo(Serial);
  Serial.print("connecting to ");
  Serial.println(host);
  while ((!client.connect(host, httpsPort)) && !setup_mode) {
    connection_iterator++;
    Serial.println("connection failed! Retrying..");
    digitalWrite(LED2, HIGH);
    delay(5000);
    digitalWrite(LED2, LOW);
    delay(5000);
    if (connection_iterator >= 10)
      ESP.restart();
  }
  if (client.verify(fingerprint, host)) {
    Serial.println("certificate matches");
  } else {
    Serial.println("certificate doesn't match");
  }
  digitalWrite(LED_BUILTIN, HIGH);
  Serial.print("requesting URL: ");
  Serial.println(url);
  client.println(String("POST ") + url + " HTTP/1.0");
  client.println(String("Host: ") + host);
  client.println("Cache-Control: no-cache");
  client.println("Content-Type: application/json");
  client.print("Content-Length: ");
  client.println(rootObject.measureLength());
  client.println();
  //rootObject.printTo(client);
  Serial.println("NUMBER OF INTERRUPTS:");
  Serial.println(interruptCounter);
  Serial.println("request sent");
  while ((client.connected()) && !setup_mode) {
    connection_iterator2++;

    String line = client.readStringUntil('\n');
    if (line == "\r") {
      Serial.println("headers received");
      break;
    }
    Serial.println("Waiting for response");
    digitalWrite(LED2, HIGH);
    delay(1000);
    digitalWrite(LED2, LOW);
    delay(1000);
    if (connection_iterator2 >= 20)
      break;

  }
  String line = client.readStringUntil('\n');
  if (line.startsWith("{")) {
    Serial.println("esp8266/Arduino CI successfull!");
  } else {
    Serial.println("esp8266/Arduino CI has failed");
  }
  Serial.println("reply was:");
  Serial.println("==========");
  Serial.println(line);
  Serial.println("==========");
  Serial.println("closing connection");
  digitalWrite(LED_BUILTIN, LOW);
  // readRegister(INT_SOURCE, 1, &dummy_read);
}

In general, you would need to examine, in detail, which individual steps are taking the most time and try to find out how to reduce that. 12 seconds is enormous for sending an HTTP request and getting a reply, and the delay might be in the ESP32 code, might be in the website receiving the data, etc. Find out where most of the time is wasted and focus efforts there. (I am assuming sending data is an HTTP POST or GET, as json is not a protocol, but a structured text format.)

you send it as many small writes? https://github.com/jandrassy/StreamLib/blob/master/README.md

JSON can be very verbose. It might be easier to send a regular GET request with a few data-variable in the query string.

esp32 is dual core. you can send on one core while the other continues to capture data. it is a bit complicated to get going, but works well. Aside from that, 12 seconds seems too long, maybe you should post some code here and we might be able to speed that up.

How big is this data? 12 seconds on the lowest connection speed - say 1mbit is, and taking into account some overheads, would be over 1megabytes of data - are you really sending that much?

I don't think I'm sending that much data. It just consists of 350x3 data points from the accelerometer and some header info for the server side. I am also trying to use the other core for sending data but it is giving task wdt issues. I will post my data sending code above.

my comment applies. the rootObject.printTo writes in small pieces. wrap client into BufferedPrint from StreamLib

Hey, @Juraj will the StreamLib be able to send the rootObject as it is or I would have to store the values in a different buffer to be sent over>

And also if I use the BufferedPrint the Json encoding will be lost which I can't afford.


text:
How can I compare two serial port readings on Arduino Mega?
I'm writing some code that compares information from two Arduino Unos by an Arduino Mega 2560. The problem that I'm having is that when I read the information coming in through Serial1 and Serial2 on my if statements, I get both inputs out on my serial monitor for the Mega, but if I try to compare them after I have read them it comes out not working the way it is intended. I don't know if I might be missing some syntax on my code or if I'm doing this wrong but I would appreciate any help I can get.
byte inData;

byte inDataTwo;

void setup()
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  Serial1.begin(9600);
  Serial2.begin(9600);

  while (!Serial)
  {
    ; // wait for serial port to connect. Needed for native USB port only
  }
}

void loop()
{
  if (Serial1.available()>0 )
  {
      inData = Serial1.read();
      Serial.print(char(inData));
  }
  if (Serial2.available()>0)
  {
    inDataTwo = Serial2.read();
    Serial.print(char(inDataTwo));
  }
  if(inData == inDataTwo)
  {
    Serial.print("true");
  }
  else
  {
    Serial.print("False");
  }
}`

can you provide a sample output as well..!?

what do you mean sample output? when i get the information on the arduino mega i get the results from both my arduino unos and i can display them on the screen. im sending letters through a laser and the two arduinos convert the information back to characters and i can display that on the screen. when i connect them to the arduino mega the mega displays both of the same character on the screen. I know is working but when i compare them, the program seem to do not what i want to do

print them in else

can you tell what are you sending on serial terminal?

Also, I see a small character after your last bracket for the loop(). I thought that it was a speck of dirt on my screen, but you actually have a character.

I think your code is implemented wrong in general. Even if it worked "like intended" it would not behave like you might want it to.
The first problem is, that you are polling for bytes that are received asynchronuously. That means that  two byte sequences must not only be equal, they must also be sent "at the same time" if they should pass your comparison test. As the atmega will loop() very fast, there is only very little tolerance in timing.
Secondly, the variables you write received values to are not reset, meaning that once they have the same value they will pass the if statement until another byte has been received. Actually they aren't initialized and therefore will be 0 at the very beginning. So I wonder why you don't get your Serial interface flushed with true. Is this actually the entire code?
As a solution I suggest accumulating received bytes into a buffer and waiting for a soecific termination byte (often /n). If a termination character has been received, perform the comparison on that buffer.


text:
Help with coding Arduino Nano to run fan through slide switch at specific intervals
I’m trying to use Arduino Nano to run my 5 V PC fan, which, I know it sounds crazy, it’ll be mounted on a piece of Tupperware that’ll control the airflow through it via the fan. However I have no idea how to code the Arduino, but I do know how to code other things when I’ve done it in class. The setup is a 5 V rechargeable lithium ion portable battery connected to the switch which would be connected to the Arduino, and when the switch is triggered/flipped it would allow power to the Arduino, boot it up, and trigger the code that would tell the fan to run at specific intervals. The idea for intervals is a result of the battery only having 23 hrs and 10 minutes of continuous battery life while powering the fan. The pseudocode would look something like:

Press bump switch, it turns on the Nano with the ensuing program. Twice an hour, the Nano starts the fan. The fan runs for 20 seconds to 30 seconds each time the fan is started. After a set of 48 on/off cycles have completed (24 hours), the Nano is set to sleep mode in order to save power. In order to restart cycles, user must press bump switch again.

I’m pretty sure I have the hardware side of things down but if I don’t please do inform me.
I’ve attached a picture of what it’ll approximately look like, with the battery at the left, switch in the middle, then the Arduino (not seen in picture), then the fan.

I know this is asking a lot when I don’t even know where to get started with the coding, but I’d be sincerely eternally grateful.

A schematic and some code would be useful to see, although you state that you don't have any code yet...

You can't run the fan directly from an Arduino pin. The fan will require to much current for that to work. Instead connect the fan, via a transistor/mosfet to the Arduino.
Also add a (flyback-)diode to the fan, as turning of the fan can create huge (but short) voltage spikes, which can damage the transistor/mosfet.
Pseudo code would be something like:
for( byte i=0; i<48; i++ )
{
  digitalWrite(fanPin, HIGH);
  delay(20000);
  digitalWrite(fanPin, LOW);
  delay(1780000);
}

You could also put the Arduino in sleep mode, during those half hours, as well. You could use the LowPowerSleep library. Then replace the delay(ms) with LowPower.sleep(ms).
Lastly, some powerbank will automatically shut down, if the detect nothing is using power. The Arduino, without the fan on, will use so little current (compared to charging a phone) that such a powerbank would shut of.

Decent answer, although using delay is teaching bad habits that will need to be unlearned almost immediately. (To the OP, the delay() function causes your app to freeze, so if you need to write code that does something else in a delay function. Better to use the millis() function and some math to record the start time of an event, and check to see when the desired amount of time has elapsed. Search on "Arduino blink without delay" to find sample code explaining the technique.


text:
Error while compiling CODE
Hey guys I have run my example with esp8266 2.4.2 version now I'm getting following error while compiling- C:\Users\Shree\Desktop\FirebaseDemo_ESP8266ex\FirebaseDemo_ESP8266ex.ino:21:29: fatal error: FirebaseArduino.h: No such file or directory #include  ^ compilation terminated. exit status 1 Error compiling for board NodeMCU 1.0 (ESP-12E Module).
I'm trying to run FirebaseDemo_ESP8266 example but getting problem to compile that code. plzzz help me to solve this issue.

install the library

which libraries I need to install.?

FirebaseArduino.h?

It's strange that the missing library isn't mentioned in the error message, just an ^. Or is it a copy and paste error?

FirebaseArduino.h: No such file or directory it is mentioned in your error message

Hey guys Thank you sooo so much to all of you for helping me. Finally after installing FirebaseArduino library now I'm able to compile code without any error.