text:
Storing and sequencing output value (Arduino)
I am new to Arduino programming, after days and nights trying to use array and for loop, and googling a lot of articles, I am still unable to find how to store each weighing output value from int Sampling() to be executed by the respective servo in sequence order.
If you have any clue to share and help me, I'll be very happy.
Below is my base code:
#include <HX711.h>
///////////////////////////////////////////////////////////////////////
#define calibration_factor -251
#define LOADCELL_DOUT_PIN 7   // data
#define LOADCELL_SCK_PIN 8    // sck
////////////////////////////////////////////////////////////////////////
HX711 scale;
////////////////////////////////////////////////////////////////////////
int servo1 = 12;
int servo2 = 13;
int proxiPin1 = 2;
int proxiPin2 = 3;
////////////////////////////////////////////////////////////////////////
int toggleState = 0;
int proxiState1 = 1;
int proxiState2 = 1;
////////////////////////////////////////////////////////////////////////
int weight;
int weightFinal;
////////////////////////////////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);
  scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
  scale.set_scale(calibration_factor);
  scale.tare();

  pinMode(servo1, OUTPUT); // simulating servo1
  pinMode(servo2, OUTPUT); // simulating servo2
  pinMode(proxiPin1, INPUT_PULLUP); // proximity
  pinMode(proxiPin2, INPUT_PULLUP); // proximity

}
/////////////////////////////////////////////////////////////////////////
void loop()
{
  Serial.print(Sampling());
  Serial.print(" gram");
  Serial.println();
  ///////////////////////////////////////////////////////////////////////
  if ( weightFinal == 10 )
  {
    toggleState = true;
    servo10gr();
  }

  if ( weightFinal == 20 )
  {
    toggleState = true;
    servo20gr();
  }
}
////////////////////////////////////////////////////////////////////////
int Sampling()
{
  int weight = scale.get_units();

  if (weight >= 10  && weight< 20)
  {
    weightFinal = 10;
  }

  else if (weight >= 20  && weight < 30)
  {
    weightFinal = 20;
  }

  return weight;
}
/////////////////////////////////////////////////////////////////////////
int servo10gr()
{
  proxiState1 = digitalRead(proxiPin1);
  if ( proxiState1 == 0 && toggleState == true )
  {
    digitalWrite(servo1, HIGH);  //Simulating servo signal Pin//
    delay(500);
    digitalWrite(servo1, LOW);

    toggleState = false;
    weightFinal=0;
  }
}
/////////////////////////////////////////////////////////////////////////
int servo20gr()
{
  proxiState2 = digitalRead(proxiPin2);
  if ( proxiState2 == 0 && toggleState == true )
  {
    digitalWrite(servo2, HIGH);    //Simulating servo signal Pin//
    delay(500);
    digitalWrite(servo2, LOW);

    toggleState = false;
    weightFinal=0;
  }
}

What do you need weight for? The servo functions don't use it. And what do you mean by each weighing output [...] in sequence order? You mean to store it in an array? Please describe what you want to achieve.

I am simulating conveyor. So first the scale weigh each object value and then the object send through a conveyor until the object separated by the servo depend on the object weight. I am using proximity switch to trigger the servo. In the code above,I am using LED to simulating servos to make the code shorter. If I am only using the code above, i cant weigh the new object before the previous object executed by the servo. If I do so, only the latest weight will be execute, so the previous object that is already on the conveyor will be executed by the wrong servo. Thank you

The speed of your loop depends on whether delay(500) is executed or not, inside your servo functions. I guess that's hard to control properly.

I am using LED to simulating servo() function on the above code that's why i am using delay(). In reality, I am using servo. My main problem is how to store value for each object weight to be executed later by the designated servo. Some people suggest me to use array. But after a week, I cant figure it out how to integrate the  button/ proximity switch with "for loop" .

It seems like you need to learn what arrays are and how to use them (explaining them on SE would go a bit too far). It's important to keep in mind that a typical loop() is executed thousands of times per second. There are some basic concepts (like BlinkWithoutDelay and finite state machines), that make your life easier.

Thank you for your suggestion @Sim Son. Yeah, I need to learn much much more about how to implementing structures to the program.

I'm still not entirely sure what you want to achieve, but maybe this will help:
You have a global variable int weight, and in int Sampling() you create another int weight = scale.get_units() which you give a value.
That second variable is only accessible inside of Sampling(). If you want to use it elsewhere for storing or in other functions, change:
int weight = scale.get_units();
to
weight = scale.get_units();
and you can then use weight wherever you like in your code, also in servo10gr() and servo20gr().
You don't need to store a sequence of weights to drive the servos; you can just use the current weight immediately to drive a servo and then get a new weight.
If, however, you want or need to keep a list of weights for some reason, there's a bit more work to be done.
There are better ways of going about this, but let's see first if this solves your problem.

First of all, i would like to say thank you for your kindness. I'll try to describe in another way. What i want to do is if my output value of each object (from the scale) was let say: 10gr>10gr>20gr>20gr>20gr>20gr>10gr> and so on, I want those each object(depend on it weight) is assign to the servo based on it designation servo, in this case servo10gr() or servo20gr(). Should I use array or another method to store those value so that those servo assignment will be executed sequencially  by the servos?. Ok I'll try different method by using  weight inside servo10gr() and servo20gr.

@FlipFlop as I understand your requirement, this answer will not solve your problem. What you need are arrays, because you want to store "a bunch" of values. What ocrdu explained is relevant, though. As arrays can't be passed as function arguments, you'll need to make them global.

Thank you Sim son for your willingness to give me suggestions.


text:
Digital Pot with Arduino
I am a newbie in electronics. Please correct me if I am wrong.
I am replacing a pot with a digital pot (DS3502) in a circuit.
The Vcc of the circuit is 12V. But the digital pot can have a maximum of 5.5V as Vcc.
I am controlling the digital pot with an Arduino UNO. Can I use 5V from the Arduino as the Vcc of the digital pot and 12V as the Vcc of the circuit?
I kept the ground common for both.
The connection is as below:
DS3502 Arduino Uno
VCC --- 5V
GND --- GND
SDA --- A4
SCL --- A5
DS3502 Circuit
RL --- GND
RW --- Circuit

This is a constant current circuit of 21mA, to drive a laser. But I want to slightly tune the intensity of laser using the digital pot. So I am replacing it with digital pot. But I am getting an open connection in the place of resistor. I have only use RL and RW to circuit. RH is kept opened. Do I need to connect RH and V bias to 12V(Vcc of my constant current circuit)? I don't have much knowledge in circuits. Please spare me if I am wrong

it depends on the circuit that the digital pot is part of ... a question about incorporating a digital pot into an existing circuit is not related to the Arduino ... it belongs at https://electronics.stackexchange.com/questions

In addition to jsotola's comment, the data sheet of the digital pot will give you the answer, once you know what the operating conditions are, which depend on the specific circuit.

I don't know why you guys closed this question. It's about connecting a digital pot to an Arduino. Would you prefer questions about connecting nothing to an Arduino?

(Regarding the edit to the question) See my answer. You would need to connect +12V (on the right of your circuit) to V+ and RH. RW is just the wiper. It needs a voltage input somewhere.

@thebusybee Comments are for clarifying the question. Not to tell people to read the datasheet. If that's all you have to say, say nothing.

I'm not sure your circuit diagram makes sense. You have a pot symbol with nothing connected to the wiper.

Assume for the moment you are using a physical pot. They have three terminals, not two, because they are a voltage divider. So, your circuit should show three connections to the pot. See Potentiometer - Wikipedia.

@NickGammon Since this question is supposed to be asked on SE/EE, I refrained to write an answer and gave a constructive hint how to proceed, even to avoid to post a question at all. The question is clearly off-topic. I would be glad if such questions would not receive positive feedback by an answer.

@thebusybee They spot the word Arduino and migrate it to here. So it is a lose-lose situation.

@NickGammon Oh, dear. Reading skills are apparently being lost. Help vampires are sucking my blood.

your diagram shows a variable resistor, not a potentiometer ... how is the original circuit connected?

If you look at the datasheet it mentions that Vcc can be from 2.5V to 5.5V, and clearly the I2C connection is referenced to Gnd. Therefore you would connect the Uno to the DS3502 in the usual way (Gnd, Vcc, SDA and SCL).
The "digital pot" side has a separate input (V+) which can be from 4.5V to 15.5V.

Can I use 5V from the Arduino as the Vcc of the digital pot and 12V as the Vcc of the circuit?

Your terminology is a bit loose here. You can use 5V from the Arduino to the Vcc pin of the pot (pin 3) and 12V to V+ and RH (pins 6 and 9). The output will be on RW (the wiper, pin 7).
It also looks like you would connect Gnd and RL (pins 2 and 8) to Gnd on the Arduino.
Although, conceivably I think, you could connect Gnd (pin 2) to Gnd on the Arduino, and RL (pin 8) to the Gnd of the "other circuit" - the one you are controlling. It looks like they are separate.
I think you might keep RL and Gnd not connected, to reduce digital noise.
The A0 and A1 pins are for modifying the I2C address.

Thank you for your answer. I have updated my circuit diagram. I am getting an open connection in place of pot.
I have not connected RH and V bias now. Is it because of that? I don't have much knowledge in circuits. Please spare me if I am wrong

Also A0 and A1 needs to be connected to Arduino to which pins of Arduino as I already connect the SDA and SCL of pot to A4 and A5 (I2C) of Arduino

Just connect A0 and A1 to Gnd.  They modify the I2C address, if zero (Gnd) it is the published address. The slave address is 1010xx where xx are A1 and A0. So if they are grounded the address will be 101000 in binary (40 in decimal).

What is V bias, that you refer to?

V+ of the digital pot is what I meant. Thanks a lot for your support. I am a beginner and I wasn't sure about the connections even. Thanks again for all the explanations.

@Teena If my answer has helped please tick the "Accept" arrow to indicate to other people that the answer has been accepted by you, and was helpful.

source: Stack Exchange

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

sort: votes


text:
Arduino Uno vs Arduino MKR1000 analogRead discrepancies
I'm using an Arduino to control a BLDC motor connected with the motor driver. It is just a simple control which I'm using a PWM as a signal. Before this, I'm used Arduino Uno pin 5 to control BLDC motor, the analogue value starts from 80. Now, I'm changed to Arduino MKR1000 board with the same pin 5 to control BLDC motor. But, for MKR1000 to rotate the motor, analogue value start from 125. My question is, why two of this board using a different PWM value for rotating the BLDC motor.

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


text:
Using a 3V latching relay to power up ESP8266
I'm trying to use a 2-Coil Latching Relay like TXS2SA-L2-3V for  powering up a ESP8266. My idea is to activate the relay by setting the first coil to high and deactivate the coil by setting the second coil to high. In my circuit i will set the second coil to high at the end of the code by the esp8266. I need the latching (holding the power) function of it. Because when somebody activtes the Deep Sleep function to early, I have no electricity to power the esp8266.
My question is:
What kind of circuit I must use? I have no idea where I can start.
I have a regulator that can be enabled via de EN signal.
Thanks in advance!

I've read your question twice, but it's still unclear to me what your actual question is.

My idea is to activate the relay by setting the first coil to high...? How?

deactivate the coil by setting the second coil to high. ...? How?

You control a latching relay of this sort in the exact same way as a normal relay. What is your problem?

You use a latching relay of this form in the exact same way as a normal relay - it's just there's two of them.
One coil you want to control with a button (power on) and the other with a transistor (and possibly an "off" button as well).

simulate this circuit – Schematic created using CircuitLab
Press ON to latch the relay into the ON position (NO -> COM). Activate M1 or press OFF to latch the relay into the OFF position (NC -> COM).

Excellent! Thank you for your help. What kind of transistor can I use? Both ESP8266 and the relay work with 3V3. Thanks in advance.

If use an n MOSFET with a VGS below 2v.

I have great luck with the IRLZ44N on 8266s; cheap w/low rds+vgsth


text:
What pins to use on a Teensy to get data from multiple peripherals?
I'm using a Teensy to keep records on the location, speed, altitude, and direction of a weather balloon I'm hoping to launch. I have an Adafruit LSM9DS1 and a Ublox NEO-M8N with compass (HMC5833L) so to get all the data from these I need to connect to a total of 6 pins to get the data. I also want to use a Pixhawk radio telemetry unit to send these data to the ground so I can see them in realtime, so that will involve at least 2 more pins I believe.
The Teensy appears to have plenty of IO pins for all of this, but I've noticed that in all the libraries I've installed to try to use with these things, the pins to use aren't explicitly set. The libraries I've played with include the Adafruit LSM9DS1 library, NeoGPS, Pixhawk Arduino link, RadioHead, Grove HMC5833L, and others. I've been able to get some serial data in by using pins 18 and 19, but I can't attach all the periperhals to the same pin.
It feels like I'm missing something very basic here but I haven't been able to figure out how to use these libraries with inputs on different pins. Even when I look into the code of the libraries themselves, I can't find where the pins are being set. Most of the documentation that mentions which pins things use is written for specific Arduino models, like the Uno, and don't mention the Teensy.
What pins do I use if I want to read and write on more than one peripheral from my Teensy? How can I get data on more than just the two "default pins" that these libraries seem to expect?

You need to look at each device/library, there is no standard for changing default pins. You might not even need to change them for e.g. I2C where several peripherals can be on the same bus if no address conflict.

The first thing to look at when determining which pins to connect a peripheral to is what protocol that peripheral uses - e.g. I2C, SPI, analog voltage via ADC, etc. The Teensy pinout for the version you have (e.g. the 3.2 pinout) lists which pins can function as which protocol functions. For example, pin 19 can act as an analog input (A5) or as part of the 0th I2C unit, SCL0. Your LSM9DS1 can use I2C, so you could connect it to that I2C unit. Typically Arduino libraries will default to using the default peripheral type. In Arduino, an I2C bus is called Wire, so a library for an I2C device will typically use the Wire device. Well-written libraries will also let you pass in your own peripheral, which is how you change the pins. Each library will do this differently.


text:
bh1750 lightsesor won't work
ok, im having problems with my bh1750, here is all info i got:
board: esp32s nodeMCU v. 1.1
Pins:

Wiring: (the 2 reds go to pin 21 and 22)

code:
#include <BH1750.h>
#include <Wire.h>

BH1750 lightMeter;

void setup(){

Wire.begin();
Serial.begin(115200);
lightMeter.begin();
if (lightMeter.begin()) {
Serial.println(F("BH1750 initialised"));
}
else {
Serial.println(F("Error initialising BH1750"));
}
}

void loop() {
uint16_t lux = lightMeter.readLightLevel();
Serial.println(lux);
delay(500);
}

Sorry for bad formating
Serial output:
13:01:41.926 -> [BH1750] ERROR: received NACK on transmit of address
13:01:41.926 -> [BH1750] ERROR: received NACK on transmit of address
13:01:41.926 -> Error initialising BH1750
13:01:41.926 -> [BH1750] Device is not configured!
13:01:41.926 -> 65534
13:01:42.430 -> [BH1750] Device is not configured!
13:01:42.430 -> 65534
13:01:42.932 -> [BH1750] Device is not configured!
13:01:42.932 -> 65534
and that goes on forever
Hope someone got an answer :D

hrello still needs help

The SCL and SDA silkscreen was reversed on my chips.
Took an hour of faffing to figure that out.
Never "Just presume" it is correct

Your code looks good. I2C configuration is default which depends on your board manager.
Then your wiring may be wrong.

Using a multimeter to check supply voltage on the BH1750 module. It should be 3.3V
Using a multimeter to check the connection between the BH1750 module with ESP32.
Difference ESP32 vendor may provide a difference I2C pinout. Make sure you connect everything correctly.
Using an oscilloscope or logic analyzer to capture data on an I2C bus.
If everything good, try to use another module.

From your log, I guessed, the power supply is good. I2C connection is your problem.
More, you should use the different color wire for the difference signal. It helps prevent unexpected connections.


text:
GPS led not blinking and wrong LAT Long values
I want to extract the latitude and longitude values of my location but my gps led is not blinking. Also result appearing on the serial monitor is wrong.
This is my Arduino code:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

SoftwareSerial gpsSerial(3, 4);
TinyGPSPlus gps;
float latitude,longitude;
void setup() {
  // put your setup code here, to run once:
  gpsSerial.begin(9600);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
while(gpsSerial.available())
  {
    int data=gpsSerial.read();
    if(gps.encode(data))
       {
          latitude = (gps.location.lat());
          longitude = (gps.location.lng());
          Serial.print("Latitude");
          Serial.println(latitude);
          Serial.print("Longitude ");
          Serial.println(longitude);
       }
   }
}

Please tell me what is wrong in the code?

The first thing you are doing wrong is not indenting your code. That makes anything else that's wrong with your code all but impossible to figure out.

Sounds like you're not getting a lock on the satellites. You do know that it can take a LONG time to get your first lock, don't you? And also that GPS doesn't work well indoors - unless you have a high gain antenna, or lots of open windows around you.

if you are going to say something like my gps led is not blinking, then you also need to explain what that means

at a guess, if the GPS led should be blinking but it isn't, then the second problem of wrong position is irrelevant, since, if GPS isn't working, how do you expect correct GPS data

There could be multiple problems here. Firstly, try doing near an open Window. GPS signals need LOS. Then, check your connections. If these are good, then what is the variable type you have initialized for Lat and Long? Are they long or long double? Start over from an example like this


text:
How to connect MPU9250 with NodeMCU using SPI or I2C Slave?
I want to connect 3 MPU9250 sensors, but since there is just one I2C bus, so there are another 2 sensors I want to connect through SPI.
Library used - https://github.com/bolderflight/MPU9250/blob/master/examples/Basic_SPI/Basic_SPI.ino
There is an SPI example code written, but I don't know about the connections. There are no MISO and other pins on the sensor which i use but its SPI compatible. How do I connect 2 MPU9250 to NodeMCU with SPI?
If SPI connection is not possible then please post about I2C slave connection.

The MPU-9250 I2C address will be 0x68 if the AD0 pin is grounded or 0x69 if the AD0 pin is pulled high. So there's 2. The third one would be more complex, though you could use 2 i2c and 1 spi. You can also just use a 2nd pair of pins to run an additional i2c bus to the 3rd sensor, instantiae another Wire instance (passing the pins numbers to it) and feeding that wire instance to the MPU9250FIFO  constructor.

if you are working on a sensor your should have read its datasheet first rather going for some arduino library instead.

If you want to use SPI-
The homepage of the library you mentioned, clearly explains the circuit connections.-
The MPU-9250 pins should be connected as:

VDD: this should be a 2.4V to 3.6V power source.
GND: ground.
VDDI: digital I/O supply voltage. This should be between 1.71V and
VDD.
FSYNC: not used, should be grounded.
INT: (optional) used for the interrupt output setup in
enableDataReadyInterrupt and enableWakeOnMotion. Connect to
interruptable pin on microcontroller.
SDA / SDI: connect to MOSI.
SCL / SCLK: connect to SCK.
AD0 / SDO: connect to MISO.
nCS: connect to chip select pin. Pin 10 was used in the code snippets
in this document  and the included examples, but any digital I/O pin
can be used.
AUXDA: not used.
AUXCL: not used.

Each sensor's nCS (chip select pin) needs to be connected to a slave select pin (any digital pin) on the NodeMCU. This allows the NodeMCU toselect which sensor it wants to talk to.
Another easy way of connecting multiple sensors with the same I2C address is by using an I2C multiplexer like the Adafruit TCA9548A

This would allow you to connect up to 8 sensors having the same I2C address. Here's a youtube video explaining how to do so.
However, if you just want connect two MPU9250s, you dont need to do any of this, as the board offers two unique addresses via the AD0 pin-

0x68 if AD0 is grounded
0x69 if AD0 is pulled high

The MPU-9250 pins should be connected as:
--Vcc: this should be a 2.4V to 3.6V power source.
--GND: ground.
--FSYNC: not used, should be grounded.
--SDA / SDI: connect to MOSI.
--SCL / SCLK: connect to SCK.
--AD0 / SDO: connect to MISO.
--nCS: connect to chip select pin (Any digital pin but in your example is PIN 10).
Also, you can check the connection from:
https://learn.sparkfun.com/tutorials/mpu-9250-hookup-guide?_ga=1.139382715.926858641.1470020364

To connect multiple SPI components, you only need 4 pins on each 'slave' (thus sensors): SLCK, MOSI, MISO and SS (Slave Select).
The Slave select pin depends to which the master (NodeMCU in your case) is 'talking too'. So on your NodeMCU you will have 3 SS pins (one for each slave sensor). The NodeMCU should talk exactly to one slave device at the same time by setting that SS pin LOW (while the other SS pins are high).
See for the full article: Multiple-SPI-devices-to-an-arduino-microcontroller.

I uploaded the sensor image, which pin is SCLK, MOSI, MISO & SS in this case?

Those are I2C slaves, SPI is a completely different protocol.

Can you post the answer about connect 3 mpu9250 sensor with i2c slave? Thanks so far

I don't have much experience with I2C, I think the SDA and SCL are default I2C connection/pins, so use those.


text:
line following IR sensor not giving readings at 3m wire length?
I am using line following IR sensor with arduino mega. I need the sensor 2-3m away from arduino since the length of rover is 2m (sensor front & motor back). However, I cannot get accurate analog reading due to voltage drop so that is giving me a problem.
What I tried:-
1) I tried to supply 5.4V to the sensor but had no effect and it might damage the sensor so avoided it.
2) tried to keep the controller close to Arduino and let the wire between controller and BLDC motor be long but didnt work
More info about the project:-
-> Using 2 BLDC motor at the back and caster wheels in front with sensor
-> car length is 2m
What could be the best way to solve this problem?
Note:- if the short wire is the only way then is keeping the motor in front with sensor and caster wheels at back a good idea?

I would use Nano or Mini at sensors location and communicate with the Mega over RS485 or CAN.

I do not think that the voltage drop is a big problem. As the Arduino's Analog Pins have a very high resistance there is very low current on the signal wire. So the drop is minimal using normal wire diameters. It also seems that there is a  OpAmp on the sensor board and a potentiometer where you can regulate the voltage. You can make reference measurements with the mega for white and black obstacles.  Why do you think there are voltage drops, and are they so big that you can not decide between black and white anymore?

yes, when I take sensor reading closer (30cm) to arduino then it works perfectly but at 3m length there is negligible detection. I am not sure about voltage drop since volatge was almost same when Imeasured in both cases. Plus I am using wires of jumper wire thickness.

Those sensors are digital, not analog, as far as I know. The potentiometer on the sensor sets the amount of reflectivity (of the surface) needed to set its output HIGH (or LOW).

It has both digital and analog options in my sensor. Sorry I put wrong sensor in the above link which I updated just now.


text:
How do I convert Arduino to an ATmega328P-based project?
I have an Arduino board where I am using some of the peripherals like LCD with I2C.
Now I want to convert this Arduino-based circuit to an atmega328p based circuit, i.e. atmega328p with LCD and I2C.
Here is my actual question: Can I use the same sketch (binary) that I have compiled and uploaded for the Arduino board for the atmega328p and does it work? Or do I need to write atmega328p based C++ code?

A compiled sketch will run just fine on a bare ATmega328p, if all the necessary surrounding components are there, and if you have a way to program it.
This could be as simple as putting the chip on the Uno and programming it there. Don't do that too often; the socket isn't intended for that. You could get a 28-pin ZIF socket, though.
There are a few things to consider:

The bare chip needs external components like a crystal, etc. to function; you can check the Uno's schematic to see what you want to copy to your PCB/breadboard;
You may want to include a way to program the ATmega328p in-circuit using an ISP or a USB-to-serial chip;
The pin numbers will be different, a minor annoyance;
Possibly things I forgot.

There is a how-to on the Arduino site, and also a description of how to build a "whole" Arduino on a breadboard.

Thank you so much!

You are most welcome. Please accept the answer (if you accept it) so the question doesn't stay open.

I've built PCBs with a standalone ATMega328p chip on them before for situations where I wanted all my electronics embedded onto a single board. It can be a great learning experience imo.
I would suggest first creating a schematic and implementing it on a breadboard with DIP packages as seen on the photo. You will need a crystal, loading caps (22 pF), as well as bypass caps (100nF) and pull-up resistors. Plus any other components your application requires.

After that typically you would burn a boot loader onto the chip so it can be programmed with the Arduino IDE.
Nick Gammon has provided an excellent tutorial on all of this. His article was my main resource when I made my PCBs: http://www.gammon.com.au/breadboard
Once you get everything working on a breadboard, you may want to look into laying out a PCB for a more permanent solution. Best of luck!

Yes, you can use the same sketch and also the same HEX file. Though the uploading depends on your actual setup. If you include a UART USB bridge, like the Arduino has, then you can upload over USB (assuming you have burned the bootloader to the Atmega328p). Otherwise you can use your Arduino as an ISP programmer and burn your sketch onto the Atmega through it. Google for Arduino as ISP for more information

Unable to write in the comments. If you are looking at using just a raw atmega328p, you can use the Arduino as ISP sketch and then upload your existing sketch to the new chip. I use it for programming ATTiny 85 chips for small stand alone projects. Here is a Link  to the Arduino site which explains this in detail.

The Arduino has already a 328p chip on the board, but with a bootloader and a 16MHz crystal.
If you use only the chip, you need to create a board like the arduino.
Or you can extend the IDE with this board library:
https://github.com/MCUdude/MiniCore
So you can still use the same sketch but remove the crystal for example.


text:
I2C communication between Arduino Uno and Nodemcu32-s (ESP32)
I want to send data between an ESP-32 (NODEMCU-32S) and an Arduino Uno but I haven't found any source on how to do that, so I tried this code:
ESP-32 code:
#include <Wire.h>

void setup() {
  Serial.begin(9600);
  Wire.begin(21, 22);      /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
}

void loop() {
  Wire.beginTransmission(8);
  Wire.write(3);  /* sends hello string */
  Wire.endTransmission();  /* stop transmitting */
  Wire.requestFrom(8, 18); /* request & read data of size 13 from slave */
  while (Wire.available()) {
    char c = Wire.read();
    Serial.print(c);
  }
}

And Arduino code:
#include <Wire.h>

void setup() {
  Wire.begin(8);                /* join i2c bus with address 8 */
  Wire.onReceive(receiveEvent); /* register receive event */
  Wire.onRequest(requestEvent); /* register request event */
  Serial.begin(9600);           /* start serial for debug */
}

void loop() {
  delay(100);
}

// function that executes whenever data is received from master
void receiveEvent(int howMany) {
  while (0 < Wire.available()) {
    int c = Wire.read();        /* receive byte as a character */
    Serial.print(c);            /* print the character */
  }
}

// function that executes whenever data is requested from master
void requestEvent() {
  Wire.write("hello esp");
}

But I found that no data was sent.
I connected pin 21 to A4 and 22 to A5 directly.
I cannot find where the problem is. Also, I don't know whether the device address is correct or not, since when I tried an I2C scanner it didn't discover any device.
Also, I hope that there is a similar method to have two-way UART communication between the Arduino and ESP as I found none since I need both chips to send data to each other.

As long as a scan on the ESP doesn't find the Arduino, no point in going forward. Strip both pieces of code to the bare minimum (only I2C and whatever serial you need to debug). Make sure you didn't swap the wires. Add pullups (4.7k or 10k) to both I2C lines.

I made sure of all of that

also, an example code may be helpful please that prints hello on both cards

@Mat I edited the code so that it is easier now

"I hope if there is a similar method to have two way UART communication between the arduino and esp" - If you want to use UART, why not using UART? It's easier to use than I2C.

I'm working on something similar at the moment. Not a complete answer put some thoughts:

Have you considered that the Uno is a 5v board and the ESP32 is 3.3v? You may need a signal level shifter (there are many to chose from) something like Pololu-2595 which is breadboard friendly.

There's a good ESP32 I2C explanation at Random Nerd Tutorials.


text:
Looking to interface height and weight sensor based on I2C Protocol
I have interfaced a height sensor and a weight sensor. The I2C address of the height and weight sensors are 0x29 and 0x2A respectively. I have merged the example of both the sensors.
This is the first time I am working with I2C and need help on this.
Do let me know about any mistakes or any sort of example which can help me to learn coding different I2C addresses, sensors, and interfacing.
#include <Wire.h>
#include "SparkFun_VL53L1X.h"
#include "SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h"

NAU7802 myScale;
SFEVL53L1X distanceSensor;

//Optional interrupt and shutdown pins.
#define SHUTDOWN_PIN 2
#define INTERRUPT_PIN 3

void setup() {
  Serial.begin(9600);
  Wire.begin(0x2A);
  if (myScale.begin() == false) {
    Serial.println("Scale not detected. Please check wiring. Freezing...");
    while (1);
  }
  Serial.println("Scale detected!");

  Wire.begin(0x29);
  if (distanceSensor.begin() != 0) { //Begin returns 0 on a good init
    Serial.println("Sensor failed to begin. Please check wiring. Freezing...");
    while (1) ;
  }
  Serial.println("Sensor online!");
}

// put your setup code here, to run once:

void loop() {
  distanceSensor.startRanging(); //Write configuration bytes to initiate measurement
  while (!distanceSensor.checkForDataReady()) {
    delay(1);
  }
  int distance = distanceSensor.getDistance(); //Get the result of the measurement from the sensor
  distanceSensor.clearInterrupt();
  distanceSensor.stopRanging();

  Serial.print("Distance(mm): ");
  Serial.print(distance);

  float distanceInches = distance * 0.0393701;
  float distanceFeet = distanceInches / 12.0;

  Serial.print("\tDistance(ft): ");
  Serial.print(distanceFeet, 2);

  Serial.println();
  if(myScale.available() == true) {
    long currentReading = myScale.getReading();
    Serial.print("Reading: ");
    Serial.println(currentReading);
  }
}

Do you have a specific question? Is your code not working? If it’s not working, please tell us what it’s doing wrong and what you expected it to do. There are a lot of tutorials on the web if you just need general information about I2C.

Yes the code is not working, I need help whether this is the way to use I2C protocol for two different sensor and if not then how should I proceed

What does “not working” mean? Please edit your question to include the output the program generates. Does it detect the devices? Does it not detect them? How are they wired to the CPU? What CPU are you using? You have both arduino-mega and nodemcu tags on your post. We’re not going to guess these things.

You really do need to edit your question to be more specific.  The whole point is for people searching with similar problems to find applicable answers.  If your title and question are not clear, then the stackexchange web sites may not be a good place for it.  Guess, by any chance are your I2C wires more than, say, 6 inches long.  I2C was designed to be used to connect devices on the same circuit board.  Not to go distances of say a foot or more.  Also, did you include pull up resistors on the I2C bus?


text:
Sparkfun CCS811 sensor not interfacing with arduino
I have sparkfun indoor air quality sensor CCS811 which needs to be interfaced with arduino. I have soldered wires on the sensors and connected with arduino. Have checked the connection with multimeter so that part works. But even using example code on library still I am not getting reading from sensor.
Code:-
#include <Wire.h>

#include "SparkFunCCS811.h"

#define CCS811_ADDR 0x5B //Default I2C Address
//#define CCS811_ADDR 0x5A //Alternate I2C Address

CCS811 mySensor(CCS811_ADDR);

void setup()
{
  Serial.begin(9600);
  Serial.println("CCS811 Basic Example");

  Wire.begin(); //Inialize I2C Harware

  //It is recommended to check return status on .begin(), but it is not
  //required.
  CCS811Core::status returnCode = mySensor.begin();
  if (returnCode != CCS811Core::SENSOR_SUCCESS)
  {
    Serial.println(".begin() returned with an error.");
    //while (1); //Hang if there was a problem.
  }
}

void loop()
{
  //Check to see if data is ready with .dataAvailable()
  if (mySensor.dataAvailable())
  {
    //If so, have the sensor read and calculate the results.
    //Get them later
    mySensor.readAlgorithmResults();

    Serial.print("CO2[");
    //Returns calculated CO2 reading
    Serial.print(mySensor.getCO2());
    Serial.print("] tVOC[");
    //Returns calculated TVOC reading
    Serial.print(mySensor.getTVOC());
    Serial.print("] millis[");
    //Simply the time since program start
    Serial.print(millis());
    Serial.print("]");
    Serial.println();
  }

  delay(10); //Don't spam the I2C bus
}

Things I tried:-
1) different combination of  A4, A5 pins
2) 0x5A & 0x5B i2c address
3) using wake pin with ground
4) using 3.3 & 5V for powering sensor
What else needs to be done?

Don't supply the sensor with 5V. It's datasheet states 3.6V as maximum. You can destroy it with 5V

We cannot see, how you connected the sensor. A4 is the SDA pin, A5 is SCL. You need to connect them to the corresponding sensor pin. Also I2C is not made for long wires. Try to add strong pullup resistors to both lines (maybe 4.7kOhm).

@chrisl will keep them in mind. SDA is connected to A4 and SCL is A5 so not a problem, have uploaded the wiring image above. Wires are around 50cm long so I thought it will be fine. Pull up resistors on SDA & SCL line?

Yes, one pullup resistor for each of both lines. And 50cm is already rather long (I2C is made for communication between ICs on the same PCB or similar distances, so a few cm). Strong pullups might help, if your issue is related to this.

thanks for helping, the problem was on the soldering part so it's solved. Moreover, I have used i2c at 1m wire where I connected Arduino and LCD which worked. Just sharing my experience if it helps.

The problem was on the soldering part. SDA & 3.3V pin on sensor were slightly in contact. I modified it and started working fine.


text:
Possible to connect 3 MPU9250 to Node MCU without multiplixer?
Is the idea of connecting AD0 pins of MPU9250 is still valid like the 2nd answer of this question? - How to change i2c address for mpu9250?
I have connected 2 sensor as test. SCL & SDA of both parallel with D1 & D2 of node mcu. Then connected AD0 of both sensors to different I/O pin of node mcu but it didnt work. What could be the solution?
Code to control 1 sensor:- It worked when I set AD0 to high and changed address to 0x69
#include "MPU9250.h"

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68
MPU9250 IMU(Wire,0x68);
int status;

void setup() {
  // serial to display data
  Serial.begin(115200);
  while(!Serial) {}

  // start communication with IMU
  status = IMU.begin();
  if (status < 0) {
    Serial.println("IMU initialization unsuccessful");
    Serial.println("Check IMU wiring or try cycling power");
    Serial.print("Status: ");
    Serial.println(status);
    while(1) {}
  }
}

void loop() {
  // read the sensor
  IMU.readSensor();
  // display the data
  Serial.print(IMU.getAccelX_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelY_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getAccelZ_mss(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroX_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroY_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getGyroZ_rads(),6);
  Serial.print("\t");
  Serial.print(IMU.getMagX_uT(),6);
  Serial.print("\t");
  Serial.print(IMU.getMagY_uT(),6);
  Serial.print("\t");
  Serial.print(IMU.getMagZ_uT(),6);
  Serial.print("\t");
  Serial.println(IMU.getTemperature_C(),6);
  delay(100);
}

Code to control 2 sensors:-
#include "MPU9250.h"

// an MPU9250 object with the MPU-9250 sensor on I2C bus 0 with address 0x68
MPU9250 IMU1(Wire,0x68);
MPU9250 IMU2(Wire,0x68);

int status;

void setup() {
  // serial to display data
  Serial.begin(115200);
  pinMode(D7, OUTPUT);
  pinMode(D8, OUTPUT);

}

void IMU_1() {
  digitalWrite(D7, LOW);
  digitalWrite(D8, HIGH);
  IMU1.begin();
  IMU1.readSensor();
  Serial.print("IMU 1 is active: "); Serial.print(IMU1.getAccelX_mss(),6);
  digitalWrite(D8, LOW);
}

void IMU_2() {
  digitalWrite(D7, HIGH);
  digitalWrite(D8, LOW);
  IMU2.begin();
  IMU2.readSensor();
  Serial.println("IMU 2 is active: "); Serial.print(IMU2.getAccelX_mss(),6);
  digitalWrite(D7, LOW);
}

void loop() {

IMU_1();
IMU_2();

  delay(500);

}

Result:- It Shows reading on one sensor but the 2nd sensor shows '0' every time.
What's the best way to use 3 I2C sensors when there is only 1 I2C bus?

Possible duplicate of Control multiple MPU9250 to start collecting data at the same time

It sounds like the MPU9250 has a pin, AD0, that lets you switch the device between 2 fixed I2C addresses.
That gives you an easy solution if you need to use 2 of them.
For more, the post you linked suggests keeping them all at the same AD0 state except the one you want to talk to. You’d switch that one’s AD0 pin to the other state, which would cause it’s I2C address, and then talk to it at that address, which would be unique on the I2C bus.
That approach should work, but it’s a bit of a hack.
You say "I have connected 2 sensor as test. SCL & SDA of both parallel with D1 & D2 of node mcu. Then connected AD0 of both sensors to different I/O pin of node mcu but it didn't work." What didn't work? What happens? What output do you get What pins on your mcu are connected to AD0 on your 3 different MPU9250 modules? Where is the code that manipulates the digital pins to select one and only one of your MPU9250 modules for reading?
You need to throughly explain your setup, including the different pin assignments and how they are supposed to work. Don't leave us to read your code and try and figure out your intentions.
Looking at your code it looks like you're using D7 and D8 on your mcu to try to control which MPU9250 is active. However i don't see any code the sets D7 and D8 as outputs.
Why don’t you want to use an I2C address mapping chip? They are readily available, and the ones I’ve seen would let you address up to 8 I2C devices that are hard-wired with the same address.

thanks, have updated the code and errors :) . It doesn't work even when i updated the code. I want to change the address to 0x69 and see but my node mcu has some problem.

You likely need to set up 2 IMU devices, IMU1 and IMU2, both at address 0x68. Configure your D7 and D8 pins to put the first one at address 0X68, and issue the IMU1.begin() command. Then switch the pins so that the 2nd one is on address 0x68 and do IMU2.begin().

What about the above code? I updated it but it shoes reading of 2nd sensor as zero. Also I am worried about the power supply. Looks like node mcu can give 550mA max current while both IMU chip takes 740mA so could this problem be due to current shortage?

Yes, that is a problem. If a single IMU can draw more than the total output of your power supply you have a problem with just one IMU. I found some inexpensive 5V 2A related power supplies online. I am using them for my project. I suggest you do the same.

Thanks Duncan :)

One las thing, which method will get the imu data faster? Using above method or using multiplexer? (except for using node mcu on each sensor) Because I want to control robot arm in realtime using those sensors so need to extract data from IMU ASAP.

I doubt you'd be able to detect the difference in speed between the 2 methods. The software method adds a few instructions to manipulate pins before issuing I2C commands, so would introduce a few microseconds of additional delay. The impact of using the hardware multiplexer would depend on how much propagation delay the multiplexer adds to I2C commands being passed back and forth to the "downstream" devices. If you use it by first selecting one of it's multiplexed I2C devices, it probably routes messages with nanosecond delay, but you would have to run code to control the I2C multiplexer.


text:
Stepper not working properly using L298N
If googled and search here but can't find the same issue.
I'm using an Arduino Uno, L298N driver (5v jumper is off - actually just 2 holes where the jumper pins were supposed to be), scavenge stepper motor from a 5 inch drive - TEAC P.no. 14769070-90 (we call it a floppy drive). I used the example from the Arduino IDE that spins the stepper in on direction and then the other.
The stepper motor has a 5 wire ribbon and with an LED test showed that the out side two wires are a pair. I've look at schematics for the 5 wire, I know it's got to do with the uni/bi polar of the motor but I have no idea if I need to connect this middle wire?
I've wired it according to this Maker Guides article
The issue is that in the clockwise direction it is very weak and it just vibrates in the anti-clockwise direction.
How do I go about diagnosing the issue?
(I'm on a beginner level with regards to hw. Sw engineer with a Solder iron - very dangerous)

The motor you got is a unipolar stepper motor. The five wires are one end of the four windings inside the motor, plus a common wire that connects all the other poles together.
Bipolar motor offer more torque than unipolar, at the expense of a more difficult control. 6 wires unipolar stepper motors can be converted to bipolar motors just selecting the correct wires. I am not aware of any method to convert a 5 wires unipolar motor to bipolar that does not imply tearing it apart (which is not really a great idea).
The L298 is not really made to drive this kind of motor, it is best suited to drive bipolar motors (can still drive it tho, please read the next paragraph). Good news, driving unipolar steppers is rather simple. You basically have to connect the common wire to you V+ rail and connect the other wires to GND via BJT/MOS. Don't connect them directly to the Arduino! It's the perfect recipe for fried chips. You can either choose to use discrete transistors or arrays like the ULN2003.
If you still want to use the L298 to drive the motor you can exploit the lower transistors of the H-bridge. Connect Vss and the enable pins to 5V, Vs to your positive rail voltage and pin 1, 8, 15 to GND. Then connect each phase to each output and the input to 4 pins to an Arduino/microcontroller. Leave the pins normally on and turn one off in turn (1->2->3->4->1...) and your stepper should run! This works because when you leave the pins on, the upper side of the H-bridge is powered on, thus shorting the winding. When you turn one pin off the lower part of the bridge will actually turn on and let the current flow to GND, closing the circuit and powering the winding. Using this kind of circuit you could also omit the freewheeling diodes needed to discharge the windings (as said before, you short them, allowing current to freely circulate).
EDIT/TLDR: Connect the windings to the output of the L298 and the common one to the positive rail. Keep the pins high and turn one sequentially off, you should see the motor move.

Take a look at this video - it has a great explanation of using a 5-wire stepper motor with an Arduino


text:
Why does my delay get inaccurate after one minute ? It makes my servo vibrate
I have a fancy setup to cool my beer at a controlled temperature (you can find details and a photo here if you want). The input of my system is a temperature, the output is a servo position.
Long story short
On startup the servo is stable enough, but every time after 67s of runtime suddenly the servo starts vibrating. I have an oscilloscope and I can see that after 67s, instead of a steady 2.3 ms the length of the pulses oscillate in a small range, like between 2.300 and 2.320 ms, and it's enough of a range to be a problem.
What happens at 67s ?? Is there some kind of overflow ? I'm very puzzled because all in all my code for the pulse is very simple.
I'm having my problem on this code, branch bs18b20 of my repo. The pulse is generated line 293, with custom code.
More context
I had already asked for help right here with my setup. We had determined that using Servo.h along along with the 1Wire protocol make the interruptions used by both libraries get in the way of one another, so the servo receives bad values and vibrates too. In my last comment in this thread I said that the problem was solved, but I discovered later the problem of the servo getting unstable after some time, as exposed above.
To overcome that I changed tactics, switched my bs18b20 for a lm35 which doesn't need 1Wire, and switched back to Servo.h. It worked very well... in my electronics lab. But then (reality sucks) I found out when actually using my device in the kitchen that sometimes the temperatures start getting very wrong, and I suspect that the humidity alters the voltage reading of my lm35. And that's why I'm trying to change back again to my previous solution with a waterproof bs18b20.
While writing this, stackexchange proposed this thread with a very promising solution, I will definitely try that. Nonetheless, for the sake of it, I'm still interested in knowing what causes my problem above, so I'm posting this anyway.

please add the code to the question

try putting timer_20 = now; at the begining of the if block

decimal 67,000,000 microseconds is hexadecimal 3FE56C0 ... that is very close to hex 4000000 ... it may be some rollover, but it makes no sense because that is a 27 bit number

Do you have the same issue if you use delayMicroseconds() instead of the while (micros() < time_micros) loop?

Yes @jsotola micros() overflows after about 70 minutes, and millis() after 70 000 minutes I guess. So that shouldn't be my problem. I'll try moving the affectation of timer_20, you're right, but I don't see how that may help.

@edgar-bonet I've actually tried that, and the problems worsens ! The servo is unstable right from the start.

@jsotola I tried moving the line at the beginning of the if block, and it behaves exactly the same.

At a first glance I find it very suspicious that the motor starts vibrating after 67s, which is very close to 2^16=65536 milliseconds...

Without looking into the details of your code, it looks like you are
having issues with interrupts. According to your comment, this simple
code gives a very uneven pulse length:
digitalWrite(SERVO_PIN, HIGH);
delayMicroseconds(servo_value*1000);
digitalWrite(SERVO_PIN, LOW);

The function delayMicroseconds() delays for the requested time, plus
any time taken by interrupts. Thus, if the delay is inconsistent while
servo_value does not change, it can only be because of interrupts.
Trying to understand the exact symptoms is likely to be quite hard, as
one would have to dig into the source of the libraries you are using,
and look at every ISR in there. The fact that the version delaying with
micros() only starts misbehaving after some time is probably due to
some very slow “beating” between the timing of your servo and the timing
of an interrupt. The fact that the pulse is occasionally 20 µs
longer is consistent with it having been interrupted for 20 µs,
which for an ISR would be kind of long but not insanely long.
Rather than trying to analyze in detail how the interrupts are
interfering with your servo, I would recommend sidestepping the problem
completely and driving the servo with a hardware-generated PWM signal.
That would give a very consistent pulse length, completely immune to
being disrupted by interrupts. You can achieve 0.5 µs resolution
with a 20 ms period by setting Timer 1 to fast PWM and
clocking it at 2 MHz, like this:
// Configure timer 1 for driving a servo
// on pin OC1A = PB1 = digital 9.
void setup_timer()
{
    TCCR1A = 0;           // undo the Arduino core configuration
    TCCR1B = 0;           // ditto
    ICR1   = 40000 - 1;   // period = 20 ms = 40000 timer ticks
    OCR1A  =  3000 - 1;   // pulse length = 1.5 ms = 3000 timer ticks
    TCCR1A = _BV(COM1A1)  // non-inverting PWM on OC1A
           | _BV(WGM11);  // mode 14: fast PWM, TOP = ICR1
    TCCR1B = _BV(WGM12)   // ditto
           | _BV(WGM13)   // ditto
           | _BV(CS11);   // clock @ F_CPU/8 = 2 MHz
}

Then you can change the pulse length simply by writing to OCR1A: write
one less than the desired pulse length, in units of 0.5 µs.

You're very probably right, and your solution is the one I've adopted, though I like that some nices folks did the ugly part, I used this : https://learn.adafruit.com/neopixels-and-servos/the-ticoservo-library and it works like a charm. It does under the hood exactly what you propose, the article is great. Still, I would have liked to understand the threshold of 67 (more like 66 actually) seconds.


text:
Serial com register formula
i am working on a atmega328p, learning to uses its registers instead a coding with common arduino code.
i've found this formula to get the baud rate on the Serial port (using USART protocol) :

how could i type this in C language ? or specifically in the arduino IDE ?
--
i made some researches and discovered that it could write it that way :
float _baudrate = (16000000/(16*9600));

then i convert the value to int (because i need an integer value)
int _baudrate_int = (int)_baudrate;enter code here

all this for a 9600 baudrate of course.
But when i do this, i don't understand why, the code does not calculate it right. i'm supposed to have 103-104 and i get 710.
it will work if i type (16*9600) product manually. Which is 153600
float _baudrate = (16000000/153600);

then i get the right baudrate result. but what if i want the code to calculate everything ? how can i do ?
where's my mistake with this line of code ?
float _baudrate = (16000000/(16*9600));

how would you do it on paper?

Welcome to SE/Arduino! Please take the [tour] to learn how this site works, and read "[ask]". Then come back and [edit] your question to provide the source you have so far. Please add where specifically you are stumbling. BTW, general C questions are better asked on [so], especially if they don't have a relation to Arduino. But it is fine here, since you are asking about the Arduino IDE. Are you aware that you are programming C++ if you use the Arduino IDE? C++ and C are different languages.

Here:

float _baudrate = (16000000/(16*9600)

other than the missing parenthesis and semicolon, you have an integer
overflow. The issue is that, on AVR-based Arduinos, an int is only
16-bits long. The constants 16 and 9600 being small enough to fit in
an int, they are implicitly given the int type. Then, their
multiplication is also done with the int type, and the product
overflows and wraps modulo 216 to 22528.
You can fix this by giving either or both of these numbers the L
suffix, which will make them use the long data type. Alternatively, if
you want a floating point calculation, you can use .0 as a suffix.
Not that the avr-libc provides a header file with some macros for this
calculation, which is then done by the preprocessor:
<util/setbaud.h>: Helper macros for baud rate
calculations. You can use them as follows:
#define BAUD 9600
#include <util/setbaud.h>

void set_baud_rate() {
    UBRR0 = UBRR_VALUE;
#if USE_2X
    UCSR0A |= _BV(U2X0);
#else
    UCSR0A &= ~_BV(U2X0);
#endif
}

Edit:
To answer the question in a comment: yes, the L suffix creates a
long constant, and is thus similar to creating a long variable
(except it is a constant instead of a variable).
I suggest you take a look at the line below from setbaud.h. In the case
where U2X0 is not needed, the baud rate register value is computed as:
#define UBRR_VALUE (((F_CPU) + 8UL * (BAUD)) / (16UL * (BAUD)) -1UL)

A few things to note:

It is all computed with integers, no floating point. Actually, the
computation is performed by the compiler, at build time, not by the
Arduino.
The suffix UL is for unsigned long
Adding 8 before dividing by 16 is a way to round the result to the
nearest integer, instead of rounding to zero. Ties are rounded up.
There is -1UL at the end, as this is required by the UART hardware
(it is in the formula from the datasheet).

yeah i know for the missing parenthesis and semicolon. just made a wrong ctrl+c ctrl+v.

I added the L suffix and it worked. impressive, it works ! and i understand what you explained and the fact it will make them use long data type. i have an other little question : is putting the L suffix the same that doing an other variable and make it = (long)variable ? if you see what i mean

yes i understand. the same formula with a 8-addition and giving it long type before rounding it and converting to integer.


text:
Weird issue with wire.requestfrom() and MailClient.sendMail() on ESP32- rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
Update_2: No change after Update_1, same error. I still have to comment either email, I2C, or Temperature out, that the other two can work.
Update_1: I'm also using a DS18B20 with #include <DallasTemperature.h> and #include <OneWire.h>. If I comment Temperatures_Sens.begin(); in Setup() out, the problem is solved as well. I excluded Dallas now and wrote my own code. Let's see, on a naked ESP32 it works... I will test later...
Original Post:
I'm facing a really hard nut. It's a weird issue, at least for me. I'm reading data via I2C and want to send them via email. Therefore I have two functions. The code compiles normally and I can upload it. But after that the ESP32 immediately restarts without even going through the setup().
But if I mark //Wire.requestFrom(PCF8591, 2); or //MailClient.sendMail(&smtp, &mail); as a comment, the program runs perfectly, well without the functionality of the comment. I'm really LOST and it keeps me busy for days already. I would be very grateful for any help that would solve my problem.
rst:0x3 (SW_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13132
load:0x40080400,len:3036
entry 0x400805e4

Here are my functions:
#include <ESP_Mail_Client.h> //mobizt/ESP Mail Client@^3.4.19
#include <Wire.h>

int readAnalogFromPCF8591(int channel) {
   Wire.beginTransmission(PCF8591);
   Wire.write(0x40 | channel);
   Wire.endTransmission();

   Wire.requestFrom(PCF8591, 2); -> Option 1 to comment out

   if(Wire.available() > 0){Wire.read();}
   if(Wire.available() > 0){
     int value = Wire.read();
     return value;}
   return -1;}

void SendEmail(const char* subject, const char* content){
    if(WiFi.status() == WL_CONNECTED){
        session.server.host_name = smtpServer;
        session.server.port = smtpServerPort;
        session.login.email = emailSender;
        session.login.password = emailSenderPassword;
        session.login.user_domain = "";
        session.secure.startTLS = true;
        mail.sender.name = "Sensor";
        mail.sender.email = emailSender;
        mail.subject = subject;
        mail.addRecipient("Recipient", emailRecipient);
        mail.text.content = content;
        mail.text.charSet = "us-ascii";
        mail.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
        smtp.setTCPTimeout(10);
        smtp.connect(&session);

        MailClient.sendMail(&smtp, &mail); -> Option 2 to comment out
}


text:
What are the Arduino hardware options for experimenting with IoT?
Just starting to learn about Arduino and IoT. I'd like to know what the Arduino hardware options are to try the following:

Use FreeRTOS as SO
WiFi and BLE connectivity
Solderless board
Test OTA features
Experiment integration with different IoT Cloud platforms e.g. Azure IoT Hub
Build custom IoT devices

an opinion based question, but ESP32 is the answer

One of the options for closing a question is that it's "opinion-based" and you're asking for what "is best".  Without any criteria on what you mean by "best" it's difficult to say that the question won't get closed for that reason.

Thank you @Juraj and @ timemage for your comments! Both of you are precise on the option-based question. The reason is that as there are so many options available at the Arduino store am not clear which of them would allow me to do all the above.

There are many options; which one is "best" for you I leave up to your own research, that could start here:
There's a list of Arduino's based on the SAMD21 that are supported by the FreeRTOS_SAMD21 library here; pick any one with WiFi and BLE.
There are probably a zillion clones out there that could also do what you want, and there is also a FreeRTOS port for the ESP32 (ESP-IDF FreeRTOS, and maybe other ones as well).

Thank you @ocrdu

You are welcome. Please accept the answer (if you accept the answer) so the question doesn't stay open.


text:
How can I operate the leds and neopixel strips together (at the same time)?
Here's the code I wrote:
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;

int numOfRegisters = 2;
byte* registerState;

long effectId = 0;
long prevEffect = 0;
long effectRepeat = 0;
long effectSpeed = 30;

#define LED_PIN    2
#define LED_COUNT 24

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
  clock_prescale_set(clock_div_1);
  #endif

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)

  //Initialize array
  registerState = new byte[numOfRegisters];
  for (size_t i = 0; i < numOfRegisters; i++) {
    registerState[i] = 0;
  }

  //set pins to output so you can control the shift register
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
}

void loop() {
  do {
    effectId = random(6);
  } while (effectId == prevEffect);
  prevEffect = effectId;

  switch (effectId) {
  case 0:
    effectRepeat = random(1, 2);
    break;
  case 1:
    effectRepeat = random(1, 2);
    break;
  case 3:
    effectRepeat = random(1, 5);
    break;
  case 4:
    effectRepeat = random(1, 2);
    break;
  case 5:
    effectRepeat = random(1, 2);
    break;
  }

  for (int i = 0; i < effectRepeat; i++) {
    effectSpeed = random(10, 90);

    switch (effectId) {
    case 0:
      effectA(effectSpeed);
      break;
    case 1:
      effectB(effectSpeed);
      break;
    case 3:
      effectC(effectSpeed);
      break;
    case 4:
      effectD(effectSpeed);
      break;
    case 6:
      effectE(effectSpeed);
      break;
    }
  }

  // Fill along the length of the strip in various colors...
  colorWipe(strip.Color(255,   0,   0), 1); // Red
  colorWipe(strip.Color(  0, 255,   0), 1); // Green
  colorWipe(strip.Color(  0,   0, 255), 1); // Blue

  // Do a theater marquee effect in various colors...
  theaterChase(strip.Color(127, 127, 127), 1); // White, half brightness
  theaterChase(strip.Color(127,   0,   0), 1); // Red, half brightness
  theaterChase(strip.Color(  0,   0, 127), 1); // Blue, half brightness

  rainbow(1);             // Flowing rainbow cycle along the whole strip
  theaterChaseRainbow(1); // Rainbow-enhanced theaterChase variant
}

void colorWipe(uint32_t color, int wait) {
  for (int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);          //  Set pixel's color (in RAM)
    strip.show();                           //  Update strip to match
    delay(wait);                            //  Pause for a moment
  }
}

void theaterChase(uint32_t color, int wait) {
  for (int a=0; a<10; a++) {  // Repeat 10 times...
    for (int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();          //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for (int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}

void rainbow(int wait) {
  for (long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    for (int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;      // First pixel starts at red (hue 0)
  for (int a=0; a<30; a++) {  // Repeat 30 times...
    for (int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();          //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in increments of 3...
      for (int c=b; c<strip.numPixels(); c += 3) {
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        int hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
      }
      strip.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}

void effectA(int speed){
  for (int i = 0; i < 16; i++) {
    for (int k = i; k < 16; k++) {
      regWrite(k, HIGH);
      delay(speed);
      regWrite(k, LOW);
    }

    regWrite(i, HIGH);
  }
}

void effectB(int speed) {
  for (int i = 15; i >= 0; i--) {
    for (int k = 0; k < i; k++) {
      regWrite(k, HIGH);
      delay(speed);
      regWrite(k, LOW);
    }

    regWrite(i, HIGH);
  }
}

void effectC(int speed){
  int prevI = 0;
  for (int i = 0; i < 16; i++) {
    regWrite(prevI, LOW);
    regWrite(i, HIGH);
    prevI = i;

    delay(speed);
  }

  for (int i = 15; i >= 0; i--) {
    regWrite(prevI, LOW);
    regWrite(i, HIGH);
    prevI = i;

    delay(speed);
  }
}

void effectD(int speed){
  for (int i = 0; i < 8; i++) {
    for (int k = i; k < 8; k++) {
      regWrite(k, HIGH);
      regWrite(15 - k, HIGH);
      delay(speed);
      regWrite(k, LOW);
      regWrite(15 - k, LOW);
    }

    regWrite(i, HIGH);
    regWrite(15 - i, HIGH);
  }
}

void effectE(int speed) {
  for (int i = 7; i >= 0; i--) {
    for (int k = 0; k <= i; k++) {
      regWrite(k, HIGH);
      regWrite(15 - k, HIGH);
      delay(speed);
      regWrite(k, LOW);
      regWrite(15 - k, LOW);
    }

    regWrite(i, HIGH);
    regWrite(15 - i, HIGH);
  }
}

void regWrite(int pin, bool state) {
  //Determines register
  int reg = pin / 8;
  //Determines pin for actual register
  int actualPin = pin - (8 * reg);

  //Begin session
  digitalWrite(latchPin, LOW);

  for (int i = 0; i < numOfRegisters; i++) {
    //Get actual states for register
    byte* states = &registerState[i];

    //Update state
    if (i == reg){
      bitWrite(*states, actualPin, state);
    }

    //Write
    shiftOut(dataPin, clockPin, MSBFIRST, *states);
  }

  //End session
  digitalWrite(latchPin, HIGH);
}

This comes up ALL THE TIME. Don't use delay. Do a Google search on "arduino blinkwithoutdelay" and read one of the various write-ups on the subject.
Here's a writeup that looks pretty good:
https://learn.adafruit.com/multi-tasking-the-arduino-part-1/using-millis-for-timing


text:
Resistor - Correct value for optocoupler, but dont have that size
I am making a shutter for my camera using a Arduino and an optocoupler.
I understand most of most parts, but unsure about the resistor because I don't have the correct size. 5V will be coming from the Arduino, and the 4N35 will need 1.3V 10mA. This leads to a 380Ω resistor.
Now I only have 100Ω, 220Ω, 330Ω, and 1kΩ resistors. I have read I shouldn't use anything lower than 380Ω and only use higher but 1kΩ seem a little too high haha.
Just looking for some pointers please.

1kΩ will be just fine. But if you want lower you could take two 1kΩ and place them in parallel - that will give you 500Ω.
BTW - 1kΩ will give you ((5-1.3)/1000=) 3.7mA through the diode of the optocoupler, and 500Ω will give you ((5-1.3)/500=) 7.4mA.

Thank you, works perfectly. Still got a lot of learning to do haha.

And 330 will give you just over 11mA, I'd go with that

Agreed, absolute max current for 4N35 is IF < 50 mA. But if IF= 3.7 mA works reliably, as there's no current required on the output side, I'd take that.


text:
Sending variable over serial
I have an LCD keypad shield that I'm using to control a Catalex serial MP3 module and I have an int variable that has the volume setting which can go from 1 to 30. I'm trying to send the variable to the module but it's not working. Here's the code for the serial request:
void SetAttractVolume() {
  SerialString = SerialString2 + AttractVolume;
  delay(20);
  Send_buf[0] = 0x7e; // starting byte
  Send_buf[1] = 0xff; // version
  Send_buf[2] = 0x06; // the number of bytes of the command without starting byte and ending byte
  Send_buf[3] = 0x06; //
  Send_buf[4] = 0x00; // 0x00 = no feedback, 0x01 = feedback
  Send_buf[5] = 0x00;
  Send_buf[6] = 0x12;
  Send_buf[7] = 0xef; //ending byte
  for (uint8_t i=0; i<8; i++) {
    mySerial.write(Send_buf[i]); // send bit to serial mp3
    Serial.print(Send_buf[i], HEX); // send bit to serial monitor in pc
  }
  Serial.println();
}

"0x12" is the volume control, you set the 12 to any number from 1 to 30 to change it, I thought I could just put my variable in there, like this:
void SetAttractVolume() {
  SerialString = SerialString2 + AttractVolume;
  delay(20);
  Send_buf[0] = 0x7e; // starting byte
  Send_buf[1] = 0xff; // version
  Send_buf[2] = 0x06; // the number of bytes of the command without starting byte and ending byte
  Send_buf[3] = 0x06; //
  Send_buf[4] = 0x00; // 0x00 = no feedback, 0x01 = feedback
  Send_buf[5] = 0x00;
  Send_buf[6] = 0xAttractVolume;
  Send_buf[7] = 0xef; //ending byte
  for (uint8_t i=0; i<8; i++) {
    mySerial.write(Send_buf[i]) ;//send bit to serial mp3
    Serial.print(Send_buf[i],HEX);//send bit to serial monitor in pc
  }
  Serial.println();
}

This doesn't compile, I know it's not the correct way to do it, but I want to know how to do it right.
Thanks in advance.

This doesn't compile  ... you did not present the complete code amd you fid not say anything about any errors ... i suggest that you learn some programming ... at least examine some of the example sketches in the arduino IDE

Send_buf[6] = 0xAttractVolume; makes no sense; 0x is used to indicate a hex number follows; you can't just stick a variable name to it. Try Send_buf[6] = AttractVolume; and see what happens.


text:
DC Motor will not work. Transistor method nor L293D!
New to Arduinos and stuff.
I have tried the L293D and the transistor method but the motor just wouldnt work.
I have tested the motor and it definitely is fine.
Below is my layout for this attempt:
Bits used:

Arduino UNO
1N4007 Diode
PN2222
230 ohm resistor

My sketch is ::
int motorPin = 3;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(motorPin, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (Serial.available()) {
    int speed = Serial.parseInt();
    if (speed >= 0 && speed <= 255) {
      analogWrite(motorPin, speed);
    }
  }
}

HELP!!!

First of all don't power the motor using your Uno's 5V supply.  Motors are notoriously noisy and will almost always cause the Uno to be unstable and reset itself.

Check your line ending in the serial terminal. If you have anything other than "none" then you'll get your number followed immediately by 0.

You can sanity check your transistor setup by not controlling the base in software.  Just take your jumper out of pin 3 and manually connect it to 5V and GND.  If you motor doesn't turn then, it has nothing to do with your software.

use simplest possible code to run the motor ... there is absolutely no reason to have any Serial code in your sketch when testing the motor .... only two commands are needed, pinMode and analogWrite ... both can be in setup()

Actually you don't even need the pinMode - PWM is an alternative function and not affected by the direction register.

Thanks for all the help guys. I have tried this setup multiple times but it didn't work. So now I put it together again to try some of the suggestions and it just worked before I could implement any of the above suggestions. I will try now with the L293 and come back.


text:
Bluesmirf Mate Silver (RN-42) enter command mode when in HID mode
I am having problems getting the Bluesmirf Mate Silver (RN-42) into command mode once I have switched to HID mode. I have bought a second new Bluesmirf Mate Silver to confirm my issue.
I soldered the Bluesmirf and connecting to Arduino Uno. I used the ‘Example code: Using Command Mode’ from https://learn.sparkfun.com/tutorials/using-the-bluesmirf to successfully enter command mode.
I then entered the following commands in command mode (leaving out the comments):
SM,5   // Mode = 5, (any) Auto reconnect
SA,2   // Authentication Mode 2 (SSP, "just works" mode)
S-,myName  // // Set BT Name, This short name with no spaces is Picked up ok on windows
S~,6   // Enable HID on reboot
R,1    // Reboot to lock in perameters

Next I use a PC and pair with the bluetooth ‘keyboard’ I have created above. I am able to use the Bluetooth and Arduino sketches to write into notepad on the bluetooth connected PC.
However now I cannot get back into command mode to make changes to the Bluesmirf config. Trying to use the example code above I can see ‘$$$U,9600,N’ typed into notepad on the connected PC each time I load the sketch, rather than being used to enter command mode.
How do I get back into command mode after HID mode has been triggered.

I believe that the problem is caused by the mode I entered. According to the datasheet on pg 10 Auto-Connect Master Mode (SM,3) enters high speed mode and this connection cannot be broken via commands or software break characters.
It goes on to explain that both Auto-Connect DTR Mode (SM,4) and Auto-Connect ANY Mode (SM,5) (which I used) function like Auto-Connect Master Mode (SM,3), so I guess that in these modes the $$$ escape characters cannot be used to enter command mode either.
I was able to resolve this by performing a hard factory reset on the Bluesmirf Mate Silver (RN-42). I previously tried following a couple of you-tube tutorials that weren't very clear and didn't have any success. I looked at the instructions in this thread titled 'Factory Reset the RN-41 or RN-42' to get me on the right lines.
This worked for me:

Connect the Bluesmirf Mate Silver GND pin to GND and disconnected all other pins
Connect a wire to 3.3v on Ardunio
Load the Ardunio with an empty sketch, and keep it powered on
Touch the 3.3v wire repeatedly (3+ times) to the GPIO4/PIO4 connection hole on the Bluesmirf. This is a third of the way down one edge of the board.
Factory reset should now be complete - note I didn't see any indication lights during this process.

Then I could wire up the Bluesmirf as normal and use ‘Example code: Using Command Mode’ from https://learn.sparkfun.com/tutorials/using-the-bluesmirf to successfully enter command mode.

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


text:
Multimeter short circuit
I am a beginner in electronics, and I recently bought the Arduino student kit from the official Arduino website. I followed the course until the lesson with the multimeter. I built a simple circuit: + from pin 13 of Arduino uno to breadboard with a resistor and a led, to - and ground in the uno board. I measured the voltage according to the tutorial. However, having no prior hands-on experience with electronics, I attempted to measure current and resistance the same way. Shortly after I realised that's not how you do it. I suppose I created a short circuit. Have I managed to fry something? The arduino board seems to be working fine, it didn't even disconnect from my laptop. Is the multimeter still safe to use?
The multimeter is XL830L. My laptop is working, as far as I can tell the arduino board is fine as well.

Can you edit your question and add that you were using a "xl830l" multimeter. Also, can you make it clear what is working and what is not working. It sounds like the laptop and Arduino is working. But the multi meter may no longer be working?

Yes the laptop and the arduino board is working, if the multimeter still measures current, does that indicate the fuse didn't blow? Also do you think it's worth it to purchase a USB hub to protect the laptop from accidental short circuits? Does it work that way?

I attempted to measure current and resistance the same way Can you clarify what "the same way" was? Exactly where did you connect the multimeter pins? Across pin 13 and ground? Across the LED? Across the resistor? In series with the resistor?

Yes across the pin 13 and ground but the probes were touching the wire connected to the breadboard. The red probe touching end of the wire that was in the + column and the black one the end of the wire that was in the - column. Not the wires that connected the breadboard and the +/- columns to pin 13/ground, if that makes any difference. The voltage was measured properly in parallel and basically I tried measuring current and resitance with the same layout.

Just to be clear, voltage in measured in parallel to a device you want to check up on. Like an LED. Current is measured in series. Again w/the LED, you would have to break the circuit open an insert the current meter to complete the circuit.  Doesn't matter which side of the LED. So, going on, you tried to measure the current from the positive to negative power wires.  Likely you put 500mA across your multi meter. And from the pictures of a XL830L, we see clearly that exceeds the mA limit printed next to the low current / voltage port. So, the low current part of your meter may be broken.

So if the multimeter still measures low current, does it mean the number is inaccurate or that the fuse just didn't blow and it still can be used?

Most multi meters are designed to measure high currents (in the Amp range) and low currents (in the Milliamp range (1/1000 of an Amp)). When measuring low current the red probe is normally connected to the same multi meter port as when measuring voltage. When measuring high current the red probe is normally moved to a special high current port.
Since you didn't mention moving the red probe, it is assumed you had left it in the low current / voltage measuring port.
Assuming the above is correct, it is likely the low current fuse inside the multi meter has blown doing its job (protecting the Arduino) and now needs replacement.
Multi meters vary greatly. This tutorial about replacing multi meter fuses might provide some general guidance.

Well yeah I had looked inside the multimeter before posting this, and there was no fuse, I guess the multimeter from the student kit is cheap. So do you think something was damaged the arduino board/multimeter or even my laptop?

Your laptop should moderate the current of a USB 2.0 port not to exceed 500mA. After that, the voltage should start dropping to protect the laptop. The Arduino outputs should be able to handle a couple dozen mA. I don't know when the multi meter low current protection on your meter will blow. An inexpensive meter might use a low value resistor as a fuse. Also, such a meter may solder fuses directly to the PCB to save money. Search for leaded fuses to see images of what they look like.

It's the xl830l multimeter. I'm quite sure the multimeter was showing like ~70-80 mA while the short circuit happened. That doesn't seem too high to me, considering short circuit means theoretically ~0 resistance, infinite current. Does this signify that the breadboard have some small intrinsic resistance?

A digital multi meter samples voltage (and current) at desecrate intervals and normally averages over that sample. Who knows what the instantaneous maximum current flow might have been. Most multi meters state a range of current it can measure right on the low current and high current multi meter ports. Exceeding the upper limit of the low current port will likely cause the fuse (or resistor) to fail. There is no such thing as zero resistance or infinite current in real life. Besides, your computer's USB 2.0 port should have limited the total current to 500mA just to protect its self.

Thanks for your help! It's much appreciated :)

@wolfgangmozart12  That doesn't seem too high to me, considering short circuit means theoretically ~0 resistance, infinite current. Yes, but the multimeter measures current by measuring the voltage drop over a small resistance, so it would not actually be zero resistance, and therefore not infinite current.


text:
L9780 and SPI communication
I'm working on a program to interface with a development board I spun for an L9780 - wideband oxygen controller IC. At this point, I'm trying to get a consistent "status" read back but continue to get some unexpected results that I'll explain below. This is the first "real" time I'm trying to write the SPI sequence for a chip from scratch, which is why I'd appreciate a sanity check!
The first question/verification I had was the SPI mode/setup. Searching around it looks like per the datasheet my clock is idle-low and the first data assertion (on SI) happens prior to the clock edge going high. This should correspond to a MODE0. Section 6.3 lists it as MSB first. The SPI timing table also lists 8MHz for the transfer rate; all the above should give me my config, correct?
My second question/verification was my use of the "SPI.transfer()" function. I made my way through this thread and understand the syntax behind it, so I think that part is ok.
Section 6.3.1 talks about the "REG" bit which is what's used to latch if the next SO frame contains the input reg, or the current "status" reg. This is why in my "get_status" function I'm sending out the request, and then doing another SPI.transfer (via the function) to read the result. Is this correct?
The reason I think I'm having issues is that for the status reg, the MSB is an ignored bit and then 3 version bits. Intermittently, when using my current code to test, I'm getting a change from a dec(1) value to a dec(2) value. This obviously isn't right, so while it appears I'm able to "communicate" in some form with the chip I'm guessing my formatting or byte order is FUBAR somewhere.
Is it the fact that the arduino is a little endian and I'm relating that to a SPI that transmits MSB first? From the various 64b words I've gotten back, that also doesn't appear to be the case, given the last byte also changes.
Also, per the datasheet there are some fixed (CB) bits and the SPI fault bits that should be giving some insight into the health of the current SPI frame. Both of these are giving me issues as well, which is further pointing me at that I've got something messed up with my SPI communication.
All reasons I'd appreciate some help! Below are some "outputs" from my current code just as a sample for what I'm talking about.

SI register on startup (no setting transfer, nothing)

0x4503458300C2CD31
0x450345A300E26E32
0x450345A300E27732

SI register after “send H/W config to L9780”

0x370045A30002F933
0x370045A30082FA33

status register on startup (no setting transfer, nothing)

0x450345A300024632
Same result, multiple times

status register after “send H/W config to L9780”

0x380045A3FFE1FA33
0x380045A300E2FA33
0x370045A300C2F933

Status register after heatup and “enable VCCS” and “enable stgINRC”

0x1A031AA3001AFA33
0x0C030CA3007AFA33
0x1A0319A300FAFA33
0x150315A3009AFA33

L9780 datasheet
/*  Program is taken from the development firmware but simplified
 *   to menu actions for preliminary debug.
 *
 *   NOTES
 *   -------------
 *   -HTR PWM output from uC seems to be inverse. When applying a
 *      15% duty, the heater draw is higher than 85% duty
 */

//*****includes
#include <SPI.h>

//*****general defines and data
#define serial_baud       9600                //serial baudrate
#define L9780_SPI_SPD           8000000                         //SPI Frequency (per L9780 timing diagram)
#define L9780_SPI_ORDR      MSBFIRST                        //define SPI order as MSB first (per L9780 timing diagram)
#define L9780_SPI_MODE      SPI_MODE0                       //define SPI mode, clock Idle LOW, first CMD sent w/o SCK (per L9780 timing diagram)
#define L9780_SO_SI       true                //used for "get status" - put the input (SI) register in SO
#define L9780_SO_STAT     false               //used for "Get status" - put the status register in SO
//pn_SPI0_MOSI              11                                  //!pinDef: SPI0 master out slave in
//pn_SPI0_MISO              12                                  //!pinDef: SPI0 master in slave out
//pn_SPI0_SCK                   13                                  //!pinDef: SPI0 clock
#define pn_L9780_CS       10                  //!pinDef: chip select for L9780
#define pn_htr_out        9                     //!pinDef: manual heater control output

//*****L9780 specific data
#define L9780_rx_reg      0x0800000000000000  //mask to get back the L9780 input register - bitOR
#define L9780_status_reg  0xF7FFFFFFFFFFFFFF  //mask to get back the status register - bitAND
#define L9780_VCCS_en     0x0040000000000000  //mask to enable operator - bitOR
#define L9780_STGINRC_en  0x0200000000000000  //mask to enable short to gnd on INRC - bitOR
#define LSU49_start_CFG   0x00040F18192A8040  //LSU 4.9 start config - non-synchronous mode
/* Config bit definitions:
 * b63-60 = 0;     not used
 * b59 = REG;      set appropriately when transmitting or receiving
 * b58 = 0;        INRC pull-down (try initially disabled)
 * b57 = 0;        INRC short to ground enable (disable on start)
 * b56 = 0;        INRC gain
 * b55 = 0;        tag resistor network switch (ch1)
 * b54 = 0;        VCCS enable (disable on start)
 * b53 = 0;        VCCS output ch (ch1)
 * b52 = 0;        VCCS pull-down (try initially disabled)
 * b51 = 0;        compensation network (chA)
 * b50 = 1;        VCCS voltage clamp enable
 * b49 = 0;        VCCS voltage clamp switch (ch1)
 * b48 = 0;        VCCS voltage clamp symetry (symetric)
 * b47 = 0;        fault clear (don't clear any faults)
 * b46-43 = 0001;  purge current (-14uA) (taken from L9780 test docs)
 * b42-40 = 111;   FV out gain (12) (taken from L9780 test docs)
 * b39-34 = 000110;VCCS capacitance (assumed Rtag ~130 ohm)
 * b33-32 = 00;    measurement clock period 4MHz
 * b31 = 0;        heater short to battery threshold (250mV)
 * b30-24 = 0011001; RCT1 switch time pulse duration (taken from L9780 test docs)
 * b23 = 0;        operation mode (free-running)
 * b22-16 = 0101010; RCT1 bandgap switch pulse duration (taken from L9780 test docs)
 * b15-14 = 10;    SPI confirmation bits - always 0b10
 * b13 = 0;        not used
 * b12-11 = 00;    heater short to battery fault time (80 Tosc)
 * b10-8 = 000;    INRC switch time pulse duration (taken from L9780 test docs)
 * b7 = 0;         protection FET ch2 (disabled)
 * b6 = 1;         protection FET ch1 (enabled)
 * b5-0 = 0;       not used
 */

void setup() {
  Serial.print(F("Initializing uC.............."));
  Serial.begin(serial_baud);          //start serial. Needed for more than just debug

  pinMode(pn_L9780_CS, OUTPUT);       // set the CS pin as an output
  digitalWrite(pn_L9780_CS, HIGH);    // set the CS pin to HIGH (off)
  SPI.begin();                        // initialize the SPI -> library begin function sets output pins

  pinMode(pn_htr_out, OUTPUT);        // heater PWM output
  digitalWrite(pn_htr_out, HIGH);     // turn htr PWM off

  Serial.println(F("Init Complete!"));

  //****display menu
  Serial.println(F("Menu Options"));
  Serial.println(F("--------------------------------------------------------------"));
  Serial.println(F("1)  Init - Send H/W config command to L9780"));
  Serial.println(F("2)  Init - Heatup WBO2 sensor"));
  Serial.println(F("3)  L9780 - Enable VCCS (start operation)"));
  Serial.println(F("4)  L9780 - Enable stgINRC (start closed-loop L9780 control)"));
  Serial.println(F("6)  L9780 - Get status register"));
  //****end display menu
}

void loop() {
  while (Serial.available() == false){} //wait for user input
    int menu_choice = Serial.parseInt(SKIP_ALL);  //get user input
  Serial.println(menu_choice);

  char c[150];                          //char string for menu outputs
  switch (menu_choice){
    case 1:
      L9780_SPI_xfr(LSU49_start_CFG);                   //set initial config values over SPI
      break;
    case 2:
      heatup_WB02();                                    //heat-up sequence
      break;
    case 3:
      L9780_SPI_xfr(LSU49_start_CFG | L9780_VCCS_en);   //enable VCCS (start operating)
      break;
    case 4:
      L9780_SPI_xfr(LSU49_start_CFG | L9780_STGINRC_en);//enable INRCSTG once started
      break;
    case 5:
      {uint64_t data = L9780_get_status(L9780_SO_STAT);   //get current status output
      Serial.print(F("Status Reg (64b): 0x")); SerialPrint_u64(data, true);
      }break;
    default:
      Serial.println(F("Input not recognized, please enter a valid number"));
      break;
  }
  Serial.println(F("--------------------------------------------------------------"));//bookend lines
}

/*  FUNC:   Serial Print unsigned 64b value
 *  DESC:   Fucntion prints an unsigned 64b wide value
 *  ARGS:   v   - value to print
 *          nl  - true/false to print a new line
 *  RETN:   none
 */
void SerialPrint_u64(uint64_t v, bool nl){
  char c[] = "00000000"; //temp byte to print
  sprintf(c,"%08lX", (v>>32)); Serial.print(c);
  sprintf(c,"%08lX", v); Serial.print(c);
  if(nl){Serial.println();}                         //if selected, print newline
  return;
}

/*  FUNC:   WBO2 sensor heatup
 *  DESC:   Fucntion called on sensor initialization
 *          and controlls the initial heatup cycle, including
 *          the condensation and ramp phase.
 *  ARGS:   none
 *  RETN:   none
 *  NOTES:  PWM out from L780 is inverse from arduino output
 */
void heatup_WB02(){
  Serial.println(F("-----Starting Sensor Heatup----"));
  int htr_pwm = 211;
  analogWrite(pn_htr_out, htr_pwm);                 //condensation stage
  Serial.println("---Condensation Phase");
  Serial.print("HTR PWM %: ");Serial.println(htr_pwm*20/51);
  delay(11000);                                     //simplified wait for ~20s total for condensation stage to be done
  Serial.println("---Condensation Phase End");

  htr_pwm = 76;                                     //start ramp phase, start at 70% duty (approx 8.4V)
  while(htr_pwm > 0){                               //increasing by 2/255 every 250ms is approx 0.4V/s for ramp phase
    Serial.print("HTR PWM %: ");Serial.println(htr_pwm*20/51);
    analogWrite(pn_htr_out, htr_pwm);               //set PWM
    delay(250); htr_pwm -= 2;                       //increase/ramp
  }

  Serial.println(F("-----Sensor Heatup Complete----"));
  return;
}

/*  FUNC:   L9780 SPI transfer
 *  DESC:   Fucntion sends a SPI command and receives its result
 *  ARGS:   d   -   data being sent on a SPI transfer
 *  RETN:   spi_buf - data result
 *  NOTES:  Calls "begin transaction" before every send to ensure
 *                  that if another SPI library is being used that updates
 *                  these values, that they're appropriately set for L9780
 */
uint64_t L9780_SPI_xfr(uint64_t d){
  uint64_t spi_buf = d;                             //data to send

    //SPI transfer
    SPI.beginTransaction(SPISettings(L9780_SPI_SPD, L9780_SPI_ORDR, L9780_SPI_MODE)); //start SPI transaction
    digitalWrite(pn_L9780_CS, LOW);                                     // set the CS pin to LOW (on)
  SPI.transfer(&spi_buf,8);                         //pass address of temp data + size (8 bytes for uint64t)
    digitalWrite(pn_L9780_CS, HIGH);                                // set the CS pin to HIGH (off)
    SPI.endTransaction();                                                           //end SPI transaction

  return spi_buf;                                   //return rx'd data from L9780
}

/*  FUNC:   L9780 Function - Get status register
 *  DESC:   Fucntion reads the current status register
 *  ARGS:   act - true/false to select what is in SO
 *                  true - RX'd data (current SI)
 *                  false - status register
 *  RETN:   d - SO register
 *  NOTES:  After sending data, per the datasheet the
 *          next SPI frame will have the associated data
 *          in the SO depdending on the asserted REG bit.
 */
uint64_t L9780_get_status(bool act){
  if(act = L9780_SO_SI){L9780_SPI_xfr(L9780_rx_reg);}//request input reg back
  else{L9780_SPI_xfr(L9780_status_reg);}             //request status reg back
  uint64_t d = L9780_SPI_xfr(L9780_status_reg);      //read result
  return d;
}

The datasheet say maximum 8MHz, it doesn't mean you have to run at 8MHz, in fact since you are using an Uno which has a clock speed of 16MHz, you probably shouldn't run the SPI higher than 4MHz. 2) I don't think your code send the correct command due to Endianness. So instead of defining the L9780_status_reg  as 0xF7FFFFFFFFFFFFFF, defined it with an array L9780_status_reg[] = { 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, this will ensure the MS bit of the MS Byte get send out first with SPI.transfer(L9780_status_reg, sizeof(L9780_status_reg));

@hcheung thanks, some good feedback. I've run some SPI devices capable up around 10MHz before but I never really dug into their library far to see if they were adjusting the prescalar or not; that's a poor assumption on my part, it's never a bad thing to slow it down first so that'll be a good start to check things.

@hcheung Also, thanks for the heads-up on the endianness. That'll be easy to implement and at least provide another known. I had looked into how pointers/addresses worked with big/little endian on the worry I was mixing something up. I wasn't 100% clear on how the endianess worked with a #define that was expanded at compile time  and the SPI.transfer order. That's reason why I used a secondary local variable in the function call with the hope was implementing a local var would alleviate issues. I'll try both and see what happens!

At the suggestion of @hcheung I updated my L9780_SPI_xfr function to shift in the passed 64b word into a uint16_t array and then I also shift that back out into a 64b result. I'm not sure if that's necessarily the most elegant way to do it, but now at least I'm getting expected answers (with one other change).
One other thing that I had mis-understood originally is that this particular chip doesn't really have an "ignore" command so every transmission I need to send the "control word" and then also update the REG bit to set what gets shifted into the SO register for the next SPI frame. After making those two changes I can request the SI register after sending a command and get the same result echo'd back.
I'm still having some issues to chase down but the actual SPI coms appear to be functional now. When requesting the status register, the SPIF1 fault bit is set, which correlates to a "SPI command data length error" when requesting the status register. The datasheet states that the expected length is [64 + n*8] bits which I'm not 100% clear on so I need to do some more digging into that. I'm unsure if the "n*8" part is just a nomenclature thing, or if there's other bits it's expecting beyond the 64b of the control/command register.
EDIT:
As a quick follow-up to this: digging into things a bit I realized that the spreadsheet I had set up for generating my control word was 1bit off (curses!). For the 3 conditions that the "error" in the SPIF[1] bit would be set, none of them are the data errors but since the CB[1,0] bits were shifted, it was causing an issue, thus setting the invalid command / CB error (via SPIF1). I'll update after some further troubleshooting


text:
Not able to control DC motor speed with l298N & pwm pins
I am using arduino uno to control dc motor speed with L298N. But the problem is that the motor is only going at max speed. PWM pin doesn't work for some reason.
I heard many people had some problem but haven't found the solution yet.
code:-
#include <L298N.h>

#define ENA 9
#define IN1 8
#define IN2 7

L298N motor(ENA, IN1, IN2);

void setup() {
// Setup pin mode

//used for display information
  Serial.begin(9600);

}

void loop() {
//Drive Motor Forward
  motor.setSpeed(10);
  motor.forward();
  delay(500);
  motor.setSpeed(100);
  motor.forward();
  delay(500);
  motor.setSpeed(255);
  motor.forward();
  delay(500);

}

I only see the motor move at full speed every time. I connected 5V of Arduino to +12V pin of motor driver and Arduino is powered with my laptop USB.
I am using 4.5V toy dc motor for test - DC motor
What could be wrong here?

The l298n output to the motor has a large voltage drop, and because of that it will not work with 5v. The 5v pin of the arduino can not supply enough current for a motor. What motor is it? Can you give a link to the motor?

added dc motor link, I am using those toy dc motor for the test. It doesn't need much voltage so I though it will be fine.

That is a small motor. With a mosfet driver (no voltage drop) it might work with the 5v pin.

this motor is just for test. Later I want to control 12V high torque motor so for that, I am using this module.

Using 5V pin (!) of an USB-powered Arduino (!!) as a motor power supply (!!!) can easily kill your Arduino.

Similar problem solved: I had a similar problem with the motors running att full speed with analogwrite values higher than 127 and not running at 127 or below.
After some research i found out that only some pins works for pwm reference for analogWrite(), but your ENA is on pin 9, and that should work.

Modifying the library code file L298N.cpp. Insert 2 lines in setSpeed():
void L298N::setSpeed(unsigned short pwmVal)
{ _pwmVal = pwmVal;
  if (_ismoving == true)                   // +++
    analogWrite(_pinEnable, _pwmVal);      // +++
}

Problem solved!

Try to use this code, without the library, and be sure to connect every pin to the correct Arduino output. If everything is okay it should work. Check the tutorial here
int IN3 = 5;
int IN4 = 4;
int ENB = 3;
void setup()
{
 pinMode (ENB, OUTPUT);
 pinMode (IN3, OUTPUT);
 pinMode (IN4, OUTPUT);
}
void loop()
{

  digitalWrite (IN3, HIGH);
  digitalWrite (IN4, LOW);
  analogWrite(ENB,55);
  delay(2000);
  analogWrite(ENB,105);
  delay(2000);
  analogWrite(ENB,255);
  delay(2000);
  analogWrite(ENB,0);
  delay(5000);
}

I did try that code also but didn't work. I think there is problem in the enable pin of driver itself.