Hello guys,
I'm finishing my electric longboard project. The only thing left to do is: making mini remote with display that will display speed, amps and battery voltage. Now I am facing some dificultiues with HC-05 modules.
This is what I have done so far:
Configured modules as a master and slave.
Paired them
And tested with some simple code(it works)
There is my code where I get data from my speed controller (Vesc):
So as you noticed I receive these measurements: voltage; current; sspeed; distance and then print them on oled display.
So my plans is to have 2 arduinos and 2 bluetooth modules and send this data remotely.
There is some code for the first arduino(master) and it needs to be finished:
laikiux:
Thanks, but how to adapt it for bluetooth?
Is the communication between the Arduinos and bluetooth modules not serial ? If so you can use SoftSerial on each Arduino to send and receive the data as in Robin's example
Thank you!
Now everything is clearer for me. But I am only able to send and receive integer numbers (0-500).
How to extend the range and transfer float numbers?
speeda = BTserial.read(); // Reads the data from the serial portDespite the comment, what that line does is to read a single byte from the SoftSerial interface. Try sending a single float, say 123.45. What numbers do you get on the slave ?
laikiux:
How to extend the range and transfer float numbers?
Send them with Serial.print() and on the receiving side my tutorial includes an example of how to parse the data and convert to to a float with the atof() functon.
and then the 3rd example in Serial Input Basics will recieve and display the message. You can then adapt and extend the parse example to turn the text into the various float variables
Note that Serial.write() just sends a single byte and Serial.read() only reads a single byte. IIRC a float variable is stored in 4 bytes.
Note also that it is much debug code when you send data in human readable form - as will happen with the above code snippet.
Those 2 lines declare an array of chars ready to hold the received data. You are sending the data so know how many are are expected. Add 1 for the terminating zero that will be added to make the array of chars into a string.
Yes. But you should only call parseData() and subsequently print the data when the variable newData is set to true by recvWithStartEndMarkers(). And after you have printed you need to set newData back to false ready for the next message. Study my example carefully. Notice how I have a showData() function.
Without delay in the end strange things happens (the sequence isn't in the right order). Maybe because arduino and modules can't send and receive data so quickly.
Slave
//BT----------------------------
#include <SoftwareSerial.h>
SoftwareSerial BTserial(10, 11);
//------------------------------
//oled--------------------------
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
//------------------------------
//values-----------------------
float current = 0.0;
float voltage = 0.0;
float sspeed = 0.0;
float distance = 0.0;
//-----------------------------
//receiving data---------------
const byte numChars = 64;
char receivedChars[numChars];
boolean newData = false;
char tempChars[numChars];
//-----------------------------
void setup() {
BTserial.begin(38400);
//OLED
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x64)
display.clearDisplay();
display.setTextSize(1.5);
display.setTextColor(WHITE);
display.setCursor(0,10);
display.println("Startup");
display.display();
delay(1000);
display.clearDisplay();
}
void loop() {
recvWithStartEndMarkers();
showNewData();
}
//-----------------------------------------------------------------------
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (BTserial.available() > 0 && newData == false) {
rc = BTserial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
//-----------------------------------------------------------------------
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars,",");
voltage = atof(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
current = atof(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
sspeed = atof(strtokIndx); // convert this part to a float
strtokIndx = strtok(NULL, ",");
distance = atof(strtokIndx); // convert this part to a float
}
//----------------------------------------------------------------------
void showNewData() {
if (newData == true) {
strcpy(tempChars, receivedChars);
parseData();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.clearDisplay();
display.print(sspeed);
display.setTextSize(1);
display.print("km/h");
display.setCursor(75,17);
display.print(distance);
display.println("km");
display.setCursor(0,17);
display.print("Vol: ");
display.print(voltage);
display.println("V");
display.setCursor(0,25);
display.print("Cur: ");
display.print(current);
display.println("A");
display.display();
newData = false;
}
else
{
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(120,10);
//display.clearDisplay();
display.print(".");
display.display();
}
}