Arduino analogRead() reset microcontroller - arduino

I am using Atmega328 with arduino bootloader. My whole code is working fine. Now I need to use analogRead() to get ADC values, but as soon as PC see analogRead(), it restart microcontroller. Here is the sample code.
void setup() {
Serial.begin(19200);
while(!Serial);
Serial.println("Setup finish");
delay(200);
}
void loop() {
Serial.println("Reading analong Values");
uint16_t a = analogRead(A0);
Serial.println(a);
delay(1000);
}
The output is,
Setup finish
�Setup finish
�Setup finish
�Setup finish
�Setup finish
�Setup finish
�Setup finish
�Setup finish
�
I also tried to put delay() before and after it but no vain. How to fix it. Thank you.
Update:
I have tried 0 instead of A0, but no vain.
Update:
The problem all boils down to voltage selection(3.3 or 5V) switch on FTDI programmer. Setting it to 5V works perfectly, but switching it to 3.3V, the problem appears again.

From the Arduino site here:
DEFAULT: the default analog reference of 5 volts (on 5V Arduino boards) or 3.3 volts (on 3.3V Arduino boards)
INTERNAL: an built-in reference, equal to 1.1 volts on the ATmega168 or ATmega328 and 2.56 volts on the ATmega8 (not available on the Arduino Mega)
This clearly shows that atmega328 you are using requires an internal reference to 1.1v when reading off the analog inputs. It is probably restarting because when using analogReference(DEFAULT); the atmega328 doesn't know how to properly decode the signal and it crashes out.

Since analogRead only works on analog input pins, it takes the channel number, not a pin number. Try passing 0 rather than A0. It likely fails because A0 has a higher number (as a digital pin) than the number of analog input channels, causing an out of bounds error.

The inductor between power supply 3.3V and AVcc pin was the problem of analogRead() reset. The purpose of this inductor is mentioned here, Inductor purpose. But short-circuiting the inductor clears the problem.

I recommend that instead of writing uint16_t a = analogRead(A0), you should declare the input of A0 as a variable and call it later in the program.Also, there is a mistake in the void setup() section which is that you wrote the while loop with the condition and the ended the line with a semi colon. You should have written the actions that are to be done if the statement is true between curly brackets

Related

Problem with serial communication between Arduino Mega2560 and ESP32

Good morning everyone.
I am trying to establish serial communication between an arduino mega and an esp32, in both I am using hardware serials.
In the arduino the uart3 in the esp the uart2. I have checked the pin connections several times.
I also adapted the arduino's tx signal to the esp32 with a level shifter.
Essentially I need to send a string to the esp32.
The code of the arduino is as follows:
String InvioDatiESP() {
String da_passare = ("hello!!!");
return(da_passare);
}
void setup() {
Serial.begin(9600);
Serial3.begin(115200);
}
void loop() {
Serial3.println(InvioDatiESP());
Serial.println(InvioDatiESP());
delay(1000);
}
I create the string in a function since it is a reduced version of the actual code in which the string is to be composed.
The code of Esp32 is as follows:
#define RXp2 16
#define TXp2 17
void setup() {
Serial.begin(115200);
Serial2.begin(115200, SERIAL_8N1, RXp2, TXp2);
}
void loop() {
Serial.println(Serial2.readString());
}
I correctly set the boudrate in both serial ports on the IDE to verify communication.
The thing I notice that makes me doubt that the problem is related only to the ESP32 reading the string is that in the serial port of the ESP32 in the IDE while the program is running, blank lines are printed on the screen exactly every 1000ms, as if the data is received but not interpreted correctly.
How could I solve this in your opinion?
Thanks in advance for the answers!
SOLVED, the lever shifter was disturbing the signal too much, seen with the oscilloscope, I used a resistive divider and everything works perfectly, thank you all the same!
EDIT: Can you try to lower the boudrate? Check to see if with a lower one it will start decoding properly.
Your problem is not with the code, it's with the hardware. The arduino Mega2560 is using 5V logic level and ESP32 is using 3.3V.
You need to do some level shifting to be able to communicate.
You can take a look at this article to learn more about it.
Hope it helps.

STM32 Blue pill and Arduino IDE

I want to program Stm32 bluepill with Arduino IDE but when I want to define pins like I write " pinMode(A10, OUTPUT)" it gives error. the error is "'A10' was not declared in this scope"
I want to know how should I declare Pins in Arduino IDE for STM32
Based on the error you're reporting, you're not building your code for the correct board. I suspect you're targeting the ArduinoUNO (default) which does not have an A10.
Also, as hcheung's answer mentions, the name on the blue pill is "PA10".
Follow the instructions here to install the board configuration for the STM "blue pill" then select it and build again.
https://maker.pro/arduino/tutorial/how-to-program-the-stm32-blue-pill-with-arduino-ide
Note, the board selection as of today is now "STM32F1 series" instead of "STM32F103C series" as specified at the link.
One reason could be there is not ADC pin of number 10 for the currently selected board (check the board on tool -> boards), there might be fewer number of ADC pins, e.g. try A0.
Or maybe you have selected wrong board. Bluepill isn't included in the Arduino IDE, by default. So you have to add it to your IDE first.
There is a nice instruction here on how to do this and a sample code.
https://maker.pro/arduino/tutorial/how-to-program-the-stm32-blue-pill-with-arduino-ide
Remember that this newly installed library could have small differences in syntax compared with standard Arduino code, Like this example that is taken from the mentioned site:
void setup() {
// change pin PC13
pinMode(PC13, OUTPUT);
}
//infinite loop
void loop() {
digitalWrite(PC13, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(PC13, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
As you can see here the pin is selected using "PC13", and not just a number aka "13".
So in this case by installing the library used in the mentioned site you should write PA0 to PA7 for using ADC.
Here is a sample picture displaying the name of the pins and their features:
For STM32 Blue Pill with Arduino Core, digital pins are named based on its port and pin number, such as PB1, PA10.
There is no A10, I assumed that you mean PA10 (which was marked on the Blue Pill PCB as "A10" (for Port A Pin 10) due to limit space on the PCB.
To use it as a digital pin, simply use PA10 to address it, that is:
pinMode(PA10, OUTPUT);
or because PA10 internally happened to be referred as D10, you can also use:
pinMode(10, OUTPUT); //not recommended
For better understanding of all the pin assignments for STM32F103 Blue Pill, please take a look at the source code here and here.

Android Things I2C read from arduino 3v3

I try to communicate, read and write, from Arduino - slave - to RPi - master - with Android Things.
If i R/W, with a level converter, from RPi to Arduino 5v (16Mhz), everything works fine.
So i decide to eliminate the level converter, and use a 3v3 Arduino mini pro (8Mhz).
The write works fine, but when i try to read from the Arduino, the signal stops.
5v_16Mhz
After the Setup to 9, 0 address, and reads to 9, the signal still low and received the data. No problem.
3v3_8Mhz
After the Setup to 9, 0 address, and read to 9, the signal goes high and the data stop.
I used the same example for the Slave:
#include <Wire.h>
byte RFID[20] = {9,8,7,6,5,4,3,2,1,1,2,3,4,5,6,7,8,9,1,2};
void setup() {
Wire.begin(8); // join i2c bus with address #8
Wire.onRequest(requestEvent); // register event
Wire.onReceive(receiveEvent); // register event
Serial.begin(115200); // start serial for output
pinMode(13, OUTPUT);
}
void loop() {
delay(100);
}
// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent() {
Serial.println("Master ask");
digitalWrite(13, HIGH);
delay(250);
Wire.write(RFID, 20);
digitalWrite(13, LOW);
}
// function should be executes whenever data is received from master
// this function is registered as an event, but it's called every time the RPi
// call the Device.
void receiveEvent(int howMany) {
while (0 < Wire.available()) {
byte RTC_syn = Wire.read(); // receive byte
Serial.println(RTC_syn);
}
}
I really don't know how drives the signal high...
Someone can help me?
If i R/W, with a level converter, from RPi to Arduino 5v (16Mhz), everything works fine.
So i decide to eliminate the level converter, and use a 3v3 Arduino mini pro (8Mhz).
The write works fine, but when i try to read from the Arduino, the signal stops.
This is because level converter you had in the 5V/3.3V version does more than shift the voltage. It also acts as a nice high-impedance buffer between the two devices that helps keep the signal driven and avoids loading effects.
Without the buffer, your bus is likely experiencing a bit of loading. You can try to combat this by adding stronger pull-up resistors. The RPi3 has 1.8k pull-up resistors on the I2C lines, which generally works but can be marginal depending on the input impedance of the slave device. The Arduino Mini has pads to install I2C pull-ups but there are none by default.
The recommended pull-up resistance for a pure 3.3V I2C bus is closer to 1k, so you likely just need to add some stronger pull-ups between SCL/SDA and +3.3V. Anything you add will be in parallel to the RPi3 resistors so factor that into your calculation. For example, adding 4.7k resistors brings the effective resistance down to about 1.3k.
If you are unable to solve it with pull-ups, you can achieve the same buffer effect without level translation by using a line driver IC (random example).
If the level converter works, you should stick with it.
Communication protocols like I2C encode data into a series of logic HIGH and logic LOW signals. What does HIGH / LOW mean? It depends on the devices. For the majority of embedded devices, logic LOW will be ground, 0V.
For Arduinos and Raspberry Pis, the source voltage is different (3.3V versus 5V). This difference can lead to several potential issues.
The 5V signal is too high for the Arduino to handle, causing the Arduino to stop working or reboot
The 3.3V signal is not strong enough to be interpreted as logic HIGH. Embedded devices have circuits that round signals to HIGH/LOW, and the thresholds may not be entirely even. A 5V input may only accept 4.5V or higher, interpreting everything else as LOW or in an indeterminate state.

How can I create a serial and read at a certain frequency on a Teensy

I think my question is more of a lack of comprehension, but here is an overview:
I'm trying to discuss with an old Mitsubishi which uses serial communications. The initialization works by toggling the K-Line at 5 bauds (this technique seems to be used elsewhere), then pass the K-Line as INPUT, read some code, and after that you can read and write directly on the K-Line. The details of said protocol (and the fact that we are only using one line) are detailled here.
This messes me up a bit, since I'm used to a TX pin and an RX pin, not having to switch a pin between TX and RX after each read and write, but let's assume this works.
How can I set up a serial communication (specify baudrate and RX/TX pins, which will be the same here) on a Teensy 3.2 ? (classic Arduino C++ stuff)
Or maybe I can have two pins, each connected to the K-Line. This is physically the same but allow me to define it in software as a standard serial.
Here is the written code so far:
void setup() {
// HERE: SETUP SERIAL WITH ONE PIN
// Or do the two-pins-on-same-wire-thing with HWSerial.begin(15625, SERIAL_8N1);
pinMode(DATA_PIN, OUTPUT);
// MUT Init
int init = MUT_INIT_CODE;
for (int i= 0; i < 9; i++){
if (init & 1){
digitalWrite(DATA_PIN, HIGH);
digitalWrite(LED_PIN, HIGH);
} else {
digitalWrite(DATA_PIN, LOW);
digitalWrite(LED_PIN, LOW);
}
init >>= 1;
delay(MUT_INIT_DELAY);
}
byte answer[3];
pinMode(DATA_PIN, INPUT);
HWSerial.readBytes(answer, 3);
}
Thanks in advance!
Technically you can not tie RX and TX together, because a hardware serial module (like the one inside the Teensy) will drive TX high by default, so RX would be always high as well. You need to configure your pin sometimes as an input, sometimes as an output.
You can not use a hardware serial module because the TX and RX pins are predefined and separate, and you should try using a software serial emulation library like https://www.pjrc.com/teensy/td_libs_AltSoftSerial.html
Try changing the code to add a function to reconfigure your unique pin as an input or output, as needed, and declare the same pin for TX and RX.
edit: a hardware approach would be to use an analog multiplexer like the MAX4619. This way you can use a hardware serial module on the Teensy, connect TX and RX to the multiplexer's X0/X1 pins, and the K-line on the X pin. You can toggle the multiplexer's A command pin with a Teensy GPIO.
I didn't test this approach because I don't have this kind of car, but it might be worth giving it a try.
edit2: to answer more specifically the op's question, the pins of the serial modules of the teensy are hardwired. On a Teensy 3.2, Serial1 is connected to pins 0/1 or 5/21, Serial2 to pins 9/10 or 26/31, etc. The list is available here: https://www.pjrc.com/teensy/td_uart.html
The baud rate is configured by calling Serial1.begin(YOUR_BAUD_RATE);

How to change serial buffer size for Arduino Due?

I've met this problem that Arduino Due takes more time to complete the serial writing than Mega 2560 or Uno.
Here is the code I'm using to test:
int t1,t2;
void setup() {
Serial.begin(115200);
}
void loop() {
t1=micros();
Serial.println("ABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGHABCDEFGH01234567");
t2=micros();
Serial.print("time taken: ");
Serial.println(t2-t1);
delay(500);
}
It takes Arduino Due 5,500 microseconds while it takes Arduino Mega 2560 600 microseconds.
To change the serial buffer size for the Mega, I know the buffer size is defined in the Hardwareserial.h at C:\Arduino\hardware\arduino\avr\cores\arduino. But I could not find the buffer size definition in the corresponding file for the Arduino Due.
Does anyone know how to make the Arduino Due have a faster serial writing speed? We need to transmit the data wirelessly so we could not use the native port although it's very fast.
Thanks!
Well, I was looking for that as well, filesearch revealed:
C:\Arduino\hardware\arduino\sam\cores\arduino\RingBuffer.h - line 28
Having the Arduino 1.5.7 and this works for Arduino Due Programming and Native Port.
for ide 1.6.7 path is:
C:\Users\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.7\cores\arduino

Resources