I have Connected HC-05 with Arduino UNO I'm sending Integer value Example:
Send Receive
10 10
11 0
15 15
18 2541
Sometime getting correct Data and sometime getting wrong Data.
Global:
//Bluetooth
#define BLUETOOTH_SPEED 9600
SoftwareSerial bluetooth(10, 11);
Setup:
bluetooth.begin(BLUETOOTH_SPEED);
Loop:
if (bluetooth.available() > 0) {
integerValue = 0;
while (bluetooth.available() > 0) {
byte incoming = bluetooth.read();
//Serial.println(incoming);
if (incoming >= '0' && incoming <= '9') {
integerValue = (integerValue * 10) + (incoming - '0');
//delay(5);
}
}
bluetooth.flush();
Serial.println(integerValue);
SoftwareSerial on Arduino is essentially a half-duplex type of communication. You may have dedicated transmit and receive pins, but the same timer is used for transmitting and receiving. So you can't do both transmitting and receiving work on the SoftwareSerial object at the same time.
This part of your code makes me think that you are transmitting something inside some other part of the code.
bluetooth.flush();
If you are, you will have to implement some form of flow control to ensure that you are not transmitting and receiving something on SoftwareSerial object at the same time.
Related
I want to send multibyte integers,(eg. 1000,10000, etc) from raspberry pi to arduino. It can either be in the form of int or string(will convert it into integer on arduino's side) through i2c. Now, I am able to send data but only till 255, If I try to send 1000, the output on ARduino serial terminal will be 232 and not 1000. I tried to search over the internet for like 4-5 hours, but no luck. Can someone please guide me?
import smbus
import time
bus = smbus.SMBus(1)
address = 0x04
a=1000
#a=str(a)
def writeString(a,b,c,d):
bus.write_i2c_block_data(address, a, [b, c, d])
return -1
while True:
try:
writeString(1000,a,5,0)
time.sleep(1) #delay one second
except KeyboardInterrupt:
quit()
Arduino:
#include <Wire.h>
int data [4];
int x = 0;
void setup() {
Serial.begin(9600);
Wire.begin(0x04);
Wire.onReceive(receiveData); //callback for i2c. Jump to void recieveData() function when pi sends data
}
void loop () {
delay(100); //Delay 0.1 seconds. Something for the arduino to do when it is not inside the reciveData() function. This also might be to prevent data collisions.
}
void receiveData(int byteCount) {
while(Wire.available()) { //Wire.available() returns the number of bytes available for retrieval with Wire.read(). Or it returns TRUE for values >0.
data[x]=Wire.read();
x++;
}
Serial.println("----");
Serial.print(data[0]);
Serial.print("\t");
Serial.print(data[1]);
Serial.print("\t");
Serial.print(data[2]);
Serial.print("\t");
Serial.println(data[3]);
// Serial.print("----");
}
I2C sends and receives BYTES. 1000 in hex is 0x3E8. 232 in hex is 0xE8. Only the low byte is sent.
i faced a problem with Arduino Uno and HC-05 Bluetooth.
i will be thankful if anyone could help me.
my problem is that: After uploading program to Arduino Uno successfully and sending commands from (Robotic arm app that was created by android studio) to Bluetooth HC-05, At first the Hc-05 receives data without any problem but after some movements to the arms the HC-05 stop receiving data from app and also Tx & Rx LEDs on Arduino don't work. if i restart Arduino it will work at first and then the same problem will happen.
#include <Servo.h>
Servo arm1;
Servo arm2;
Servo arm3;
Servo arm4;
Servo arm5;
char c = ' ';
String strData = "";
void setup() {
arm1.attach(3);
arm2.attach(5);
arm3.attach(6);
arm4.attach(9);
arm5.attach(10);
arm1.write(0);
arm2.write(0);
arm3.write(0);
arm4.write(0);
arm5.write(90);
Serial.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
while (Serial.available() > 0) {
c = ((byte)Serial.read());
if (c == '?') {
String strDegree = strData.substring(6, strData.length());
int intDegree = strDegree.toInt();
if(strData.indexOf("arm1") >= 0)
arm1.write(intDegree);
if(strData.indexOf("arm2") >= 0)
arm2.write(intDegree);
if(strData.indexOf("arm3") >= 0)
arm3.write(intDegree);
if(strData.indexOf("arm4") >= 0)
arm4.write(intDegree);
if(strData.indexOf("arm5") >= 0)
arm5.write(intDegree);
Serial.println(strData);
strData = "";
break;
}
else {
strData += c;
}
delay(1);
}
}
}
i am waiting to hear something from you.
Best regards.
I hope it's not too late to help: D
Your code is good (Assuming the application you have is also correct)
I think the problem is in the hardware. I think that during the motion of the robot arm motor, there is a significant voltage drop on the arduin and that is why the connection is lost.
Try connecting the HC-05 to a separate power supply (VCC - 3.3-5V, HC-05 GND - Arduino GND - GND external power) and I think your problem will be solved.
I wonder what robot arm you use to integrate with the Arduino? I found a site where there are many robotic arms, but none are compatible with Arduino.
I want to read a byte sent by Bluetooth to the Atmega8 to process it. I found this function online to receive a byte
uint8_t receiveByte()
{
// Wait until a byte has been received
while((UCSRA&(1<<RXC)) == 0);
// Return received data
return UDR;
}
but it doesn't work by say turning a led on if 'a' was sent, so when I changed it and enabled port c to HIGH just before the while loop, and turned it low after it, but port c never gone low - which means this loop is infinite.
so my question is how to fix it or how can I read a byte from Bluetooth module
its atmega8-16pu and I configured it as follows:
/** define the cpu clock frequency*/
#define F_CPU 8000000UL
and fuse = 0xD9C4, from this site http://www.engbedded.com/fusecalc/
I'm trying to talk to an arduino via a rs485 serial link. I have a usb to serial rs485 adapter plugged in my pc and a max485 in the arduino side. To get started i simply uploaded a sketch that send back what it receives.
#include <SoftwareSerial.h>
#define SSerialRX 10 //Serial Receive pin
#define SSerialTX 11 //Serial Transmit pin
#define SSerialTxControl 3 //RS485 Direction control
#define RS485Transmit HIGH
#define RS485Receive LOW
#define Pin13LED 13
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX
void setup()
{
pinMode(Pin13LED, OUTPUT);
pinMode(SSerialTxControl, OUTPUT);
digitalWrite(SSerialTxControl, RS485Receive);
RS485Serial.begin(300);
}//--(end setup )---
void loop()
{
if (RS485Serial.available()){
delay(100);
char x = RS485Serial.read();
digitalWrite(Pin13LED, HIGH);
digitalWrite(SSerialTxControl, RS485Transmit); // Enable RS485 Transmit
Serial.write(x);
RS485Serial.write(x);
Serial.flush();
delay(10);
digitalWrite(SSerialTxControl, RS485Receive); // Disable RS485 Transmit
digitalWrite(Pin13LED, LOW);
delay(200);
}
}//--(end main loop )---
Then, to test the connection, i run a python script in the pc that writes a character to the serial port and listens to the response:
import serial
import time
PORT1 = "/dev/ttyUSB0"
try:
rs485 = serial.Serial(PORT1, 300)
while True:
print 'loop'
rs485.write('r')
time.sleep(0.5)
data = rs485.read()
if data == '\0':
print 'null'
else:
print data
time.sleep(1)
except:
rs485.close()
The first time I launch the script it happens something like this:
giulio#giulio-vaio:~$ python rs485io.py
loop
r
loop
r
loop
^C
If i try to launch again the script, it writes nothing more than:
giulio#giulio-vaio:~$ python rs485io.py
loop
null
loop
null
loop
null
^C
It starts working again only if i reboot my pc (with ubuntu by the way). If i unplug and plug again the usb to serial converter, nothing changes, if i reboot the arduino, same story. I tried the same configuration with a raspberry pi and the result is identical. Changing usb port doesn't work, upload again the same sketch in the arduino, nothing happens.
The led on the pin 13 blinks, so the arduino is receiving and sending something, the serial.read() function returns, so something is arriving, but is (after the first time) a null carachter '\x00'. In one positive case, after rebooting, I tried to let the script go on for a few time and everything went fine, until i hitted ctrl-c and started again the script.
This is dmesg after i plug in the serial converter:
[ 6116.508264] usb 1-2.1.3: new full-speed USB device number 27 using ehci-pci
[ 6116.617247] usb 1-2.1.3: New USB device found, idVendor=1a86, idProduct=7523
[ 6116.617257] usb 1-2.1.3: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[ 6116.617264] usb 1-2.1.3: Product: USB2.0-Serial
[ 6116.617694] ch341 1-2.1.3:1.0: ch341-uart converter detected
[ 6116.621498] usb 1-2.1.3: ch341-uart converter now attached to ttyUSB0
I don't know what to do after this, any help would be appreciated.
EDIT :
the pc doesn't need to be rebooted, it works if i unload and then load again the module ch341, the one that handles the usb converter.
I added two lines at the top of the code:
subprocess.Popen("modprobe -r ch341".split()).wait()
subprocess.Popen("modprobe ch341".split()).wait()
I know it doesn't really solve the problem, but it works.
EDIT 2 :
Looking at the documentation http://lxr.free-electrons.com/source/Documentation/serial/serial-rs485.txt , I tried to send an ioctl signal to the driver, using this code in c (i'm not good with C, so please forgive me)
#include (all the libraries needed)
/* Driver-specific ioctls: */
#define TIOCGRS485 0x542E
#define TIOCSRS485 0x542F
/* Open your specific device (e.g., /dev/mydevice): */
int main(){
const char *file1 = "/dev/ttyUSB0";
const char *file2 = "output_cprog.txt";
int fd = open (file1,O_WRONLY);
if(fd < 0){
printf("%s: %s\n","error opening ttyusb",strerror( errno ) );
}
int fq = open(file2,O_WRONLY);
if( fq < 0){
printf("%s: %s\n","errore apertura file",strerror( errno ));
}
struct serial_rs485 rs485conf;
// Enable RS485 mode:
rs485conf.flags |= SER_RS485_ENABLED;
// Set logical level for RTS pin equal to 1 when sending:
rs485conf.flags |= SER_RS485_RTS_ON_SEND;
// or, set logical level for RTS pin equal to 0 after sending:
rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
// Set rts delay before send, if needed:
rs485conf.delay_rts_before_send = 10;
// Set rts delay after send, if needed:
rs485conf.delay_rts_after_send = 10;
int ioc = ioctl (fd, TIOCSRS485, &rs485conf);
if(ioc < 0){
printf("%i\n",ioc);
printf("ioctl error: %s\n", strerror( errno ));
}
char *character = "f\n";
write(fd,character,2);
char *buffer;
buffer = (char *) malloc(10);
read(fd, buffer, 1);
write(fq, buffer, 1);
printf("received character: %s\n",buffer[0]);
if( close(fd) < 0){
printf("%s: %s\n","error closing port",strerror( errno ));
}
if (close(fq) < 0){
printf("%s: %s\n","error closing file",strerror( errno ));
}
return 0;
}
but compiling and running the program what i see is only this:
giulio#giulio-vaio:~$ ./ioctlRS485.o
-1
ioctl error: Inappropriate ioctl for device
received character: (null)
I think, by looking at the driver https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c that it doesn't have the appropriate function to handle an ioctl at all.
to start off, this might not be a problem with arduino code or arduino, but I figured I would post here because I really just can not figure out what is wrong.
I am working on this project just for fun to send key strokes from the keyboard, through the computer, and out through the USB to my arduino mega. No additional hardware is here, just the computer, the arduino, and the USB cable.
I am using Microsoft Visual Studio Express 2012 to write code to receive key strokes and send them to the USB. This is the code I am using:
#include "stdafx.h"
#include "conio.h"
using namespace System;
using namespace System::IO::Ports;
int main(array<System::String ^> ^args)
{
String^ portName;
String^ key;
int baudRate=9600;
Console::WriteLine("type in a port name and hit ENTER");
portName=Console::ReadLine();
//arduino settings
SerialPort^ arduino;
arduino = gcnew SerialPort(portName, baudRate);
//open port
try
{
arduino->Open();
while(1)
{
int k = getch();
key = k.ToString();
Console::WriteLine(key);
arduino->Write(key);
if (k == 32)
return 0;
}
}
catch (IO::IOException^ e )
{
Console::WriteLine(e->GetType()->Name+": Port is not ready");
}
}
This code works fine, and sends commands to the arduino. I might as well ask this as well, but after 35 key strokes it just stops sending key strokes, I am unsure as to why, but that is not an arduino problem (I don't think).
So when the certain value for key gets sent to the arduino, it changes. For example, the values that are assigned to the variable key for pressing the number 1 and 2 are 49 and 50, respectively. However, when they get sent to the arduino, the values are different some how. 1 is now 57, and 2 is now 48. I am unsure as to why this is happening. I tried 4 and 5 and they both have their values shift down 2 like the key 2. This is the code I have on the arduino:
int ledPin = 13;
int key=0;
int c;
void setup()
{
pinMode(ledPin, OUTPUT); // pin will be used to for output
Serial.begin(9600); // same as in your c++ script
}
void loop()
{
if (Serial.available() > 0)
{
key = Serial.read(); // used to read incoming data
if (key == 57)
{
digitalWrite(ledPin, HIGH);
}
else if (key == 48)
{
digitalWrite(ledPin, LOW);
}
}
c = key;
Serial.println(c);
}
As of right now it is just to switch a light on and off. I am hoping to involve many more keys and having the values be consistent would be very convenient. Anyways, if anyone could help me with why the values are different that would be awesome. I am not completely new to programming but I am certainly no expert and have not gotten too far into advanced stuff.
Thank you for any help or advice.
This has to do with what you are sending through visual studio. You are converting a keypress to its ASCII value, then converting that ASCII value to string, then sending that string through serial. The arduino is expecting a number, not a string.
For example, if you press the 1 key, your visual studio code converts that to an ASCII number 49, which is then converted to string "49", which the Arduino receives - but since you are sending "49", which is a "4" and an "9", the Arduino is reading 9 which corresponds to 57, as you have seen.
Similarly, pressing 2 converts it to "50", and the Arduino reads "0" which corresponds to the value 48 which you were getting.
To fix this, send the number directly, don't convert it into a string.