I am now trying to have my Arduino Uno to output a binary number sent from my mobile phone through bluetooth. The mobile phone would be sending an integer to the Arduino. Hopefully the Arduino converts the integer into binary and turning on corresponding LED. 4 LEDs are used to represent the binary number. However, the LED just flashes once or all the LED turn on when I input a number. Here is my code:
int li1;
const byte numPins = 4;
int pins[] = {10,11,12,13};
void setup () {
Serial.begin(19200);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
}
void loop() {
while(!Serial.available());
li1 = Serial.read();
for (byte i=0; i<numPins; i++) {
byte temp = bitRead(li1, i);
digitalWrite(pins[i],temp);
}
}
li1 is the variable I get from the mobile phone.
Thank you for helping.
Probably not the answer, but do not have enough reputation to leave a comment.
Try setting a sleep after you write the bytes in case its going away to quick.
int li1;
const byte numPins = 4;
int pins[] = {10,11,12,13};
void setup () {
Serial.begin(19200);
pinMode(10,OUTPUT);
pinMode(11,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
}
void loop() {
while(!Serial.available());
li1 = Serial.read();
for (byte i=0; i<numPins; i++) {
byte temp = bitRead(li1, i);
digitalWrite(pins[i],temp);
delay(4000);
}
}
Related
I am doing a project where I need to send data from ultrasonic sensor wirelessly present in one arduino to other arduino where I need these values in Serial monitor. But the problem is I cannot able to send these values through bluetooth. I tried to send one character, it is appearing in serial monitor.. But when I tried to the same for integer values it is not appearing in serial monitor.
I have configured Master and Slave modes for the Bluetooth. I have uploaded the image of the code which I am using to send these values. Please help me on this. Thanks in advance .
code
//# transmitting end
#define trigPin 12
#define echoPin 11
void setup() {
Serial.begin(38400); // Default communication rate of the Bluetooth module
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
long duration;
float distance;
digitalWrite(trigPin, LOW); // Added this line
delayMicroseconds(2); // Added this line
digitalWrite(trigPin, HIGH);
delayMicroseconds(10); // Added this line
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
Serial.println(distance,2); // Sends floatValue
delay(500);
}
//# receving end
#include <SoftwareSerial.h>
#define led 13
SoftwareSerial BTSerial(10, 11);
int data=0;
void setup() {
pinMode(led,OUTPUT);
Serial.begin(38400);
BTSerial.begin(38400); // Default communication rate of the Bluetooth module
}
void loop() {
int number;
if(Serial.available() > 0){ // Checks data is from the serial port
data = BTSerial.read(); // Reads the data from the serial port
//analogWrite(led,data);
delay(10);
//Serial.println(data);
}
Serial.println(data);
}
I need integer values at the serial monitor. But there I am getting some symbols like ?/<>..
From the Arduino reference, Serial.read() only reads the first available byte available in the Serial buffer. As an int is coded on 8 bytes, I would say that you need to read the incoming bytes sequentially in order to get the full value.
Maybe you can implement this by putting (Serial.available() > 0) in a while loop, concatenate the values you get in a char[8] for instance and then convert this char to a integer value.
Also, beware that you are sending floats and not int.
Thanks for the help..!
I modified the code in the receiver end to get the float values from the transmitter.. Here is my modified code
#include <SoftwareSerial.h>
int bluetoothTx = 10;
int bluetoothRx = 11;
String content; //content buffer to concatenate characters
char character; //To store single character
SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);
void setup(){
bluetooth.begin(38400);
Serial.begin(9600);
}
void loop(){
bluetooth();
}
void bluetooth(){ //
while(bluetooth.available()){
character = bluetooth.read();
content.concat(character);
if(character == '\r'){ // find if there is carriage return
Serial.print(content); //display content (Use baud rate 9600)
content = ""; //clear buffer
Serial.println();
}
}
}
I'm trying to set up a serial communication between Arduino and MATLAB over USB. I have this basic code where I'm sending "hello" from MATLAB to Arduino, and I read it back and print it in MATLAB. However, the "hello" sent from Arduino looks like a strange text.
Arduino:
void setup() {
Serial.begin(57600);
Serial.println("ready");
}
void loop() {
String input;
if (Serial.available()) {
char c = Serial.read();
while (c != '\n') {
input += c;
c = Serial.read();
}
Serial.println("I received: " + String(input));
input = "";
}
}
MATLAB:
s = serial('COM3');
set(s, 'BaudRate', 57600);
fopen(s);
pause(1);
first = strtrim(convertCharsToStrings(fgetl(s)));
if first == "ready"
fprintf(s, '%s', 'hello\n');
for i = 1:10
tline = strtrim(convertCharsToStrings(fgetl(s)));
disp(tline);
if size(tline, 2) > 0
fprintf(s, '%s', 'hello\n');
end
end
end
fclose(s);
The output in MATLAB looks like this:
I received: hÿÿÿÿÿÿeÿÿÿÿÿÿÿlÿÿÿÿÿÿÿÿlÿÿÿÿÿÿoÿÿÿÿÿÿÿ
Also, I would appreciate any constructive criticism on improving my code for serial communication. This is my first time, and I'm trying to get a simple setup in which Arduino and MATLAB take turns writing and reading. Thank you.
Your microcontroller code reads faster than you're physically sending characters, so you're reading from an empty buffer. Serial.available() has one char for you, you read it, then you read more chars even though the receive buffer is already empty. Serial.read() will return -1 when there's nothing to read. -1 cast to char is 0xFF, or in Ascii 'ÿ'.
You could change loop() to something like
void loop() {
String input;
while (Serial.available()) {
char c = Serial.read();
if (c != '\n') {
input += c;
} else {
Serial.println("I received: " + String(input));
input = "";
}
}
}
Or you could go with Arduino's Serial.readString():
void setup() {
Serial.begin(57600);
Serial.setTimeout(20);
Serial.println("ready");
}
void loop() {
String input = Serial.readString();
Serial.println("I received: " + input);
}
Both untested, but you get the idea.
I am using ESP8266 and ModbusMaster.h library to communicate with RS485 enabled power meter. Communication works fine but responses are the ones are confusing me and I can not get correct values. My power meter shows 1.49 kWh but response from Modbus is 16318. Here is my code:
#include <ArduinoOTA.h>
#include <BlynkSimpleEsp8266.h>
#include <SimpleTimer.h>
#include <ModbusMaster.h>
#include <ESP8266WiFi.h>
/*
Debug. Change to 0 when you are finished debugging.
*/
const int debug = 1;
#define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
int timerTask1, timerTask2, timerTask3;
float battBhargeCurrent, bvoltage, ctemp, btemp, bremaining, lpower, lcurrent, pvvoltage, pvcurrent, pvpower;
float stats_today_pv_volt_min, stats_today_pv_volt_max;
uint8_t result;
// this is to check if we can write since rs485 is half duplex
bool rs485DataReceived = true;
float data[100];
ModbusMaster node;
SimpleTimer timer;
// tracer requires no handshaking
void preTransmission() {}
void postTransmission() {}
// a list of the regisities to query in order
typedef void (*RegistryList[])();
RegistryList Registries = {
AddressRegistry_0001 // samo potrosnju
};
// keep log of where we are
uint8_t currentRegistryNumber = 0;
// function to switch to next registry
void nextRegistryNumber() {
currentRegistryNumber = (currentRegistryNumber + 1) % ARRAY_SIZE( Registries);
}
void setup()
{
// Serial.begin(115200);
Serial.begin(9600, SERIAL_8E1); //, SERIAL_8E1
// Modbus slave ID 1
node.begin(1, Serial);
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
// WiFi.mode(WIFI_STA);
while (Blynk.connect() == false) {}
ArduinoOTA.setHostname(OTA_HOSTNAME);
ArduinoOTA.begin();
timerTask1 = timer.setInterval(9000, updateBlynk);
timerTask2 = timer.setInterval(9000, doRegistryNumber);
timerTask3 = timer.setInterval(9000, nextRegistryNumber);
}
// --------------------------------------------------------------------------------
void doRegistryNumber() {
Registries[currentRegistryNumber]();
}
void AddressRegistry_0001() {
uint8_t j;
uint16_t dataval[2];
result = node.readHoldingRegisters(0x00, 2);
if (result == node.ku8MBSuccess)
{
for (j = 0; j < 2; j++) // set to 0,1 for two
datablocks
{
dataval[j] = node.getResponseBuffer(j);
}
terminal.println("---------- Show power---------");
terminal.println("kWh: ");
terminal.println(dataval[0]);
terminal.println("crc: ");
terminal.println(dataval[1]);
terminal.println("-----------------------");
terminal.flush();
node.clearResponseBuffer();
node.clearTransmitBuffer();
} else {
rs485DataReceived = false;
}
}
void loop()
{
Blynk.run();
// ArduinoOTA.handle();
timer.run();
}
I have tried similar thing but with Raspberry Pi and USB-RS485 and it works.
Sample of NodeJS code is below. It looks similar to Arduino code.
// create an empty modbus client
var ModbusRTU = require("modbus-serial");
var client = new ModbusRTU();
// open connection to a serial port
client.connectRTUBuffered("/dev/ttyUSB0", { baudRate: 9600, parity: 'even' }, read);
function write() {
client.setID(1);
// write the values 0, 0xffff to registers starting at address 5
// on device number 1.
client.writeRegisters(5, [0 , 0xffff])
.then(read);
}
function read() {
// read the 2 registers starting at address 5
// on device number 1.
console.log("Ocitavanje registra 0000: ");
client.readHoldingRegisters(0000, 12)
.then(function(d) {
var floatA = d.buffer.readFloatBE(0);
// var floatB = d.buffer.readFloatBE(4);
// var floatC = d.buffer.readFloatBE(8);
// console.log("Receive:", floatA, floatB, floatC); })
console.log("Potrosnja u kWh: ", floatA); })
.catch(function(e) {
console.log(e.message); })
.then(close);
}
function close() {
client.close();
}
This code displays 1.493748298302 in console.
How can I implement this var floatA = d.buffer.readFloatBE(0); in Arduino? Looks like that readFloatBE(0) does the trick, but available only in NodeJS / javascript.
Here i part of datasheet for my device
Here is what I am getting as result from original software that came with device:
If someone could point me in better direction I would be thenkfull.
UPDATE:
I found ShortBus Modbus Scanner software and tested readings.
Library read result as Unsigned integer, but need Floating Point and Word Order swapped. It is shown on image below.
Can someone tell how to set proper conversion please.
Right, so indeed the issue is with the part done by var floatA = d.buffer.readFloatBE(0);Modbus returns an array of bytes, and the client has to interpret those bytes, ideally done by the library you're using, but if not available on Arduino, you may try manually with byte decoding functions, with the following considerattions:
Modbus registers are 16 bit in length, so length 1 = 16 bits, length
2 = 32 bits, hence the data type noted on the docs as float32 means
"2 registers used for this value, interpret as float".
Therefore, on client.readHoldingRegisters(0000, 12)you're asking to read the register with address 00, and size 12... so this makes no sense, you only need 2 registers.
On your sample Node code, first you're writing
2 registers to address 5 in client.writeRegisters(5, [0 , 0xffff])
register 5 = 0, and register 6 = 0xFFFF, why? Then you go and read
from address 0, in read(), which is the address for Total KwH per
your docs.
So, you should get an array of bytes, and you need to
decode them as a float. Modbus is Big Endian for words and bytes, so
you need to use those in the decoding functions. I don't know exactly
what is available in Arduino, but hopefully you can figure it out
with this extra info.
I suppose that if you just send the buffer to print, you'll get an integer interpretation of the value, hence the problem
EDIT 2: I got the solution. Anytime someone wants the code I'd be happy to provide. Peace.
Topic:
I'm trying an experiment of echoing strings that I receive in my arduino.
So this is the code so far:
byte byteRead = 0;
bool readable = LOW;
char fullString[50];
int index = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
// State 1
if (Serial.available()) {
readable = HIGH; // flag to enter in the next state when there's nothing else to read
byteRead = Serial.read();
fullString[index] = (char)byteRead;
index++;
}
// State 2
if (readable == HIGH && !Serial.available()){
fullString[index] = '\0'; // '\0' to terminate the string
Serial.println(fullString);
// resets variables
index = 0;
readable = LOW;
}
/**
* Somehow a delay prevents characters of the string from having
* a line printed between them.
* Anyways, when the string is too long, a line is printed between
* the first and second characters
*/
delay(5);
}
Somehow this delay in the end prevents the characters of the string from having a line printed between them, like this:
H
e
l
l
o
Nonetheless, when the string is too long, a line is printed between the first and second characters.
Do you know a better way of doing this?
EDIT: Next time I'd appreciate answers from someone who actually KNOWS programming. Not just condescending idiots.
that's my String Echo
#define MAX_BUFFER_SIZE 0xFF
char buffer[MAX_BUFFER_SIZE];
void setup() {
Serial.begin(115200);
buffer[0] = '\0';
}
void loop() {
while (Serial.available() > 0) {
char incomingByte;
size_t i = 0;
do {
incomingByte = Serial.read();
buffer[i++] = incomingByte;
} while (incomingByte != '\0' && i < MAX_BUFFER_SIZE);
if(i > 0){
delay(1000); /// delay for the echo
Serial.write(buffer, i);
}
}
}
You want to echo the string read, so just echo the input.
void setup() {
Serial.begin(9600);
}
void loop() {
int c = Serial.read();
if (c >= 0) Serial.write(c);
}
I have this pretty simple task to light up an LED for 3 seconds when I send the right password from my Android phone to the Arduino via Bluetooth. Below's the code I am using:
Setting up variables:
int output = 9; //Pin 9 on arduino (LED)
char final[4];
char correct[4] = {'Q','W','E','R'}; //Password is QWER
int pass_true;
void setup() {
pinMode(output, OUTPUT);
Serial.begin(9600);
}
Here's the code in question:
void loop() {
while(Serial.available()){
for(int i=0; i<4; i++){
final[i] = Serial.read();
}
for(int i=0; i<4; i++){
if(final[i]==correct[i]){
pass_true = 1;
}
else{
pass_true = 0;
break;
}
}
}
if(pass_true==1){
digitalWrite(output, HIGH);
Serial.println("ON");
delay(3000);
pass_true = 0;
}
else{
digitalWrite(output, LOW);
}
}
As a newbie I can't see what's wrong with this code. I don't get any response from the arduino when sending the correct password. The LED doesn't turn on, the device doesn't return any Serial.println() string.
I see to it that the electrical part is all good so I'm pretty sure the problem is with the code. I am using Bluetooth spp pro Android app.