text:
Using 5V arduino with 12v solenoid lock
I wish to use an arduino like this with a 12v solenoid lock like this. How can I do this. I am told that using this might work, but I am also thinking I can use a transistor's amlification to do that. Can you tell which one is better and if transistor, how to do that?

you can definitely use a somewhat small transistor (600mA) for that. search the web for "arduino relay interface", choose a circuit, subsitute the relay with your solenoid, and you're done.

That ebay solenoid does not distinguish in its "datasheet" between its pull and hold power consumption; not does it list real and apparent/total power. Good luck sizing a transistor for that. Also if I multiply their stated current and voltage (presumably to get total power), I get less than their stated real power.

@EM Fields: They state 7.5W. Also look up some real solenoid datasheets and see that the activation voltage is a few volts below the nominal one, which makes their calculation even more dubious. And no, even for a DC solenoid you have different pull and hold currents. http://electronicdesign.com/analog/what-s-all-solenoid-driver-stuff-anyhow

@EMFields: Are you saying the hold power is zero? What makes the lock return when the solenoid coil is deenergized? Some spring maybe? Doesn't the Hooke force of that need to be defeated by the solenoid in its hold position?

By sheer luck your lock solenoid looks very similar to this one (similar spec too "Draws 650mA at 12V") and they have a working circuit for it over here so look at that and see what they used to drive it. Apparently it's a TIP120, so the peak/draw current is probably higher than that ballpark figure, which I suspect is for the hold.

Overengineering the transistor by an order of magnitude or so (for a poorly spec'd solenoid part) ensures it doesn't go pop so easily. Also, a Darlington like TIP120 is very easy to drive from the arduino or some other microcontroller.
A similar project using the same solenoid lock used an IRLB8721 (power MOSFET) instead, which is even more beefy in terms of load current it can handle.


text:
Is it possible to make a mathematical function generator using Arduino?
I want to build a function generator but not the ones which outputs square wave or sawtooth ect. I will input a discrete function lets say f(n) = e^n for n=0 to n=100 and the output array will be outputs as voltage samples creating a e^x like signal on a scope?
Is this possible?

If you attach some kind of DAC to it - why not?

but doesnt Arduino have already its own DAC?

No, why would it? Before assuming something, check the specs.

sorry Im not into micro controllers much. Isnt Arduino's analog output a DAC? if not whats that?

If you refer the analogWrite function - it is setting PWM output.

oh ok now I got it thanks. what would you recommend as a DAC converter in this case? im not into DAC hardware.

Arduino DUE has a built-in DAC (has two in fact) and so you can do arbitrary function generation fairly easily by just going over some arbitrary table (that sampled the function) and output that with analogWrite to the DAC channel[s]; details in this arduino.cc tutorial. They only show sine/triangle/square waves there, but if you look at Waveforms.h at the end of that tutorial you can put arbitrary shapes in there.
By the way this technique of waveform generation of using a lookup table and a DAC is abbreviated DDS for Direct Digital Synthesizer.
Here's a more conceptual tutorial on DDS (not involving arduino):
http://www.ni.com/white-paper/5516/en/
The DACs built-in Arduino DUE have 12-bit resolution by the way, i.e. 4096 discrete output levels. IF you need better than that, an external DAC is required, which you could connect by TWI/SPI etc.
You can get a poor man's DAC on the Arduino UNO or Leonardo by PWMing with analogWrite on the GPIO pins (as suggested in the other answer), but you need understand low pass filter fundamentals to get that done.

... or create an R-2R ladder on any number of IO pins you want.

@Majenko: yes, that can surely can be done but it can well turn into a project by itself: e.g http://pcarduino.blogspot.com/2013/11/arduino-r-2r-ladder-audio-dac.html

You can generate arbitrary waveforms using either the built-in PWM and a low-pass filter or an external DAC.
You won't get more than 16-bits in PWM ( or AFAIK non-audio DAC with arduino libraries ), so your e^N function will be below your resolution for most of the cycle.
Alternatively, generate a saw-tooth and use an op-amp exponential function

no I just gave an e^n as an example. I want to make one which can output any given simple function.

You can't generate arbitrary waveform using PWM, unless you have some kind of PWM-to-waveform circuitry. And the bitness of DAC is depending on DAC only, and can be as high as specified by the DAC itself.

@EugeneSh.  Add an appropriate low pass filter and PWM becomes a low-quality DAC.  If you can find a greater than 16 bit, non-audio, DAC with an arduino library, post a link.

I would say that you CAN generate arbitrary waveforms using PWM. All you need is a reconstruction filter. All 1 bit DA (sigma delta) converters basically use PWM. BUT the PWM signal from an Arduino is very low in frequency (around 400 Hz) and only 256 levels (8 bit) so very crude. You could make a half decent 10 Hz arbitrary waveform though. But note the 10 Hz, not very usefull !

Filter = circuitry. Why audio is a constraint?

Audio DACs are usually limited to a sample rate of around 200 kHz. It could be sufficient depending on what arbitrary frequency you want to generate.

whats the thing anout 16 bit? why ui that a limit?

Perhaps it's not easy (or impossible?) to find any off-the shelf gen purpose DAC with higher than 16-bits resolution. But here is an App note of a 20-bit DAC concept: http://cds.linear.com/docs/en/application-note/an86f.pdf

@EugeneSh. I think the average Arduino user has enough of a challenge to a 12 or at best a 14 bit DAC to its rated spec, higher resolution DACs are just more expensive. 20 and even 16 bit DAC's are a healthy challenge for EE pro's, let alone for hobbyists.

@jippie I agree. Just theorizing :)

@EugeneSh. As long as, in your theorising, you realise that Arduino level hardware is generally not going to outperform a 5mV to 10mV noise figure. So anything beyond 12bit with +/-5LSB accuracy at 5V reference is wasted money anyway.

@Asmyldof Why should I care of Arduino hardware, if I have some kind of I2C controlled DAC?

@EugeneSh. Because the comment was towards "Arduino level Hardware". If the OP is going to buy a DAC board ("not really into DAC hardware") and hook it up in the general way, that'll easily be 10mV coupled noise, if not more.

@user16307 PWM on ATMega uses the timers, the highest resolution one being 16 bit. As the others have noted, you probably will hit noise issues before then, but the point was more that when thinking about generating such-and-such a waveform, if a 16 bit DAC won't give you anything 90% of the time, your waveform is probably not realistic on any home-made hardware.

source: Stack Exchange

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

sort: votes


text:
Problem with L293D controlled motors using IR pilot remote
I have a problem with my line follower:
My robot has 4 wheels with DC motors connected to L293D shield (Arduino Uno).
The robot is a line follower controlled by IR pilot with an IR receiver, it has 4 IR sensors(two in the back and two in the front). The robot goes forward if none of sensors sees the black line.
When I click > button, the robot should use only the sensors in the front and follow the line until the end of the road made of black tape, and when I click < it should use only the sensors on the back and run CarBackward() (go backwards).
The robot should only stop working if I click 0 button on the pilot (CarStop() function). So without the IR remote code the robot drives normally, but when I add the code for the pilot only two right motors work, they spin forward and nothing else happens no matter if one, two or none sensors see the line.
Everything is powered by two 18650 batteries.
The IR pilot receiver is connected to A0 pin on the shield - pin 14 (which can be used as digital).
#include <IRremote.h>
#include <AFMotor.h>

int IRsensorPin = 14;
AF_DCMotor motor1(1);
AF_DCMotor motor2(2);
AF_DCMotor motor3(3);
AF_DCMotor motor4(4);

IRrecv irrecv(IRsensorPin);
unsigned long key_value = 0;
decode_results results;

const int back_left_sensor_pin = A0;
const int left_sensor_pin = A1;
const int back_right_sensor_pin = A2;
const int right_sensor_pin = A3;
int left_sensor_state;
int back_left_sensor_state;
int right_sensor_state;
int back_right_sensor_state;

void CarBackward()
{
  if (back_left_sensor_state > 500 && back_right_sensor_state < 500)
  {
    Serial.println("turn right");
    motor1.run(BACKWARD); // LP
    motor2.run(RELEASE); // LT
    motor3.run(BACKWARD); // PT
    motor4.run(FORWARD); // PP

    motor1.setSpeed(160);
    motor2.setSpeed(130);
    motor4.setSpeed(180);
    delay(20);
  }

  if (back_left_sensor_state < 500 && back_right_sensor_state > 500)
  {
    Serial.println("turn left");
    motor1.run(FORWARD); // LP
    motor2.run(BACKWARD); // LT
    motor3.run(RELEASE); // PT
    motor4.run(BACKWARD); // PP

    motor1.setSpeed(180);
    motor4.setSpeed(160);
    motor3.setSpeed(130);
    delay(20);
  }

  if (back_left_sensor_state < 500 && back_right_sensor_state < 500)
  {
    Serial.println("forward");
    motor1.run(BACKWARD); // LP
    motor2.run(BACKWARD); // LT
    motor3.run(BACKWARD); // PT
    motor4.run(BACKWARD); // PP

    motor1.setSpeed(110);
    motor2.setSpeed(110);
    motor3.setSpeed(110);
    motor4.setSpeed(110);
    delay(20);
  }

  if (back_left_sensor_state > 500 && back_right_sensor_state > 500)
  {
    Serial.println("stop");
    motor1.setSpeed(0);
    motor2.setSpeed(0);
    motor3.setSpeed(0);
    motor4.setSpeed(0);
    delay(20);
  }
}

void CarForward()
{
  if (right_sensor_state > 500 && left_sensor_state < 500)
  {
    Serial.println("turn right");
    motor1.run(FORWARD); // LP
    motor2.run(FORWARD); // LT
    motor3.run(RELEASE); // PT
    motor4.run(BACKWARD); // PP

    motor1.setSpeed(160);
    motor2.setSpeed(130);
    motor4.setSpeed(180);
    delay(20);
  }

  if (right_sensor_state < 500 && left_sensor_state > 500)
  {
    Serial.println("turn left");
    motor1.run(BACKWARD); // LP
    motor2.run(RELEASE); // LT
    motor3.run(FORWARD); // PT
    motor4.run(FORWARD); // PP

    motor1.setSpeed(180);
    motor4.setSpeed(160);
    motor3.setSpeed(130);
    delay(20);
  }

  if (right_sensor_state < 500 && left_sensor_state < 500)
  {
    Serial.println("forward");
    motor1.run(FORWARD); // LP
    motor2.run(FORWARD); // LT
    motor3.run(FORWARD); // PT
    motor4.run(FORWARD); // PP

    motor1.setSpeed(110);
    motor2.setSpeed(110);
    motor3.setSpeed(110);
    motor4.setSpeed(110);
    delay(20);
  }

  if (right_sensor_state > 500 && left_sensor_state > 500)
  {
    Serial.println("stop");
    motor1.setSpeed(0);
    motor2.setSpeed(0);
    motor3.setSpeed(0);
    motor4.setSpeed(0);
    delay(20);
  }
}

void CarStop()
{
  Serial.println("stop");
  motor1.run(RELEASE);
  motor2.run(RELEASE);
  motor3.run(RELEASE);
  motor4.run(RELEASE);
  delay(200);
}

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  irrecv.enableIRIn();
  irrecv.blink13(true);
  motor1.setSpeed(130);
  motor2.setSpeed(130);
  motor3.setSpeed(130);
  motor4.setSpeed(130);
}

void loop()
{
  left_sensor_state = analogRead(left_sensor_pin);
  right_sensor_state = analogRead(right_sensor_pin);
  back_left_sensor_state = analogRead(back_left_sensor_pin);
  back_right_sensor_state = analogRead(back_right_sensor_pin);

  static int wariat_na_lini = 1;  // if = 1 follow the line and go forward, if -1 go backwards

  if (irrecv.decode(&results)) // have we received an IR signal?
  {
    if (results.value == 0xFFFFFFFF) // if the value is equal to 0xFFFFFFFF
    {
      results.value = key_value; // set the value to the key value
    }
    switch (results.value)
    {
      case 0xCBA816E1:
      case 0xC078:
        Serial.println("right button");
        wariat_na_lini = 1;
        break;
      case 0x43D69629:
      case 0xC0F8:
        Serial.println("left button");
        wariat_na_lini = -1;
        break;
      case 0xA6F5461D:
      case 0xC004:
        Serial.println("stop button");
        wariat_na_lini = 0;
        CarStop();
        break;
      default:
        Serial.println("different code");
        break;
    }
    key_value = results.value; // store the value as key_value
    irrecv.resume(); // reset the receiver for the next code
  }

  if (wariat_na_lini > 0) CarForward();
  else if (wariat_na_lini < 0) CarBackward();
}

So my question is - why are there only right motors working when the ir receiver is plugged?
This is my motor driver:

You may want to edit your question to add in a link for your exact shield.

edited, i thought that it was obvious that i want to know why doesnt it work with the sensor in? i've added an image of this l293d motor driver

@WojtekHawryluk, it is possible that it wasn't needed.  Then again, it may be that it factored into the answer you just received.

Your problem is most likely this line:
  irrecv.blink13(true);

That is intended to flash an LED on pin 13 when you use your IR remote. However pin 13 is also used by the motor shield as part of the serial protocol to communicate with the control chips.
By using that you are confusing the motor shield.
Just remove that line should allow the motors to work again.

didn't help, deleted this and still only right motor worked for a while, then turned off after a few seconds and i had to turn it off and on again.

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


text:
Unable to upload any sketch but Serial Monitor keeps displaying "Start scan, Scan done, Network found" message
I have bought a new Mega 2560 with WiFi.
I tried to upload a sketch that worked OK with the previous Mega 2560 but the upload always fails with the following error message:
*************************************************************
Arduino: 1.8.13 (Windows 10), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

Sketch uses 2762 bytes (1%) of program storage space. Maximum is 253952 bytes.

Global variables use 391 bytes (4%) of dynamic memory, leaving 7801 bytes for local variables. Maximum is 8192 bytes.

C:\Users\warph\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/bin/avrdude -CC:\Users\warph\AppData\Local\Arduino15\packages\arduino\tools\avrdude\6.3.0-arduino17/etc/avrdude.conf -v -patmega2560 -cwiring -PCOM3 -b115200 -D -Uflash:w:C:\Users\warph\AppData\Local\Temp\arduino_build_593938/2560-Mega-WiFi.ino.hex:i

avrdude: Version 6.3-20190619

         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/

         Copyright (c) 2007-2014 Joerg Wunsch

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

         Using Port                    : COM3

         Using Programmer              : wiring

         Overriding Baud Rate          : 115200

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_ReceiveMessage(): timeout

avrdude: stk500v2_getsync(): timeout communicating with programmer

avrdude done.  Thank you.

An error occurred while uploading the sketch

Can someone please help to get this issue fixed?

Did you select the correct COM port?

remove the tx rx pin and try again

you have esp8266 on USB. use the DIP switches to configure the board https://robotdyn.com/mega-wifi-r3-atmega2560-esp8266-flash-32mb-usb-ttl-ch340g-micro-usb.html

My apologies for the dumb question but did you try to upload any other, simpler, sketch on this Mega board?

Thanks a lot. All good after changing the DIP switch settings.

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


text:
Arduino MKR GSM 1400 fails to start up without Serial Monitor
This question is similar to another question, but I have added more details. See: MKR GSM 1400 Works only when connected to computer.
I have designed and built a custom board into which I plug an Arduino MKR GSM 1400. It's a basic IO abstraction level shifter as the system I am integrating to run on 24 V logic (done via opto-couplers). Everything is working perfectly and as-designed. I've added an I2C EEPROM.
When I boot the board from an external ATX supply +12 V line it doesn't complete setup. After I've left it for some time, I connect it to my PC USB port and open the serial monitor in the Arduino IDE and it simply completes the setup process and enters loop successfully.
Voltages are perfect. The 12-24 V supply is first fed through a standard 7810 (since I need +10 V for the analog lines of the controlled system) and then a 7805. The +5 V output of the 7805 is sent into the Vin of the Arduino. Measuring VIN with a DMM reads +5.07 V and VCC reads +3.33 V. I have a 3.7 V, 300 mAh 25C Li-Po connected to the battery port on the Arduino, to deal with the current requirements as specified in the documentation.
I thought this could be a power issue, so I also tried booting it with a 10 Ah USB Power bank that has 2 x 5 V, 2 A (3 A max) USB ports. Same result, until I connect the PC with the serial monitor.
Simplified Arduino Code:
#include <MKRGSM.h>
#include <Wire.h>

GSM gsm;
GPRS gprs;
GSMServer server(80);
GSMSSLClient client;
GSM_SMS sms;

void setup() {
  //Initialise Serial
  Serial.begin(9600);
  while(!Serial)
  {}
  Serial.println("Gineer.Industrial.GSM.Controller");
  Serial.println("www.gineer.co.za");
  Serial.print("Hardware Version: ");
  Serial.println(hwVersion);
  Serial.print("Software Version: ");
  Serial.println(swVersion);
  Serial.println();

  Serial.print("Connecting");

  bool connected = false;

  while (!connected) {

>>> Here is where it gets stuck until I plug in the USB Serial Monitor, and then it continues happily.

    if ((gsm.begin(SIMpinNumber) == GSM_READY) &&
        (gprs.attachGPRS(SIMgprsAPN, SIMgprsLogin, SIMgprsPassword) == GPRS_READY)) {
      connected = true;
    } else {
      Serial.print(".");
      delay(1000);
    }
  }
.
.
.

Interestingly, the +5 V output pin on the Arduino measures 4.68 V when not connected to the PC. I don't however use this pin as I have the 7805 on my board. All other voltages measure as above at all times.

your program does not fail to start up ....... take a look at your code ... examine any command lines that deal with Serial ... any of them look like they might hang up your code?

@jsotola Can you help me understand how Serial could do that? The way I understand it is that serial would just output without checking if it is connected anywhere. In fact, I can see this happening, until the point where it hangs.

https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial/

while(!Serial) {} will wait for a serial connection and in your program will block execution until it gets one.
Remove it and your program should continue without the serial monitor.

Copy and Paste will get you every time. When I noticed it I wanted to delete the question, but maybe it helps someone.


text:
How to name the temperature sensors instead of printing address using ds2482-100 and ds18b20 sensor- Help
I am using 10 ds18b20 Temperature sensors using with "DS2482-100" I2C board and Arduino
so when I am getting the output like this:- "ROM = 28 46 04 1F 0D 00 00 74 96014B467FFF0A100A 25.3 2699 Dc", so Instead of address I want to name it "Sensor-1", "Sensor-2"  like that any tutorial or help would be appreciated.

`*
Arduino library for controlling DS2482-100 and DS2482-800 1-wire masters.
Uses Wire library to communicate with DS2482 so be sure to call Wire.begin() before using the library.
Quick example modeled after Onewire example:
*/
 #include <OneWire.h>
 #include <Wire.h>
 #include <DS2482.h>
 #include <DallasTemperature.h>

 DS2482 ds(0);  //channels ds2482-800 is 0 to 7, DS2482-100 is just set 0

 byte data[12]; //holding for onewire capture
 byte addr[8]; //1wire wire address and CRC
 long time_temp;

 uint8_t sensor1[8] = { 0x28, 0x00, 0xF9, 0x1E, 0x0D, 0x00, 0x00, 0x76 };
 uint8_t sensor3[8] = { 0x28, 0x61, 0x64, 0x12, 0x3F, 0xFD, 0x80, 0xC6 };

 void setup()
 {
    Wire.begin();
    ds.reset();
    pinMode(13, OUTPUT);

    // start serial port
     Serial.begin(57600);
     time_temp = millis();
 }

 void loop()
{

   //do search

  if ( !ds.wireSearch(addr))
  {
    if(addr == sensor1)
    {
    Serial.print("sensor1");
    };
 Serial.print("No more addresses.\n");
 ds.wireResetSearch();

return;
}

Serial.print("ROM =");
for ( int i = 0; i < 8; i++) {
Serial.write(' ');
if (addr[i] < 16) Serial.print("0");
Serial.print(addr[i], HEX);
}

if (ds.crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}

//test if device code DS18b20
 if (addr[0] == 0x28) {

 //read temperature data.
  ds.wireReset();
  ds.selectChannel(0);
  ds.wireSelect(addr);
  ds.configure(0x05); //set bus on strong pull-up after next write until next command
  ds.wireWriteByte(0x44); //convert temperature on this device
  delay(770); //wait for conversion 750ms Plus margin
  ds.wireReset();
  ds.selectChannel(0);
  ds.wireSelect(addr);
  ds.wireWriteByte(0xbe);         // Read Scratchpad command

  //display hex values of scratchpad
  Serial.print(" ");
  for ( int i = 0; i < 9; i++)
  {

   data[i] = ds.wireReadByte();

  if (data[i] < 16)Serial.print("0");
  Serial.print(data[i], HEX);

}
  Serial.print(" ");

  //convert to decimal temperature

    int LowByte = data[0];
    int HighByte = data[1];
    int TReading = (HighByte << 8) + LowByte;
    int SignBit = TReading & 0x8000;  // test most sig bit
    if (SignBit) // negative
{
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
}

    int Tc_100 = (double)TReading * 0.0625 * 10;

    if (SignBit) // If its negative
{
    Tc_100 = 0 - Tc_100;
}

  //print temp for each device

   Serial.print(Tc_100 / 10);
   Serial.print(".");
   Serial.print(Tc_100 % 10);
   Serial.print(" ");
   Serial.print(millis() - time_temp);
   Serial.println(" Dc");
   }

   }

You've almost done it - but you can't compare one array to another as you would compare two ints. Instead you have to compare them byte by byte and test that both byte[0]s match, both byte[1]s match, ..., etc until you reach the end of the arrays. Some languages support comparing or doing arithmetic and array transformations on an entire array with a single statement. C++ doesn't support that.

Like JRobert said, it's not a feature of the language.  It is, however, available to you in a couple of ways on the ESP8266.  The C library (and therefore C++) has memcmp(), which will compare sequences of bytes.  The ESP8266 also comes with a fairly complete C++ standard library, including std::equal, which can be used to compare arrays of anything that supports ==.

Thanks a lot for the reply, I am trying it with 2 sensors,since I am new to this programming I am unable to write it correctly, and moreover I want to use it for 10 or more than 10 temperature sensors in that case is it possible to use memcmp(). Thank you


text:
Is it possible to read multiple buttons with the CD74HC4067?
I am working on a project with a claw machine. I am working on this chip (CD4067BE which is equivalent to the CD74HC4067) and I was wondering: can I read more than one button with the CD4067? I tried the following code, and it works great, but when I want to push two buttons, it will not read both of them as zero. Why am I using a chip with the buttons? It was to reduce I/O pins on my PCB for the claw machine. Yes, I could use a matrix, but I want control over my components, whether to turn it on or off. Also, the CD4067 includes all my buttons. I have thirteen buttons. (13 buttons). By the way, this chip is a multiplexer/demultiplexer. I am using this chip as a multiplexer. Oh, and also, I have an Arduino Mega 2560 rev3. I have followed the instructions of this question, but this doesn't answer if the chip can read more than button at one time. Thanks,
Austin
//Mux control pins
int s0 = 5;
int s1 = 4;
int s2 = 3;
int s3 = 2;

//Mux in "SIG" pin
int SIG_pin = 6;

void setup() {

  pinMode(s0, OUTPUT);
  pinMode(s1, OUTPUT);
  pinMode(s2, OUTPUT);
  pinMode(s3, OUTPUT);

  pinMode(SIG_pin, INPUT_PULLUP);

  Serial.begin(9600);
}

void loop() {

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

int readMux(int channel) {
  int controlPin[] =       {s0, s1, s2, s3};
  int muxChannel[16][4] = { {0, 0, 0, 0},
                            {1, 0, 0, 0},
                            {0, 1, 0, 0},
                            {1, 1, 0, 0},
                            {0, 0, 1, 0},
                            {1, 0, 1, 0},
                            {0, 1, 1, 0},
                            {1, 1, 1, 0},
                            {0, 0, 0, 1},
                            {1, 0, 0, 1},
                            {0, 1, 0, 1},
                            {1, 1, 0, 1},
                            {0, 0, 1, 1},
                            {1, 0, 1, 1},
                            {0, 1, 1, 1},
                            {1, 1, 1, 1}
                          };
  //loop through the 4 sig
  for (int i = 0; i < 4; i ++) {
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }
  //read the value at the SIG pin
  int val = digitalRead(SIG_pin); //return the value
  return val;
}

There is no reason why it can't be used as you want. You're not reading two buttons at once, you're only ever reading one button, the other buttons are ignored. However you should have a pullup on every button, not just the Arduino's IO pin.

Why do the buttons need a pullup resistor? How do I go about reading more than one button at one time?

The buttons that aren't being read at any one moment will be floating. You need pullups. You don't read more than one button at one time. You only ever read one button. There is only ever one button - the button that is currently selected. All other buttons do not exist.

If you cycle through the mux's inputs it'll read whatever is there--you're only reading one button at a time, but if it's quick enough, it won't matter. You'll sometimes see circuits w/ a mux that include an aggregated interrupt indicating the processor should read from the mux.

Is it possible to use LEDs instead of pullup resistors? I read about that on this tutorial: https://www.baldengineer.com/arduino-keyboard-matrix-tutorial.html

So, this "floating", is it the same as "ghosting" from that tutorial?

floating refers to an input that has a high impedance (resistance) to both ground and supply ... ambient electric charges can randomly push the input to one of the two states ........ ghosting happens in some matrix keypads, where a non-pressed key is detected as being pressed because of two, or more, other keys are pressed ... this is the result of the design of the keypad

I'm not sure if it's an issue to have floating pins on Analog MUX. Maybe some day I'll test if there is higher current draw if left unconnected, but it's not switching anything between two states (and in CMOS switching needs current), so one pull up on the muxed side might be enough. Maybe with bigger line capacitance it might get some false presses when switched to level near gnd?

Yeah, I am not so sure what floating means and I still don't get the difference.

Okay, so, I'll put the pullup resistors on. But, what I want to know is how do I read multiple buttons on the chip all at once?

You don't--you read them one at a time; that's what thismux does--turns n signals into one signal, which you select with S0-S3. Again--if you read them sequentially, with little or no delay, it's unlikely to matter--computers fast, humans slow.

Okay, so, maybe I should switch to the matrix, considering that when I read the data, even fast, it won't work for what I am doing. So, basically, I am trying to use a joystick and some other buttons to run with stepper motors (to control them) on my claw machine. But, the problem is that when I would use a button, it would scan it individually. So, the buttons would not be "smooth," the stepper would have to wait until it gets to a certain channel. It would be a bumpy ride, in other words.

I think you're over-estimating human perceptive ability, or under-estimating computer speed.

OT: Your function readMux() will be more efficient and faster if you define the constant arrays as such: static const int controlPin[] = /*...*/; and static const int muxChannel[] = /*...*/;. Currently these variables are allocated on the stack and initialized each time you call the function.

I think that you are misunderstanding the concept of a multiplexer. Its purpose is to allow multiple signals to share one signal. Therefore you can only read one at a time. If you want to read them simultaneously, you will need an input/output expander. This will allow you to sample all the signals simultaneously on command, then send the data either serially or parallely to the MCU.

Yeah, but I was just experimenting with this new chip based on that question from Electrical Engineering. I think a matrix will work well for my new PCB design.

Although, I do want to thank everyone for helping me. I know understand that the concept of the mux is to read with a single output/input. So, it HAS to read it one at a time, because I don't want extra hardware. It's been fun. I will post the link to the tutorial for my claw machine on the Arduino Forum at arduino.cc in the upcoming future. Thank you very much!

An alternative way to write to the 4-bit MUX select pins is to use shifting and masking, something like this:
// MUX control pins
byte s0 = 2;
byte s1 = 3;
byte s2 = 4;
byte s3 = 5;
byte controlPin[] = { s0, s1, s2, s3 };

. . .

byte readMux(byte channel)
{
  // Loop through the 4 signals
  for (byte b = 0; b < 4; b++, channel >>= 1)
  {
    digitalWrite(controlPin[b], channel & 1);
  }
  // Read and return the value at the SIG pin
  return digitalRead(SIG_pin);
}


text:
SIM800L HTTP request is not reliable
I have a question regarding SIM800L and HTTP GET request. I'm using this https://exploreembedded.com/wiki/Setting_up_GPRS_with_SIM800L simple code to communicate with SIM800l with AT commands. To perform the HTTP request, I use the following set of AT commands:
AT+CFUN=1
OK

AT+CSTT="internet","",""
OK

AT+CIICR
OK

AT+CIFSR
10.180.xxx.xx

AT+CIPSTART="TCP","84.42.xxx.xx",80
OK

CONNECT OK

AT+CIPSEND=52
>
GET /bakalarka.php/? HTTP/1.1
Host:84.42.xxx.xx

SEND OK
HTTP/1.1 200 OK
Date: Mon, 19 Aug 2019 16:20:27 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

10
time201908191820
0

CLOSED

The problem is that sometimes. Or every other time, I don't get the whole HTTP answer. I usually get only the beginning. Something like this:
AT+CIPSEND=52
>
GET /bakalarka.php/? HTTP/1.1
Host:84.42.xxx.xx

SEND OK
HTTP/1.1 200 OK
Date: Mon, 19 Aug 2019 16:20:27 GMT
Server: Apac

and then after a couple of seconds, the connection closes.
CLOSED

Do you know what could cause that? It's literally random. I need the information from the webpage (it's the current time) and currently, it's really unreliable.
Another question. What does the "10" and "0" mean in the HTTP request? The "time201908191820" is the current time from printed from PHP.
Thank you very much!

I've figured it out. The answer to HTTP GET request was read as a string. The string has aroud 284 bytes. Since it's so big, string gets to be saved fragmented, which is apparently a problem. The solution is to create a buffer and save the characters there from the Serial.

Thank you for your answer. The code is as follows:
#include <SoftwareSerial.h>

String Arsp, Grsp;
SoftwareSerial gsm(12, 8); // RX, TX

String GET = "GET /bakalarka.php/? HTTP/1.1\r\nHost:84.42.xxx.xx\r\n\r\n";

void setup() {

  Serial.begin(115200);
  Serial.println("Testing GSM SIM800L");
  gsm.begin(19200);

}

void loop() {

  AT("AT+CFUN=1");
  AT("AT+CSTT=\"internet\",\"\",\"\"");
  AT("AT+CIICR");
  AT("AT+CIFSR");
  AT("AT+CIPSTART=\"TCP\",\"84.42.xxx.xx\",80");

  int get_length;
  get_length = GET.length();

  AT("AT+CIPSEND=" + String(get_length));
  AT(GET);
}

void AT(String AT){

  gsm.println(AT);

  if(gsm.available()){

    Grsp = gsm.readString();
    Serial.println(Grsp);
  }
}

I was thinking about a couple of things that could cause this.
1. Hardware design - some noise could cause a freeze of the GSM module while getting the answer from the server. After thinking through I don't think it's likely to be that. The power supply is made to be really beefy and there are enough bypass caps to reduce the noise and provide enough energy during current spikes. Also, the module doesn't freeze. It's still connected to the server, after a couple of seconds it closes the connection exactly as it should be.

Serial buffer gets somehow full. This was just a quick thought. The buffer of Arduino could get somehow full so it's not able to save any more incoming data. I think it's nonsense, but...

Thank you for your answers.
Krystof

Do you know what could cause that? It's literally random.

Could be your code, could be your network provider / signal. It's impossible to tell without you providing your code for us to inspect.

Another question. What does the "10" and "0" mean in the HTTP request? The "time201908191820" is current time from printed from PHP.

Those look to be part of the response body - so they are printed by whatever the PHP script is that you are requesting. Either that or they are generated by your undisclosed Arduino program.


text:
Why am I getting wrong compass heading using magnetometer readings?
I have been trying to calculate the compass heading using the magnetometer in an MPU9250 sensor. But the result is not making sense to me. I am completely new in this and do not have much understanding in how magnetometers work and just trying to find resources in the internet to make it work. I am calculating the atan2 of the y and x axis readings of the sensor to find out the angle:
float mx = imu.mag_x_ut();
float my = imu.mag_y_ut();
float mz = imu.mag_z_ut();

float heading = atan2(my, mx) * 180 / PI;

Serial.print(mx);
Serial.print(",");
Serial.print(my);
Serial.print(",");
Serial.print(mz);
Serial.print(",");
Serial.println(heading);

My understanding is that when the x axis of my magnetometer faces the north direction the value of heading should be 0, for east 90, south 180 and then for west 270. But my calculations are nowhere near the expected results. I am not even getting a zero reading in any directon. I am attaching the screenshots of the direction reading :
This is when x axis points to north.

Rotated x axis towards east.

x towards south.

x towards west.

I have also added the raw readings from the magnetometer represnted by mx, my and mz. Is something wrong with my sensor or there is some misunderstanding from my part.
EDIT: Readings after hard iron offset compensation.

The displayed heading seems consistent with the measured mx and my. These values, however, seem wrong: The modulus of the magnetic field changes as you turn the device. It should not. Either you are doing something wrong while getting the readings, or there is something magnetic next to (or on) your device that affects the local field.

@EdgarBonet, hi can you elaborate a bit on your statement " the modulus of the magnetic field changes as you turn the device", sorry if that's a newb question. I used this library for mpu9250 https://github.com/bolderflight/invensense-imu and just calling the methods for getting the data.

I mean the norm of the vector. You can plot it: it should not depend on the orientation of the sensor. 2. Re “just calling the methods”: can you post the complete code?

Consider calibrating your magnetometer.  Off the shelf, almost all magnetometers require calibration before making use of their data.  The offset (commonly referred to as Hard Iron) and the magnitude (commonly referred to as Soft Iron) need to be found for each of the 3 sensors (X, Y & Z) for individual magnetometers.
As there is no accelerometer in this design let us simplify the problem and assume the magnetometer will always be used on a flat surface with its Z axis normal to the surface of the Earth.  Let us also assume the X and Y sensors in the magnetometer are perfectly orthogonal to one another.
To calibrate the magnetometer remove metal objects from the local vicinity and avoid large metal object such as cars by 10s of meters.  Sample the X and Y sensors many times as these sensors point toward and away from north.  Find the maximum and minimum X and Y values.
Find the offset calibration value by adding the minimum and maximum values then divining by 2.  Find the magnitude calibration value by arbitrarily picking one axis and adjusting the magnitude of the other to match.  Picking X, we subtract the X minimum from the X maximum to find the X range.  We do the same for Y to find the Y range.  Then we assume the X magnitude calibration value to be 1 and the Y magnitude calibration value to be x-range divided by y-range.
Once calibration is done, to get calibrated X and Y values we subtract the X and Y offset respectively.  Then we multiply the offset adjusted Y value by the Y magnitude calibration value.
Note, this type of calibrated compass is difficult to carry around by hand because it may not be held level with the surface of the earth.  Also, because the inclination of the magnetic field points deeper into the earth the more one travels away from the equator, it will require re-calibration when traveling to a different latitude.
Calibration calculations based on data in question:
X max to min is 42 to -22 so offset is 10 and range is 64
Y max to min is 120 to 48 so offset is 84 and range is 72
So Y magnitude calibration is 64/72 or 0.889

Data when sensors are pointed East:
Y ~48 & X ~11
bearing = atan2(((48 - Y_offset) * Y_magnitude), ((11 - X_offset) * X_magnitude))
bearing = atan2(((48 - 84) * 0.889), ((11 - 10) * 1))
bearing = atan2(((-36) * 0.889), (1 * 1))
bearing = atan2(-32.004, 1)
bearing = -1.540 rad = -88.236 degrees

If instead of -88.236 degrees the value of approximately 90 degrees is desired, change the sign of the Y sensor as part of the calibration process.
The C programming function atan2 is an enhanced form of the math arc tan operation.  The C programming function atan2 will calculate to a full 2-Pi circle.  To verify how this works use this online atan2 calculator.

You could almost derive offset and magnitude calibration values from the data posted.  But it would be better if you rotated the sensor all the way around and observe the maximum and minimum values.  Because they may not be where you expect them.  Magnetic declination changes (in what appears like a random pattern) all around the world.

Hi thanks for your response, I will try with the calibration. However is there a way to tell if the readings by the sensor are accurate? For example in case of an accelerometer I can use gravity vector as reference.  @st2000

You don't need to change the X and Y values to any of the dozens of different magnetic measurement standards!  You are only interested in the relationship between the X and Y sensors.  Since the C programming atan2 function essentially divides one by the other, you will cancel out any effort you make at calculating a given magnetic dimension standard.  BTW, I think your X and Y sensor data looks good.  I think you just need to calibrate and apply that calibration before using the atan2 function.

Okay thanks, I will work on the calibration and get back here. @st2000

Thank you for your guidance, I calibrated the sensor for hard iron offset and it's working reasonably well now. Just one quick question, even when I have kept the sensor still, the heading is not fixed, it constantly changes in a range of 5-6 degrees, how can I make this stable?

@SayantanDas: Smooth your readings using a digital low-pass filter, e.g. an exponentially weighted moving average. Beware, though, that you will have to handle the angles wrapping around at 0°/360°. I suggest you try the runningAngle library, which takes care of correctly handling the wrapping for you.


text:
Mqtt not subscribe on topic that's converted from String to char array
I am still not sure what should be the exact Title for this question, because I don't know where the problem is.
I am using #include <MQTTClient.h> mqtt library to subscribe on a topic.
This topic is created dynamically depending on the name of the device. Currently I am testing with device name myDeviceAbc.
String baseTopic  = "arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing";
String espInTopicStr  = baseTopic + "/" + config.machineName + "/espIn"; //config.machineName is a string "myDeviceAbc"

const char* espInTopic  = "";
espInTopic = espInTopicStr.c_str();

const char* hardCodedTopic = "arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn";

int rc = client.subscribe(espInTopic, MQTT::QOS0, messageArrived);
if (rc != 0) {
  Serial.print("rc from MQTT subscribe is ");
  Serial.println(rc);
  return;
}
Serial.println("MQTT subscribed");

Serial.print("size of hardcoded topic: ");
Serial.println(strlen(hardCodedTopic));
Serial.print("size of actual topic: ");
Serial.println(strlen(espInTopic));

Serial.print("hardCodedTopic >>>");
Serial.print(hardCodedTopic);
Serial.print("<<<");
Serial.println(".");

Serial.println("---");

Serial.print("espInTopic topic >>>");
Serial.print(espInTopic);
Serial.print("<<<");
Serial.println(".");

I have defined two variables for same topic
arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn
. one is hardcoded hardCodedTopic and other is created dynamically espInTopic.
when I subscribe on espInTopic, I get MQTT subscribed message on serial console BUT nothing is received on this topic when I publish from AWS portal.
but when I subscribe on hardCodedTopic I then receive all published messages. I cannot figure out what is the issue. I checked the mqttClient subscribe method inside the library header file, which is defined like this
int subscribe(const char* topicFilter, enum QoS qos, messageHandler mh);

/** MQTT Unsubscribe - send an MQTT unsubscribe packet and wait for the unsuback
 *  @param topicFilter - a topic pattern which can include wildcards
 *  @return success code -
 */
int unsubscribe(const char* topicFilter);

It does takes const char* as topic name. I though maybe due to conversion from String to char array, there might be some unknown characters appended in the char array espInTopic, but I also checked the size and content of both topics which is exactly the same.
size of hardcoded topic: 52
size of actual topic: 52
hardCodedTopic >>>arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn<<<.
---
espInTopic topic >>>arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing/myDeviceAbc/espIn<<<.

Full Code:
#include <Arduino.h>
#include <Stream.h>
#include <EEPROM.h>
#include <ArduinoJson.h>
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266WiFiMulti.h>
#include "helpers.h"
#include "global.h"

//AWS
#include "sha256.h"
#include "Utils.h"

//WEBSockets
#include <Hash.h>
#include <WebSocketsClient.h>

//MQTT PAHO
#include <SPI.h>
#include <IPStack.h>
#include <Countdown.h>
#include <MQTTClient.h>

//AWS MQTT Websocket
#include "Client.h"
#include "AWSWebSocketClient.h"
#include "CircularByteBuffer.h"

#define ACCESS_POINT_NAME  "VM"
#define ACCESS_POINT_PASSWORD  "12345678"

extern "C" {
  #include "user_interface.h"
}

//AWS IOT config, change these:
char wifi_ssid[]       = "TALKTALKAF521F";
char wifi_password[]   = "xxxxxxxx";
char aws_endpoint[]    = "xxxxxxxxxxxxxxxx.iot.us-east-2.amazonaws.com";
char aws_key[]         = "xxxxxxxxxxxxxxxx";
char aws_secret[]      = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
char aws_region[]      = "us-east-2";

String baseTopic  = "arn:aws:iot:us-east-2:xxxxxxxxxxxx:thing";
//const char* espInTopic  = "";        // was global before, but later I also tried to keep this local on subscribe() method
const char* espOutTopic  = "";
int port = 443;

//MQTT config
const int maxMQTTpackageSize = 512;
const int maxMQTTMessageHandlers = 1;

const char response[] = "{\"response\": {\"request_id\":, \"data\":}}";

String nodeName = ""; // Name needs to be unique
String nodeMac = "";

ESP8266WiFiMulti WiFiMulti;

AWSWebSocketClient awsWSclient(1000);

IPStack ipstack(awsWSclient);
MQTT::Client<IPStack, Countdown, maxMQTTpackageSize, maxMQTTMessageHandlers> client(ipstack);

//# of connections
long connection = 0;
unsigned long timer = 0;
unsigned long maxTimeOut = 7000;  //7 seconds

//generate random mqtt clientID
char* generateClientID () {
  char* cID = new char[23]();
  for (int i=0; i<22; i+=1)
    cID[i]=(char)random(1, 256);
  return cID;
}

//count messages arrived
int arrivedcount = 0;

//callback to handle mqtt messages
void messageArrived(MQTT::MessageData& md)
{
    MQTT::Message &message = md.message;

    Serial.print("Message ");
    Serial.print(++arrivedcount);
    Serial.print(" arrived: qos ");
    Serial.print(message.qos);
    Serial.print(", retained ");
    Serial.print(message.retained);
    Serial.print(", dup ");
    Serial.print(message.dup);
    Serial.print(", packetid ");
    Serial.println(message.id);
    Serial.print("Payload ");
    char* msg = new char[message.payloadlen+1]();
    memcpy (msg,message.payload,message.payloadlen);

}

//connects to websocket layer and mqtt layer
bool connect () {

    if (client.isConnected ()) {
        client.disconnect ();
    }
    //delay is not necessary... it just help us to get a "trustful" heap space value
    delay (1000);
    Serial.print (millis ());
    Serial.print (" - conn: ");
    Serial.print (++connection);
    Serial.print (" - (");
    Serial.print (ESP.getFreeHeap ());
    Serial.println (")");

   int rc = ipstack.connect(aws_endpoint, port);
    if (rc != 1)
    {
      Serial.println("error connection to the websocket server");
      return false;
    } else {
      Serial.println("websocket layer connected");
    }

    Serial.println("MQTT connecting");
    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
    data.MQTTVersion = 4;
    char* clientID = generateClientID ();
    data.clientID.cstring = clientID;
    rc = client.connect(data);
    delete[] clientID;
    if (rc != 0)
    {
      Serial.print("error connection to MQTT server");
      Serial.println(rc);
      return false;
    }
    Serial.println("MQTT connected");
    return true;
}

//subscribe to a mqtt topic
void subscribe () {
   //subscript to a topic
  String espInTopicStr  = baseTopic + "/" + "myDeviceAbc" + "/espIn";
//  String espOutTopicStr = baseTopic + "/" + config.machineName + "/espOut";
  const char* espInTopic  = espInTopicStr.c_str();
//  espOutTopic = espOutTopicStr.c_str();

  const char* hardCodedTopic = "arn:aws:iot:us-east-2:xxxxxxxxxxxxxx:thing/myDeviceAbc/espIn";
  Serial.print("size of hardcoded topic: ");
  Serial.println(strlen(hardCodedTopic));
  Serial.print("size of actual topic: ");
  Serial.println(strlen(espInTopic));

   Serial.print("hardCodedTopic >>>");
   Serial.print(hardCodedTopic);
   Serial.print("<<<");
   Serial.println(".");

   Serial.println("---");

   Serial.print("espInTopic topic >>>");
   Serial.print(espInTopicStr.c_str());
   Serial.print("<<<");
   Serial.println(".");
   int rc = 99;
   while (rc != 0){
      rc = client.subscribe(hardCodedTopic, MQTT::QOS0, messageArrived);
      if (rc != 0) {
        Serial.print("rc from MQTT subscribe is ");
        Serial.println(rc);
        return;
      } else {
        Serial.println("");
        Serial.println("MQTT subscribed");
      }
      Serial.println("rc: " + String(rc));
      delay(500);
   }

}

//send a message to a mqtt topic
void sendmessage (const char* topic, String msg) {
    //send a message
    MQTT::Message message;
    char buf[100];
    strcpy(buf, msg.c_str());
    message.qos = MQTT::QOS0;
    message.retained = false;
    message.dup = false;
    message.payload = (void*)buf;
    message.payloadlen = strlen(buf)+1;
    int rc = client.publish(topic, message);
}

void setup() {

    wifi_set_sleep_type(NONE_SLEEP_T);
    EEPROM.begin(1024);
//    for (int i = 0; i < 1024; ++i) { EEPROM.write(i, 0); }
    Serial.begin(115200);
    ardMegaSerial.begin(9600);

    delay (2000);

    //////////////////////////////////////////
  if (!ReadConfig())
  {
    // DEFAULT CONFIG
    config.configMode = true;
    config.ssid = "N.A";
    config.password = "N.A";
    config.machineName = "N.A";
    config.dhcp = true;
    config.IP[0] = 192;config.IP[1] = 168;config.IP[2] = 1;config.IP[3] = 100;
    config.Netmask[0] = 255;config.Netmask[1] = 255;config.Netmask[2] = 255;config.Netmask[3] = 0;
    config.Gateway[0] = 192;config.Gateway[1] = 168;config.Gateway[2] = 1;config.Gateway[3] = 1;
    WriteConfig(true);
    Serial.println("default configs applied");
    //////////starting web config server hotspot
        Serial.println("No configuration stored, starting access point.");
        ESP.eraseConfig();
        WiFi.disconnect();
        WiFi.setAutoConnect(false);
        WiFi.setAutoReconnect(false);
        WiFi.mode(WIFI_AP_STA);
        nodeName = String(ACCESS_POINT_NAME) + String("-") + String(WiFi.softAPmacAddress().c_str());
        WiFi.softAP(nodeName.c_str() , ACCESS_POINT_PASSWORD);
        Serial.print("Connect to ssid " + nodeName + " to configure Node on IP: ");
        Serial.println(WiFi.softAPIP());
        ConfigureWifi();
        server.on ( "/favicon.ico",   []() { Serial.println("favicon.ico"); server.send ( 200, "text/html", "" );   }  );
        server.on ( "/", send_gateway_node_config_html  );
        server.on ( "/admin/values", send_gateway_node_config_values_html );
        server.on ( "/admin/connectionstate", send_connection_state_values_html );
        server.on ( "/style.css", []() { Serial.println("style.css"); server.send ( 200, "text/plain", PAGE_Style_css );  } );
        server.on ( "/microajax.js", []() { Serial.println("microajax.js"); server.send ( 200, "text/plain", PAGE_microajax_js );  } );
        server.onNotFound ( []() { Serial.println("Page Not Found"); server.send ( 400, "text/html", "Page not Found" );   }  );
        server.begin();
        Serial.println( "HTTP server started" );
  } else {
      nodeName = String(ACCESS_POINT_NAME) + String("-") + String(WiFi.softAPmacAddress().c_str());
      Serial.println("Device already configured");
      Serial.println("Wifi SSID: " + config.ssid);
      Serial.println("Wifi password: " + config.password);
      Serial.println("Node name: " + config.machineName);

      setupWifiAndAws();
  }

    //////////////////////////////////////////

}

void setupWifiAndAws() {
    char ssidBfr[500];
    strcpy(ssidBfr, config.ssid.c_str());
    char passBfr[100];
    strcpy(passBfr, config.password.c_str());
    //fill with ssid and wifi password
    WiFiMulti.addAP(ssidBfr, passBfr);
    Serial.println ("connecting to wifi");
    while(WiFiMulti.run() != WL_CONNECTED) {
        delay(100);
        Serial.print (".");
    }
    Serial.println("\nconnected");
    ardMegaSerial.println("ESP Started\n");
    //fill AWS parameters
    awsWSclient.setAWSRegion(aws_region);
    awsWSclient.setAWSDomain(aws_endpoint);
    awsWSclient.setAWSKeyID(aws_key);
    awsWSclient.setAWSSecretKey(aws_secret);
    awsWSclient.setUseSSL(true);

    if (connect ()) {
        String espOutTopicStr = baseTopic + "/" + config.machineName + "/espOut";
        espOutTopic = espOutTopicStr.c_str();
        subscribe();
        sendmessage (espOutTopic, "{\"device\":\"connected\"}}");
    }
}

void loop() {

  receiveFromArduino();
  //responseTimeOutCheck();
  //keep the mqtt up and running
  if (awsWSclient.connected ()) {
      client.yield(50);
  } else {
    //handle reconnection
    if (connect ()){
      subscribe ();
    }
  }

}

in that case, the difference should be clearly shown in Serial.print(espInTopic) ?
but I will paste in my full code today.

how can I check weather its valid later ?

its not global.

The c_str() function of the String class returns a pointer to current internal char array. This pointer is valid only until the String exists and is not changed.
Variable espInTopicStr is defined in a function and is destroyed at the end of the function. It frees the memory allocated for the internal char array.
You send a pointer to the internal char array of the espInTopicStr to client.subscribe. The MQTT library doesn't copy that char array, it only stores the pointer. Later the library uses the pointer to call the topic, but the memory on that location already changed and doesnt't contain the name of the topic.

placing the string espInTopicStr global, worked !... thank you so much Juraj for pointing out the issue :)


text:
Second item in array not gets assigned from struct object, ArduinoJson
I got the below code generated this amazing tool.
const size_t capacity = JSON_ARRAY_SIZE(2) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(4) + 2*JSON_OBJECT_SIZE(7);
DynamicJsonDocument doc(capacity);

JsonObject config = doc.createNestedObject("config");
config["type"] = "power_plug";
config["chip_id"] = "12345";
config["mac_address"] = "abc";

JsonArray config_attachments = config.createNestedArray("attachments");

JsonObject config_attachments_0 = config_attachments.createNestedObject();
config_attachments_0["name"] = "socket";
config_attachments_0["input_type"] = "toggle_switch";
config_attachments_0["on_state"] = "on";
config_attachments_0["off_state"] = "off";
config_attachments_0["pin_type"] = "output";
config_attachments_0["pin"] = 15;
config_attachments_0["current_state"] = "on";

JsonObject config_attachments_1 = config_attachments.createNestedObject();
config_attachments_1["name"] = "socket_1";
config_attachments_1["input_type"] = "toggle_switch";
config_attachments_1["on_state"] = "on";
config_attachments_1["off_state"] = "off";
config_attachments_1["pin_type"] = "output";
config_attachments_1["pin"] = 12;
config_attachments_1["current_state"] = "off";

serializeJson(doc, Serial);

This prints out the desired json properly. but when amend single line from the second array item, to take the on_state from my struct object d_config,
Serial.println(">>" + d_configs.peripherals[1].current_state);
Serial.println(">>" + d_configs.peripherals[1].on_state);
config_attachments_1["on_state"] = d_configs.peripherals[1].on_state;

the parsing gets quiet unexpected, and some of the keys from serialised string json gets missing. For above case, This gets printed in serial monitor;
>>off
>>on
{"config":{"type":"power_plug","chip_id":"12345","mac_address":"abc","attachments":[{"name":"socket","input_type":"toggle_switch","on_state":"on","off_state":"off","pin_type":"output","pin":15,"current_state":"on"},{"name":"socket_1","input_type":"toggle_switch","on_state":"on","off_state":"off","pin_type":"output","pin":12}]}}

NOTE in the second item of attachments, the key current_state is entirely missing.
When I assign all values from this struct object, the serialised json misses many more keys... and the behaviour is quite unexpected. here is how I have defined my structs;
typedef struct Peripheral{
    String name;
    String input_type;
    String on_state;
    String off_state;
    String pin_type;
    String current_state;
    int pin;
};

typedef struct {
  String type;
  String chip_id;
  String mac_address;
  Peripheral peripherals[10];
} DeviceConfig;

I am not sure if its an issue during serialization or something else... :/
Any help would be highly appreciated :) .
UPDATE When I added three items inside attachments, then the serialized json string is missing some keys for only the last item. Seems like only the last item on the list is having problem getting serialized.

ArduinoJson stores strings differently depending on their types:

for const char*, it saves a pointer;
for other types (char*, String...) it copies the string.

Because ArduinoJson stores the copy of the string in the JsonDocument, you must increase the capacity of the JsonDocument.
In your case, you pass Peripheral::current_state, which is a String, so ArduinoJson makes a copy in the JsonDocument. Increasing capacity by a few bytes should solve the problem.
Note that the ArduinoJson Assistant also computes the number of bytes required to store all the strings. Look for "Additional bytes for strings duplication" on the right panel.


text:
Computer doesn´t recognize MKR1010
I´m learning how to use the Arduino MKR1010. When I wrote a program for controlling LEDs and to read a BMP280 sensor with a web aplication, and I uploaded the program to the board, suddenly the computer did not recognice the board.
The power LED of the board works, but I can't access the board with my computer, and I can't see in the COM ports list, and neither as a "unrecognised device" to reinstall the drivers.
I have tried with a few others USB cables and with another computer, but I still have the same problem. I have also tried to press the reset button reset and I still have the same result. What can I do to make my board work?

The MKR board connects to computer over native USB support of the MCU. The handling of the USB is done by Arduino core functions linked at build to your sketch.
A consequence of using the native USB port is, if your sketch has a problem, it influences the USB communication. In this case you can activate the bootloader to handle the USB port and the upload. It is done by double clicking the reset button on board.
This applies to other SAMD boards (Zero, M0) and to AVR boards with native USB port (Leonardo, Micro) too.

I followed these steps, I connected the board to the computer, the power led is on and the chrd led is on for a few seconds, I press the board button reset two times and the board doesn't do anything. It's possible that the board it's broken?

@mourazo, the onboard LED should start blinking with slow fade.

It  start blinking for a few seconds at the start, later it´s off and i can´t do anything with the board


text:
What kind of power cable do I need for the MKR 1010?
I see very confusing documentation on powering the Arduino MKR 1010. I would like to know what kind of cable to power it with (a weird connector port on its side).
Can I just put 5 V + (AC or DC?) on the Vin port and connect a ground?

what do you mean by weird connector? ... which one are you referring to?

@jsotola there is only one weird connector on MKR boards :-)

https://forum.arduino.cc/t/lipo-connector-for-mkr-series-seriously/854713/2

@Juraj I looked at pictures on the web, and I do not see any "weird" connectors

@jsotola it is relative. there are two connectors. one is USB, second is some JST. which one of them is the weird one? :-)

@greg your question is not very clear. Please have a read of How to ask a good question and then edit your question to suit.

The documentation shows three ways of powering the board see FAQs section Batteries, Pins and board LEDs

Using a USB connector to provide 5V to the board. Typically, this is connected to a USB port on the PC you are using to program the board. Alternatively, a USB cable connected to a standard USB power supply could be used after the program has been loaded.

Using the Vin pin to supply a REGULATED 5V (maximum 6V). Of course, this is DC. Yes, you would also connect the power supply GND to the board's GND pin.

LiPo battery. This is a little more complicated to use safely and there is documentation on that as well - see the app note here to start. You absolutely need to understand how to use a battery with that board - there are safety concerns in this regard that can't be ignored.

Hope it helps.

Thank you very much DrG. I am very new to Arduino.. There is no USB port( unless that is the small type "C"? connector on the end). I see the Vin pin and thanks to your " app note" insert I found what I need, a 2-pin JST-PH connector for the battery, now to look for it.

found a proper USB connector, on my wifes Kindle. thanks again

Just if you are wondering,The mkr1010 uses Micro USB (USB-B) arduino doc says. https://docs.arduino.cc/hardware/mkr-wifi-1010

that is not the weird connector

Then is it  this Battery connector: The connector is of type JST S2B-PH-SM4-TB(LF)(SN). Mating connector is JST PHR-2?

This maybe? Additional I2C Port
The MKR WiFi 1010 has an additional connector meant as an extension of the I2C bus. It's a small form factor 5-pin connector with 1.0 mm pitch. The mechanical details of the connector can be found in the connector's datasheet.
The I2C port, also referred to as the Eslov self-identification port within Arduino, comes with: SDA, SCL, GND, +5V, and an extra digital pin meant to send an alarm to the otherwise plain I2C devices connected to it. The pinout is shown in the following image:


text:
MKR 1010 voltage confusion
I'm very confused about powering my MKR 1010 on a breadboard. It says use USB, but that is 5.5 V and it specifically says never go above 3.3 V, yet there is a 5 V pin. So what size external power supply do I need and where to attach it? Some sites say anywhere from 3.3 to 7 V and even 12 V????

Does this Q+A help? https://arduino.stackexchange.com/a/61006/37523

As per the reference at Arduino Docs! it's nominal input voltage is between 5-7V. But make sure you apply in between 3.3V - 5V. And remember to supply it at power socket and not the 5V port itself.


text:
Help with program upload problem
I'm going to upload some code to my LeArm using an Arduino board. I connected the RX and TX pins of the LeArm to the Arduino, but I got an error message when I tried to upload the code.
I'm not sure if I made the connections correctly. Does anyone have any tips on how to upload the programs successfully?

Diagrams and actual code or error messages rather than photos of them, will help a great deal. If you update your question, please edit the question itself rather than adding comments. But from what I can read of the error messages (board not replying), either: the IDE has not got the right port selected, it has not got the correct board-type selected, the connections to your board are incorrect, or the board doesn't have the correct (or any) bootloader. That's about all I can get from what you've provided. But check out those 4 things thoroughly; one of them is the cause of your failure.

Thank you so much!

Is the Arduino Mega you have a "Chinese" version? If it is, try installing these drivers and try again.


text:
Why are the UART ports not working on my Portenta breakout board?
I am using a Portenta Arduino Breakout Board that is connected to the Portenta H7 for a project I am working on. The project requires me to use three Adafruit Ultimate GPS sensors and connect each to its own UART ports on the Portenta breakout board. I am only using UART0, UART1, and UART2 (which are respectively Serial, Serial1, and Serial2).
To be able to get data, I've been using this example code from the Arduino IDE:
// Test code for Ultimate GPS Using Hardware Serial
// (e.g. GPS for Leonardo, Flora or FeatherWing)
//
// This code shows how to test a passthru between USB and hardware serial
//
// Tested and works great with the Adafruit GPS FeatherWing
// ------> https://www.adafruit.com/products/3133
// or Flora GPS
// ------> https://www.adafruit.com/products/1059
// but also works with the shield, breakout
// ------> https://www.adafruit.com/products/1272
// ------> https://www.adafruit.com/products/746
//
// Pick one up today at the Adafruit electronics shop
// and help support open source hardware & software! -ada

// what's the name of the hardware serial port?
#define GPSSerial Serial1

void setup() {
  // make this baud rate fast enough to we aren't waiting on it
  Serial.begin(115200);

  // wait for hardware serial to appear
  while (!Serial) delay(10);

  // 9600 baud is the default rate for the Ultimate GPS
  GPSSerial.begin(9600);
}

void loop() {
  if (Serial.available()) {
    char c = Serial.read();
    GPSSerial.write(c);
  }
  if (GPSSerial.available()) {
    char c = GPSSerial.read();
    Serial.write(c);
  }
}

This code works for Serial1, and I get data when I connect a GPS to the UART1 port of breakout board. When I call for Serial, or Serial2, changing #define GPSSerial Serial1 to #define GPSSerial Serial or #define GPSSerial Serial2 the code will upload with no errors, but I am not receiving any data from the GPS when it is connected to the respective UART port (UART0 and UART2).
I checked to see if the data is automatically only coming from UART1 port but it will not show anything when I am calling for Serial or Serial2, which should be expected.
Does anyone know how to deal with this issue? Could UART0 and UART2 ports not be transferring data to the Portenta H7 board which could be why I am not seeing any data?
Please let me know if I should clarify anything.

I just spent a day tracking down this same issue. The cause is that Arduino made an absolute mess of the naming conventions for these UART ports. Please see the table below. I created this table from the Portenta Schematic and the Breakout board Schematic.

Breakout Schematic
P. Schematic @ J1,J2
P. Schematic @ Micro
Micro Pin (tx,rx)
pins_arduino.h

UART0
Serial2
UART4
(PA0,PI9)
not defined

UART1
Serial1
LPUart
(PA9,PA10)
Maybe Serial 1?

UART2
Serial3
UART6
(PG14,PG9)
not defined

UART3
Serial4
UART8
(PJ8,PJ9)
Serial 3

Unfortunately as you can see, the built in serial definitions in pins_arduino.h are not going to work for the breakout board. (unless you use Serial 1 or Serial 3)
If you want to use these other serial ports, you need to define your own serial ports which actually isn't that hard. You just have to manually specify the pins and you're off.
#include "Serial.h"
UART UART0Breakout = UART(PA_0, PI_9);
UART UART2Breakout = UART(PG_14, PG_9);
void setup()
{
    UART0Breakout.begin(115200);
    UART2Breakout.begin(115200);
}

Hope this helps you! It certainly drove me mad for a while. Unfortunately the schematic I used for the breakout board was not nearly as nicely annotated as the one I linked here (I found it while writing this answer).


text:
Sleep mode and watchdog at the same time
Suppose we want to save battery power, and we use sleep mode and also prevent the Arduino from hanging and use the watchdog timer.
The problem is here that when the Arduino goes to sleep the watchdog timer never (or can't be) reset again because of sleep and it will overflow over and over and reset the Arduino over and over.
So what do you suggest to solve this problem, I mean running sleep mode and watchdog timer at the same time in a code?

Please show us the sketch you're using.

When you sleep the Arduino is locked up. So yes, the watchdog timer will time out and reset the Arduino.
But, since you're in sleep mode, it's not so much a "reboot" as a "wakeup".
The watchdog timer is one of the normal ways of waking up periodically to do things.  If you want to use the watchdog for its other "anti-lockup" purpose then you will have to arrange some other way of waking up before the watchdog is due to expire so you can "kick" it.
Or you disable the watchdog entirely before going to sleep so that the only wakeup source is whatever source you have configured. Then you can turn the watchdog on again when you wake up.
However that probably means that the watchdog is useless, since chances are you won't be awake for long enough periods for the watchdog to have any effect.
Sleeping and using the internal watchdog as a watchdog are pretty much mutually exclusive.  If you sleep, then the watchdog is a periodic wake-up source.

If you set the arduino to sleep while the watchdog is running, the arduino will reset after the set amount of time. Unless you set the watchdog to trigger an interrupt. The watchdog isn't a wake-up source, unless you set it up as one. Also note that the watchdog unsets the interrupt when triggered. This is so that, if the program hangs, the first timeout it will call the interrupt, and the second timeout will cause a reset.

Either set the watchdog to 8s, and setup the WDT interrupt. And deal with the fact that the MCU wakes up every 8s. You could have it go back to sleep, unless a button is pressed, or something. The extra power usage for these short wakeups is negligible in most cases.
Or disable the watchdog right before sleeping, and enable right after waking up. And hope the MCU never hangs in between.

the periodically reset(or reboot) doesn't hurt the MCU?

No. Won't hurt the MCU.


text:
Can not receive data from Python code
I want to send 4 float numbers from Python code to an Arduino; I was trying to send it via serial and I have some problems.
here is my Python code:
import time
import serial
import struct

data = serial.Serial('COM6', 9600, timeout=1)
time.sleep(1)

while True:
   a = str(47.256*1000)
   data.write(a.encode())

Here is my Arduino code :
String msg;

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

void loop()
{
  if (Serial.available()) {
    msg = Serial.readString();
  }

  if (msg.toInt()>30){
    digitalWrite(13, 1);
  }
}

end of code
Thanks in advance.
My problem is that it does not work (LED does not turn on while I send data from the Python code in a while loop; when I remove the while and make it send data 1 time it works (LED turns on). Any ideas why this could be happening?

https://www.instructables.com/id/Interface-Python-and-Arduino-with-pySerial/

"I can't do it" is not a good problem description. What exactly is your problem in writing the code? What exactly did you try? Please add this information to the question by editing it

When you say it does not work, what do you mean? Exactly what happens? What is in your init () method? Are you setting up Serial? Are you setting the LED for output? Please submit the entire code.

That while loop in the python code is going to send that number over and over really really fast.  I wonder if you shouldn't slow that down just a little.  Put a sleep call in that while loop.

It would be easier if you used Arduino <--> Python compatible libraries to ensure the communication between the two is robust and reliable. An example of such libraries would be pySerialTransfer and SerialTransfer.h.
pySerialTransfer is pip-installable and cross-platform compatible. SerialTransfer.h runs on the Arduino platform and can be installed through the Arduino IDE's Libraries Manager.
Both of these libraries have highly efficient and robust packetizing/parsing algorithms with easy to use APIs.
Example Python Script:
import time
from pySerialTransfer import pySerialTransfer as txfer

if __name__ == '__main__':
    try:
        link = txfer.SerialTransfer('COM17')

        link.open()
        time.sleep(2) # allow some time for the Arduino to completely reset

        while True:
            send_size = 0

            ###################################################################
            # Send a list
            ###################################################################
            list_ = [1, 3]
            list_size = link.tx_obj(list_)
            send_size += list_size

            ###################################################################
            # Send a string
            ###################################################################
            str_ = 'hello'
            str_size = link.tx_obj(str_, send_size) - send_size
            send_size += str_size

            ###################################################################
            # Send a float
            ###################################################################
            float_ = 5.234
            float_size = link.tx_obj(float_, send_size) - send_size
            send_size += float_size

            ###################################################################
            # Transmit all the data to send in a single packet
            ###################################################################
            link.send(send_size)

            ###################################################################
            # Wait for a response and report any errors while receiving packets
            ###################################################################
            while not link.available():
                if link.status < 0:
                    if link.status == -1:
                        print('ERROR: CRC_ERROR')
                    elif link.status == -2:
                        print('ERROR: PAYLOAD_ERROR')
                    elif link.status == -3:
                        print('ERROR: STOP_BYTE_ERROR')

            ###################################################################
            # Parse response list
            ###################################################################
            rec_list_  = link.rx_obj(obj_type=type(list_),
                                     obj_byte_size=list_size,
                                     list_format='i')

            ###################################################################
            # Parse response string
            ###################################################################
            rec_str_   = link.rx_obj(obj_type=type(str_),
                                     obj_byte_size=str_size,
                                     start_pos=list_size)

            ###################################################################
            # Parse response float
            ###################################################################
            rec_float_ = link.rx_obj(obj_type=type(float_),
                                     obj_byte_size=float_size,
                                     start_pos=(list_size + str_size))

            ###################################################################
            # Display the received data
            ###################################################################
            print('SENT: {} {} {}'.format(list_, str_, float_))
            print('RCVD: {} {} {}'.format(rec_list_, rec_str_, rec_float_))
            print(' ')

    except KeyboardInterrupt:
        link.close()

    except:
        import traceback
        traceback.print_exc()

        link.close()

Example Arduino Sketch:
#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  myTransfer.begin(Serial);
}

void loop()
{
  if(myTransfer.available())
  {
    // send all received data back to Python
    for(uint16_t i=0; i < myTransfer.bytesRead; i++)
      myTransfer.txBuff[i] = myTransfer.rxBuff[i];

    myTransfer.sendData(myTransfer.bytesRead);
  }
}

Note that you can send more than just individual chars with these libraries. It is possible to transfer floats, ints, bytes, arrays, and even structs (or any combination of the like) within your program using the libraries! See the examples in SerialTransfer.h for more info
For theory behind robust serial communication, check out the tutorials Serial Input Basics and Serial Input Advanced.


text:
ESP8266 I2C doesn't respond
I've got a huge problem using an ESP8266 from a Wemos D1 mini.
I am using an STM32L073RZ to send a request to an ESP8266 to send me the time it has acquired from a WiFi connection.
ESP code:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <NTPClient.h>
#include <Wire.h>

// Zastąp poniższe wartości danymi Twojej sieci WiFi
const char* ssid = ":>>>>>>>>>>>";
const char* password = "NOPE";

#define Status D4

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);

void setup() {
  pinMode(D4, OUTPUT); // Pin odpowiedzialny za gotowość urządzenia do komunikacji przez I2C
  digitalWrite(D4, LOW); // Ustawiamy go na początku na "0".

  Serial.begin(9600);
  WiFi.begin(ssid, password);

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

  timeClient.begin();

  Wire.begin(8); // Odpala D2 jako SDA i D1 jako SCL jako slave
  Wire.onRequest(sendTime); // Rejestracja funkcji zwrotnej, która zostanie wywołana, gdy urządzenie nadrzędne zażąda danych

  digitalWrite(D4, HIGH); // Tutaj konfiguracja z siecią jak i też konfiguracja z pinami i ustawienie I2C jest zakończone
                          // i sygnalizowane stanem wysokim na D4
}

void loop() {
  timeClient.update();
  Serial.println(timeClient.getFormattedTime());
  delay(1000);
}

void sendTime() {
  String time = timeClient.getFormattedTime();
  Wire.write(time.c_str()); // Wysłanie czasu do urządzenia nadrzędnego będzie to razem 8 bajtów bo jeszcze znaki oddzielające.
}

STM simple code :
xD = HAL_I2C_Master_Receive(&hi2c2, 0x08<<1, czas, 8, 1000);

I tried everything. Adding pull ups, changing the GPIO speeds, etc.
Here is what my logic analyser gave me:

Still nothing. I've also checked which pins are the SDA and SCL which are D2 and D1. I've checked is the connection was correct and it should be, but still no response.
I don't know anymore what is wrong or what is not.
Schematic :

It is already powered so I didn't need to add 5 V and G pins to it, but I also tested with adding G pin to ground of the STM32, and also with 5 V to the 5 V of the STM32, but it still didn't work.

you must have a common ground

I've mentioned in the Edit, that I've connected G with GND of the STM32, didn't work

Is D4 high - to confirm you initialized ok?

Yup D4 is high.

What are the voltage levels? The STM32L073RZ seems to be a 3.3V device, and the ESP8266 also, however you mentioned 5V. I'm no expert on either, but that could be an issue.

Oh I have mentioned that I only connected 5V STM32 to 5V ESP8266 a lot later after so many attempts to connect with I2C. But welp still sitting 5h fixing it.

But welp still sitting 5h fixing it. - I don't understand that.

nothing just saying that it is exhausting. But I've burned now the WiFi connected it  accidently GND from STM32 to 5V ESP8266. But still I don't understand why my I2C didn't work

Are you powering both devices from 3.3V or 5V?

Both of them I power using simple USB port. Which is as I know 5V and is lowered to 3.3V.

From this: https://github.com/esp8266/Arduino/issues/5762 it appears that the esp8266 is not a good I2C slave device.

Hmmmm interesting. I thought it was an old post so maybe they've fixed it.
I saw some tutorials that they have used the I2C on ESP8266 so I thought maybe it works.

@Jakob2001 The esp8266 works as a master and, if you are lucky, works as a slave but only with another esp8266 as master. You could try reversing the roles. The esp8266 as master sending a time stamp occasionally to your STM device as an I2C slave.

I2C slave doesn't work on esp8266 because it doesn't have hardware support for I2C.
From the esp8266 Wire library documentation:

Wire library currently supports master mode ...

https://arduino-esp8266.readthedocs.io/en/3.1.2/libraries.html#i2c-wire-library

Even though the wire library has this "onRequest" the ESP8266 cannot use it ?

the code for slave is there. it just doesn't work.

The devices must share a common ground, and also you may need 4.7k pull-up resistors on both SDA and SCL.
See http://gammon.com.au/i2c for a whole lot more detail.

I've mentioned in the post that I've added pull ups in STM32 using software and in the edit I've mentioned I have connected G pin with GND pin of the STM32, still didn't work.

I was looking at your circuit diagram. You can't expect to post incorrect information and get a good answer.

Okey, my bad. But still the solution to add pull ups didn't work as well as connecting G pin to GND pin of stm32.

Both other answers are correct, but there is yet another problem with your design.
As can be clearly seen from the logic analyzer output, the master runs its clock at 100kb/sec (the standard i2c rate). That leaves the slave ca. 5us to react. For a 80 MHz chip this might be quite a tight timing by itself and requires thorough inspection and optimization of code. But a UDP request into the big net? Seriously?!
The only way it might work is if both parties could agree on a clock stretching. However, the i2c spec never defines precise timings for the stretched clock, so, the chances are, any master would probably break the session assuming the slave hung up long before the UDP request could be served.
Therefore, such requests need to be split into two parts. First, the master asks the slave to initiate the process of measurement/exchange/computation/whatever. And second, after an appropriate delay, the master issues another request for the buffered result from slave.

I am not that good at speeds etc. So 80 MHz and 100kb/s doesn't say a lot to me if context of if it makes in time etc.
I just wanted to get time, so I checked some tutorials how to do it. I've checked the I2C frequency speed and it was 100 kHz.
Let's say I don't know how to imagine yet these speeds and timings because 5 us itself is so small for me. Sorry for my incompetence. Although I would like to learn something how to judge whether the clock is enough or not, or it must be always the same or it can be a bit different.

@Jackob2001 The timings are written on the chart. 100khz is the smallest i2c speed by spec and by h/w implementations. 100000 cycles per second gives 10/1000000 sec per whole cycle and 5/1000000 for one half of it (when clock is low). Pretty trivial.

Sorry for pinging. h/w ? 10/100000 ? I just wondered how timing works here though because as you said there are two now. One is with 100kHz and the other one is with 80Mhz. Shouldn't the timing be the same for them to work ? If one of the clock is faster than the other then after one cycle the same bit can change mamy time ??? I don't know. Just saying after reading your comment about timing I want to learn more though

@Jackob2001 10/1000000 = 1/100000. Divide by two and get 5/1000000. If mcu runs at 80 mhz then it has ca. 400 internal clocks per 5 us (1/2 of i2c clock). This is at most 400 machine instructions even for RISC arch.

@Jackob2001 You probably need to start with master mode. Don't use libraries but implement it in software. This is pretty easy as master runs the scl clock the way it wants. Then you'll understand how i2c works completely.

I still don't quite get the calculations. Maybe this is not the best topic, but with timing things I don't quite get what you've tried to say. And implement it in software ? Hmmm I am quite new just happened to learn some stuff so I don't know how to get to it. WiFi code was made from yt videos :D


text:
Can't print out a field with ArduinoJSON
I'm trying to create a command interpreter. Allowed commands are stored in a JSON document inside SPIFFS. If I send an allowed command, it doesn't print the field associated with that value (end of receiveMsg function), can someone help me to figure out what the problem is? Here's the full code.
EDIT: added minimal code
EDIT 2: solved, but not entirely. I fixed readFile function, but I cannot print out the first field, it appears to be empty. Json is { "ssid"="aaa", "password":"bbb"}, password is printed out, but not ssid. Changing position, password is empty, ssid is printed out. I can resolve by adding a first empty field, but why it happens?

#include<ESP8266WiFi.h>
#include<ArduinoJson.h>
#include<stdio.h>
#include<string.h>
#include "FS.h"

DynamicJsonDocument* functions;

DynamicJsonDocument* readFile(String filename) {
  File file = SPIFFS.open(filename, "r");
  if (!file) {
    Serial.println("Failed to open the file");
  }
  size_t size = file.size();
  if (size > 1024) {
    Serial.println("File size is too large");
  }
  std::unique_ptr<char[]> buf(new char[size]);
  file.readBytes(buf.get(), size);
  DynamicJsonDocument* jsonBuffer = new DynamicJsonDocument(200);
  DeserializationError error = deserializeJson(*jsonBuffer, buf.get());
  if (error) {
    Serial.println("Failed to parse file");
  }
  return jsonBuffer;
}

int connection() {
  DynamicJsonDocument *settings = readFile("/wifiSettings.json");
  const char* ssid = (*settings)["ssid"];
  Serial.println("Printing ssid");
  Serial.println(ssid);
  const char* psw = (*settings)["password"];
  Serial.println("Printing password");
  Serial.println(psw);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, psw); //Connect to wifi
  Serial.println("Connecting to Wifi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
  return WiFi.status();
}

void setup() {
  Serial.begin(115200);
  if (!SPIFFS.begin()) {
    Serial.println("Failed to mount file system");
    return;
  }
  if (connection() != WL_CONNECTED)
    Serial.println("Not connected");
  else
    Serial.println("Connected");
}

Could it be that you're losing all your data as you pass objects around copying them like that? A better strategy would be to have a single document as a global object, and load the data into that once at start up (after all, it's not going to change, is it?)

add the output from Serial Monitor to the question? do you sent the command from Serial Monitor? contains the  command a space? Is the command from Serial Monitor terminated with new line characters?

I tried modifying readFile function by returning a DynamicJsonDocument pointer, but the problem still remains. The output from serial monitor is empty, even If I put a fixed key like "test" (where "test":"test")

so this is not a minimal sketch to reproduce the problem?

Not properly, I changed it to minimal

Solved. I was using static allocation instead of dynamic. I'll upload the fix soon


text:
Can we burn Arduino bootloader into any microcontroller chip?
I am new to this Arduino community
I noticed on youtube that while the prototype is complete people purchase new ATmega328p chips and flash bootloaders into them using in-system-programmers so that the chip could actually understand and interpret the instructions that are written in the high-level language if I am right(No I was wrong, it's actually the compiler that sits on Arduino). so I thought what if we could burn the atmega328p bootloader into any other microcontroller. So that we could program it in Arduino programming language(C/C++). Is this possible? sorry if I am dumb, but I wanted to know. And can anyone tell me whether could we use ATmega328p for production purposes(consumer electronics)? Thanks in advance.

the purpose of the bootloader is to make upload of the code over UART possible. nothing else. the use of higher language possibility is provided by compiler

thanks @Juraj that really makes some sense

The compiler itself is not loaded on or run by the microcontroller. For compiled languages, like C, the compiler produces machine code that the microcontroller can run by itself. You're probably thinking of interpreted languages, like Python, that do require an interpreter to exist on whatever hardware is used to run the code.

You do realize it's quite simple to program an ATmega328p in C and other languages without Arduino, right? It's part of the megaAVR family and can be reached with the Atmel Studio.

The answer needs to have multiple parts:
Yes, in principle you can create a bootloader for any microcontroller, which acts like the Arduino's.
Please be aware that there are different bootloaders, not just the common STK500 compatible one. Each of these bootloaders implements a certain protocol to transfer the binary code to the target system.
Additionally, some protocols also include commands to restart the microcontroller, to set configuration registers, and maybe more.
You need to read the bootloader's documentation to become familiar with its capabilities.
But it is your decision whether such a bootloader on a non-AVR system or an non-Arduino-AVR system is good for you.
No, the bootloader does not enable the microcontroller to "understand" the high-level language.
The standard Arduino IDE uses the specific compiler for the target microcontroller to translate the C++ source code to machine language. The resulting binary commonly runs on this target microcontroller only.
The bootloader just implements the protocol. In general, it is completely unaware of the meaning of the transferred data.
Microcontrollers in general use different processors with possibly different machine languages, contain different kinds of memory of different sizes, include different sets of different peripherals. But you know this for sure. You need to write and compile your source code for the specific part you're targeting.
Yes, you can use ATmega328P for a consumer product, as Michel already said.
You need to take the common measures that you take with any part of your product, though.

Thank you so Much @the busybee . Now I completely understand about bootloaders and what actually they are meant for .  Your answer is ultimate ...

Upvoted your (better/detailed) answer. I was assuming (and still do) that he meant to upload an AtMega328 bootloader into any other MCU. You can (as you say) create a bootloader for any MCU acting like an Arduino, but those will be different kind of boatloaders per MCU (type).

Thanks a lot! Please keep your answer because of its details about selecting an MCU for production purposes. -- Your assumption about the OP might be right. ;-) But who knows who else comes around because of the question's title.

You cannot just load a sketch into any microcontroller, because every microcontroller has different memory layout, peripherals, ways of uploading, FLASH size etc.
You can use the atMega (or any microcontroller) for production purposes though. Of course each MCU type has operation conditions (like min/max temperature), so in e.g. automotive or military environments not all MCUs are allowed to be used, but for consumer electronics, afaik all MCUs can be used (meaning they will pass by themselves the needed certifications, which may not be true for components added and the circuit/enclosure resulting out of it).

Note: It's not Atmel who will stop you using all MCUs for all applications, it's your customers who will stop you. And for a consumer product, possibly the laws about what customers should be able to expect (so basically your customers).

@user253751 Thanks for this addition.


text:
Uploading Firmware to Atmega1284p using ESP8266 with AVRISP as programmer
I am trying to flash a new Firmware to my Ender 3 Pro.
I am using the ESP8266 as an ISP via AVRISP over Wifi.
I have a 10mF capacitor between the ground and reset of the ESP8266
I followed this thread: ESP8266 as ISP program for ATMega16
When uploading I get the following output on console:
C:\Users\Chry>"I:\3dPrints\Firmware Pack Source Folder\Windows Arduino\hardware\tools\avr/bin/avrdude" -C "I:\3dPrints\Firmware Pack Source Folder\Windows Arduino\hardware\tools\avr/etc/avrdude.conf"
-v -V -p atmega1284p -c arduino -P net:192.168.178.59:328 -b 115200 -D -U flash:w:C:\Users\Chry\AppData\Local\Temp\arduino_build_166520/TH3DUF_R2.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 "I:\3dPrints\Firmware Pack Source Folder\Windows Arduino\hardware\tools\avr/etc/avrdude.conf"

         Using Port                    : net:192.168.178.59:328
         Using Programmer              : arduino
         Overriding Baud Rate          : 115200
avrdude: ser_drain(): read error: Falscher Parameter.

avrdude: ser_drain(): read error: Falscher Parameter.

avrdude: ser_drain(): read error: Falscher Parameter.

         AVR Part                      : ATmega1284P
         Chip Erase delay              : 55000 us
         PAGEL                         : PD7
         BS2                           : PA0
         RESET disposition             : dedicated
         RETRY pulse                   : SCK
         serial program mode           : yes
         parallel program mode         : yes
         Timeout                       : 200
         StabDelay                     : 100
         CmdexeDelay                   : 25
         SyncLoops                     : 32
         ByteDelay                     : 0
         PollIndex                     : 3
         PollValue                     : 0x53
         Memory Detail                 :

                                  Block Poll               Page                       Polled
           Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
           ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
           eeprom        65    10   128    0 no       4096    8      0  9000  9000 0xff 0xff
           flash         65    10   256    0 yes    131072  256    512  4500  4500 0xff 0xff
           lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
           signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
           calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00

         Programmer Type : Arduino
         Description     : Arduino

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x14

avrdude: stk500_getparm(): (a) protocol error, expect=0x14, resp=0x10
         Hardware Version: 4744608
         Firmware Version: 0.2
         Topcard         : STK502
         Vtarget         : 1.8 V
         Varef           : 0.0 V
         Oscillator      : Off
         SCK period      : 0.1 us

avrdude: stk500_initialize(): (b) protocol error, expect=0x10, resp=0x01
avrdude: initialization failed, rc=-1
         Double check connections and try again, or use -F to override
         this check.

avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x10

avrdude done.  Thank you.

I can't seem to get it to work. Does anyone have any ideas?
I tried programming it directly:
I use the standard Arduino ISP sketch on my ESP8266 and try to upload that way. Directly connected the ESP8266 to my computer. I get sync-problems now: avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x61
The Board in the arduino IDE is set to Sanguino 1284p and the programmer is set to Arduino as ISP.

I have a 10mF capacitor between the ground and reset of the ESP8266. I'll edit that info in the question as well.

found this ... https://github.com/arduino/Arduino/issues/730

That goes beyond my understanding. I changed plans though. I use the standard Arduino ISP sketch on my ESP8266 and try to upload that way. Directly connected the ESP8266 to my computer. I get sync-problems now: avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x61

you are not alone https://github.com/esp8266/Arduino/issues/6517#issuecomment-531480035 I will try it today. I tested it in Jan 2018 and it worked then

https://github.com/esp8266/Arduino/issues/6519#issuecomment-531551733

10milliFarad, or 10microFarad?  0.1microFarad is generally used when you are trying to create a Reset pulse for serial downloads. For programming via the SPI pins - SCK, MOSI, MISO - Reset is controlled directly.

I assume that you have to wrap the directory in the option -U flash:w:C:\Users\Chry\AppData\Local\Temp\arduino_build_166520/TH3DUF_R2.ino.hex:i with "s. I don't promise that it'll work with that change, but C:\Users... will definitely confuse the parser due to the :!


text:
Windows driver installer not detecting arduino
I'm trying to program my Arduino Uno with my Windows PC. I followed all the instructions on the site. I mistakenly downloaded the .zip file and didn't unzip it, before plugging in my Arduino Uno. So naturally, no message came up. I then followed the correct procedure, but Windows driver installer does not detect the Arduino Uno. What can I do to fix this?

Is this a genuine Arduino or a clone? Also, why not just try deleting the zip and downloading and running the installer instead?

@JakeC genuine Arduino. I'm a newbie so you're going to have to take it slow with me.

Being that you are a newbie, I highly recommend just downloading the installer and running that. While the zip does contain the drivers, it is pretty hard to install them unless you are already familiar with manually installing drivers on Windows.

@JakeC can you direct me to where I can find the installer? I'm using a Windows machine.

https://www.arduino.cc/en/Main/Software where it says "Windows Installer"

@JakeC I got it working. Thanks, your advice saved a noob llike me a lot of wasted hours.

Please feel free to answer your own question and mark it as accepted (you might have to wait a bit for this depending on reputation) especially if there was something particular about your setup that you think might help future users.

@JakeC - alternatively convert your comment into an answer as it appears to have worked. :)

Per my comment above, the drivers are not installed when using the Arduino editor from an extracted zip file. If you are feeling adventurous, they are located in the /drivers folder and you can install them manually, there are plenty of instructions elsewhere on the internet on how to do that.
My recommendation would be to just download and run the installer version of Arduino, as that will take care of registering the drivers for you. The installer can be found on the download page indicated with the text "Windows Installer".

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