Programming a buffer using ATMEGA328 - arduino

Im just learning how to use the Arduino, so i bought a Arduino UNO that comes with the ATMega328. And just to start learning i was thinking to use the controller as a buffer:
How would be the code for that? What pins can i use for a RS232 signal?
Thanks a lot.

Uhm... Sorry but.. What? What do you want to do?
If you just want to use it as a buffer you can do this
const int inputPin = 2;
const int outputPin = 1;
void setup() {
pinMode(inputPin, INPUT);
pinMode(outputPin, OUTPUT);
}
// the loop routine runs over and over again forever:
void loop() {
digitalWrite(outputPin, digitalRead(inputPin));
}
But this is absolutely useless.
If you want to start from the beginning start reading the examples provided with the IDE. Starting from the classic example (blink a led).
As for the RS232.. You can't connect to a RS232 signal (because the RS232 signal is a bipolar signal which can range from -15V to 15V). If you want you can convert the RS232 voltage levels to UART levels (0-5V) with an IC (the most famous one is the MAX232).
And then.. You can either connect it to the TX and RX pins (but doing so you exclude the USB port) or to two other pins and then use the SoftwareSerial library.
But usually people use the integrated USB-Serial converter on the board: when you connect the Arduino to the PC your computer detects a new serial port..

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.

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);

Arduino Uno DC Motor not working with simple test. Can not get Arduino to spin the motor

I am using the V2.3 motorsheild on the arduino uno r3.
I no almost nothing about ardunio excpet from what ive read about the past week.
I have been trying to simply turn the motor with the code below and it wont work. I have the arduino plugged into my computer and 12v going to the blue power box thing.
I am using this motor https://www.servocity.com/html/900_rpm_micro_gearmotorblocks.html#.VyELIFaDFBc
I cannot get the dang thing to spin, motor works fine if i wire it straight to the 5v/grnd but not when its in the M1 connection
wiring: https://i.groupme.com/747x1328.png.54a01e30433241d4a99905bd0e8ede2b let meknow if this link doesnt work
Heres an Imgur link for the wiring http://imgur.com/J92ewnu
#include
AF_DCMotor motor(1);
void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
Serial.println("Motor test!");
// turn on motor
motor.setSpeed(200);
motor.run(RELEASE);
}
void loop() {
uint8_t i;
Serial.print("tick");
motor.run(FORWARD);
for (i=0; i<255; i++) {
motor.setSpeed(i);
delay(10);
}
for (i=255; i!=0; i--) {
motor.setSpeed(i);
delay(10);
}
Serial.print("tock");
motor.run(BACKWARD);
for (i=0; i<255; i++) {
motor.setSpeed(i);
delay(10);
}
for (i=255; i!=0; i--) {
motor.setSpeed(i);
delay(10);
}
Serial.print("tech");
motor.run(RELEASE);
delay(1000);
}
I am not expert in current particular shield and its library. But what i see when first time look at your sketch and motor connection image is that you are trying to run dc motor at a certain speed with commands, which seems to be for servo or stepper motors.
You should know that running DC motor at some speed is possible if you have speed calculation based on its current and voltage or when a speed sensor is located at motor's shaft. This motor doesn't have the sensor (i know it for sure, because used same in my projects) and i think the shield can't calculate speed. What you can is only switch it on and off and maybe change its direction.
So, first of all you should look (and use) at the library for such functions.
Looking for what the function you called "AF_DCMotor" does I see how you were confused. There is also this product, which is another adafruit motor sheild.
But it's actually a very different motor driver. Both shields have a power stage which takes pulses and amplifies them to drive a motor. The V2 apparently has a chip which generates these pulses, and you send it serial data to command it using I2C. The V1 just gets these pulses directly from the Arduino.
For yours, a V2 motor shield, try the guide Adafruit provides.
Here's the link - Adafruit Motor Sheild V2 DC motor control
And here's the code
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
AFMS.begin();
myMotor->setSpeed(100);
myMotor->run(FORWARD);
It mentions the use of I2C on the introductory page
Instead of using a latch and the Arduino's PWM pins, we have a fully-dedicated PWM driver chip onboard. This chip handles all the motor and speed controls over I2C
That's why it includes the Wire library. You could make your own code to run this, but it would have to use I2C to send commands to the PWM driver chip they are using.

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