#include <SoftwareSerial.h>
#define DEBUG true
SoftwareSerial esp8266(8,9);
void setup()
{
Serial.begin(9600);
esp8266.begin(9600);
pinMode(11,OUTPUT);
digitalWrite(11,LOW);
pinMode(12,OUTPUT);
digitalWrite(12,LOW);
pinMode(13,OUTPUT);
digitalWrite(13,LOW);
pinMode(10,OUTPUT);
digitalWrite(10,LOW);
sendCommand("AT+RST\r\n",2000,DEBUG); // reset module
sendCommand("AT+CWMODE=1\r\n",1000,DEBUG); // configure as access point
sendCommand("AT+CWJAP=\"SSID\",\"PASSWD\"\r\n",3000,DEBUG);
delay(10000);
sendCommand("AT+CIFSR\r\n",1000,DEBUG); // get ip address
sendCommand("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections
sendCommand("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80
Serial.println("Server Ready");
}
void loop()
{
if(esp8266.available()) // check if the esp is sending a message
{
if(esp8266.find("+IPD,"))
{
delay(1000);
int connectionId = esp8266.read()-48; // subtract 48 because the read() function returns
// the ASCII decimal value and 0 (the first decimal number) starts at 48
esp8266.find("pin=");
int pinNumber = (esp8266.read()-48); // get first number i.e. if the pin 13 then the 1st number is 1
int secondNumber = (esp8266.read()-48);
if(secondNumber>=0 && secondNumber<=9)
{
pinNumber*=10;
pinNumber +=secondNumber; // get second number, i.e. if the pin number is 13 then the 2nd number is 3, then add to the first number
}
if((pinNumber==12)&&(pinNumber!=11))
{digitalWrite(12, HIGH);
digitalWrite(11,LOW);}
if((pinNumber==11)&&(pinNumber!=12))
{digitalWrite(12, LOW);
digitalWrite(11,HIGH);}
// build string that is send back to device that is requesting pin toggle
String content;
content = "Pin ";
content += pinNumber;
content += " is ";
if(digitalRead(pinNumber))
{
content += "ON";
}
else
{
content += "OFF";
}
sendHTTPResponse(connectionId,content);
// make close command
// String closeCommand = "AT+CIPCLOSE=";
// closeCommand+=connectionId; // append connection id
// closeCommand+="\r\n";
// sendCommand(closeCommand,1000,DEBUG); // close connection
}
}
}
/*
* Name: sendData
* Description: Function used to send data to ESP8266.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
String sendData(String command, const int timeout, boolean debug)
{
String response = "";
int dataSize = command.length();
char data[dataSize];
command.toCharArray(data,dataSize);
esp8266.write(data,dataSize); // send the read character to the esp8266
if(debug)
{
Serial.println("\r\n====== HTTP Response From Arduino ======");
Serial.write(data,dataSize);
Serial.println("\r\n========================================");
}
long int time = millis();
while( (time+timeout) > millis())
{
while(esp8266.available())
{
// The esp has data so display its output to the serial window
char c = esp8266.read(); // read the next character.
response+=c;
}
}
if(debug)
{
Serial.print(response);
}
return response;
}
/*
* Name: sendHTTPResponse
* Description: Function that sends HTTP 200, HTML UTF-8 response
*/
void sendHTTPResponse(int connectionId, String content)
{
// build HTTP response
String httpResponse;
String httpHeader;
// HTTP Header
httpHeader = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n";
httpHeader += "Content-Length: ";
httpHeader += content.length();
httpHeader += "\r\n";
httpHeader +="Connection: close\r\n\r\n";
httpResponse = httpHeader + content + " "; // There is a bug in this code: the last character of "content" is not sent, I cheated by adding this extra space
sendCIPData(connectionId,httpResponse);
}
/*
* Name: sendCIPDATA
* Description: sends a CIPSEND=<connectionId>,<data> command
*
*/
void sendCIPData(int connectionId, String data)
{
String cipSend = "AT+CIPSEND=";
cipSend += connectionId;
cipSend += ",";
cipSend +=data.length();
cipSend +="\r\n";
sendCommand(cipSend,1000,DEBUG);
sendData(data,1000,DEBUG);
}
/*
* Name: sendCommand
* Description: Function used to send data to ESP8266.
* Params: command - the data/command to send; timeout - the time to wait for a response; debug - print to Serial window?(true = yes, false = no)
* Returns: The response from the esp8266 (if there is a reponse)
*/
String sendCommand(String command, const int timeout, boolean debug)
{
String response = "";
esp8266.print(command); // send the read character to the esp8266
long int time = millis();
while( (time+timeout) > millis())
{
while(esp8266.available())
{
// The esp has data so display its output to the serial window
char c = esp8266.read(); // read the next character.
response+=c;
}
}
if(debug)
{
Serial.print(response);
}
return response;
}
hi i have this code the esp will connect to the internet so that i can turn on or turn off led from a mobile appl i want to change it . i want the esp8266 01 ti be an access point .. i don't want to use the internet i want the phone to connect directly to the esp8266
what changes do i have to do and how can i configure esp8266 as access point
When you initialized the ESP, you configured it in Station Mode
sendCommand("AT+CWMODE=1\r\n",1000,DEBUG);
sendCommand("AT+CWJAP=\"SSID\",\"PASSWD\"\r\n",3000,DEBUG);
In order to configure in AP mode you should replace this with :
sendCommand("AT+CWMODE=2\r\n",1000,DEBUG);
See CWMODE documentation
mode:
1 means Station mode
2 means AP mode
3 means AP + Station mode
Related
I want to send some data (int) to android app, I can do it by writing text in Serial, but I need to send int from code. All I get is "?". I'm not sure what type of data SerialBT.write should I use.
Here is my code:
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32test"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
}
void loop() {
RawValue = analogRead(15);
Voltage = (RawValue / 4096.0) * 3300; // Gets you mV
Amps = ((Voltage - ACSoffset) / mVperAmp);
OdczytNap= analogRead(2);
napiecie=OdczytNap*(3300/4096.0);
napiecie=map(OdczytNap,0,1023,0,5);
SerialBT.write(napiecie);
SerialBT.write(Amps);
if (SerialBT.available()) {
Serial.write(SerialBT.read());
}
delay(20);
}
I'm trying to communicate with an ESP8266 WiFi chip from an Android device using WebSockets to remotely control some motors connected to an Arduino. First I prototyped using a PC & Python & set up a WebSocket server on the ESP8266...
ESP8266_server.ino
#include <ESP8266WiFi.h>
#include <WebSocketsServer.h>
const char* ssid = "SKYNET";
const char* password = "yourdogsauntsmaidenname";
WebSocketsServer webSocket = WebSocketsServer(81);
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t lenght) {
//Serial.printf("[%u] get Message: %s\r\n", num, payload);
switch(type) {
case WStype_DISCONNECTED:
break;
case WStype_CONNECTED:
{
IPAddress ip = webSocket.remoteIP(num);
// Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\r\n", num, ip[0], ip[1], ip[2], ip[3], payload);
}
break;
case WStype_TEXT:
{
//Serial.printf("[%u] get Text: %s\r\n", num, payload);
String _payload = String((char *) &payload[0]);
Serial.print(_payload);
}
break;
case WStype_BIN:
{
hexdump(payload, lenght);
}
// echo data back to browser
webSocket.sendBIN(num, payload, lenght);
break;
}
}
void setup() {
// Set up serial comms
Serial.begin(115200);
// Set up WiFi
WiFi.begin(ssid, password);
while(WiFi.status() != WL_CONNECTED) {
// Serial.print(".");
delay(200);
}
// Serial.println("");
// Serial.println("WiFi connected");
// Serial.println("IP address: ");
// Serial.println(WiFi.localIP());
delay(500);
// Set up web socket
// Serial.println("Start Websocket Server");
webSocket.begin();
webSocket.onEvent(webSocketEvent);
}
void loop() {
webSocket.loop();
}
The WiFi chip is connecetd via a serial connection to an Arduino Mega which in turn parses the data to control some H-bridges for 2 DC motors. The Arduino also relays the data to the Arduino IDE serial monitor.
motor_control.ino
// Serial comms from Wemos EPS8622 to Arduino Mega
#include "SoftPWM.h"
// Outputs to PWM & H bridge direction
// PWMs:
// DC_pwm, left_pwm, right_pwm = 3, 4, 5
int pwm_out[] = {3, 4, 5};
const int num_pwm = sizeof(pwm_out) / sizeof(pwm_out[0]);
// H bridge direction control:
// right_2, right_1, left_2, left_1, dc_2, dc_1 = 6, 7, 8, 9, 10 ,11
int dir_pins[] = {6, 7, 8, 9, 10 , 11};
const int num_dir_pins = sizeof(dir_pins) / sizeof(dir_pins[0]);
// Input buffer from ESP8266
int in_buff[] = {0, 0};
const int num_in_buff = sizeof(in_buff) / sizeof(in_buff[0]);
void setup() {
// Set up serial comms
Serial.begin(115200); // Debug to Serial Monitor
Serial3.begin(115200); // From ESP8266
// Set up PWM pins
SoftPWMBegin();
for (int i = 0; i < num_pwm; i++)
{
SoftPWMSet(pwm_out[i], 0);
}
// Set up H bridge direction pins
for (int i = 0; i < num_dir_pins; i++)
{
pinMode(dir_pins[i], OUTPUT);
digitalWrite(dir_pins[i], LOW);
}
}
void loop() {
// Check input from EPS8266 & send it to the H bridges
while (Serial3.available() < num_in_buff){}
if (Serial3.available()) {
// read the incoming bytes
// in_buff[0] - direction flags
// in_buff[1] - PWM
Serial.println(".......");
Serial.println("In from ESP8266");
for (int i = 0; i < num_in_buff; i++){
in_buff[i] = Serial3.read();
Serial.println(in_buff[i]);
}
Serial.println(".......");
}
// Set direcions on H bridges
Serial.println("Direction pins");
for (int i = 0; i < num_dir_pins; i++)
{
digitalWrite(dir_pins[i], bitRead(in_buff[0], i));
Serial.print("pin ");
Serial.print(dir_pins[i]);
Serial.print(" : ");
Serial.print(digitalRead(dir_pins[i]));
Serial.println();
}
// PWM to motors
for (int i = 0; i < num_pwm; i++)
{
SoftPWMSet(pwm_out[i], in_buff[1]);
}
}
On the PC side I have some Python code that is set up as a WebSocket client that takes user input from the terminal & transmits to the ESP chip.
motor_control_WiFi.py
"""
Motor control over WiFi using Wemos EPS8266 & Mega board
Motor H-bridge direction flags
Both forwards - b'111001, d'57, ASCII 9
Both backwards - b'110110, d'54, ASCII 6
Clockwise (right) - b'111010, d'58, ASCII :
A/Clock (left) - b'110101, d'53, ASCII 5
"""
from ws4py.client.threadedclient import WebSocketClient
import time, requests
import struct
esp8266host = "ws://192.168.1.84:81/"
class DummyClient(WebSocketClient):
def opened(self):
print("Websocket open")
def closed(self, code, reason=None):
print("Connexion closed down", code, reason)
def received_message(self, m):
print(m)
if __name__ == '__main__':
try:
ws = DummyClient(esp8266host)
ws.connect()
print("Ready !")
direction = ""
while direction != "q":
direction = input("Direction: ")
if direction == "f":
payload = "9"
if direction == "b":
payload = "6"
if direction == "r":
payload = ":"
if direction == "l":
payload = "5"
ws.send(payload)
time.sleep(.20)
pwm_out = int(input("PWM: "))
pwm_out = struct.pack('<B', pwm_out)
ws.send(pwm_out)
time.sleep(.20)
print("Finished, close Websocket connexion now and exit script")
ws.send("0:0")
ws.close()
exit()
except KeyboardInterrupt:
ws.send("0:0")
ws.close()
This all works fine. So my next step was to make an Android app to do what my Python code is doing. I'm using the okhttp3 library & added implementation 'com.squareup.okhttp3:okhttp:3.6.0' to the Gradle build file & added internet permissions to the manifest.
MainActivity.java
package qdivision.org.websocketexample;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;
public class MainActivity extends AppCompatActivity {
private Button start;
private TextView output;
private OkHttpClient client;
private final class EchoWebSocketListener extends WebSocketListener {
private static final int NORMAL_CLOSURE_STATUS = 1000;
#Override
public void onOpen(WebSocket webSocket, Response response) {
//webSocket.send("l");
webSocket.send(ByteString.decodeHex("23"));
webSocket.send(ByteString.decodeHex("32"));
webSocket.close(NORMAL_CLOSURE_STATUS, "Goodbye !");
}
#Override
public void onMessage(WebSocket webSocket, String text) {
output("Receiving : " + text);
}
#Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
output("Receiving bytes : " + bytes.hex());
}
#Override
public void onClosing(WebSocket webSocket, int code, String reason) {
webSocket.close(NORMAL_CLOSURE_STATUS, null);
output("Closing : " + code + " / " + reason);
}
#Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
output("Error : " + t.getMessage());
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.start);
output = (TextView) findViewById(R.id.output);
client = new OkHttpClient();
start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
start();
}
});
}
private void start() {
Request request = new Request.Builder().url("ws://192.168.1.84:81").build(); //"ws://echo.websocket.org"
EchoWebSocketListener listener = new EchoWebSocketListener();
WebSocket ws = client.newWebSocket(request, listener);
client.dispatcher().executorService().shutdown();
}
private void output(final String txt) {
runOnUiThread(new Runnable() {
#Override
public void run() {
output.setText(output.getText().toString() + "\n\n" + txt);
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="qdivision.org.websocketexample.MainActivity">
<Button
android:id="#+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Start !"
android:layout_marginTop="40dp"
android:textSize="17sp"/>
<TextView
android:id="#+id/output"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/start"
android:layout_centerHorizontal="true"
android:textSize="16sp"
android:layout_marginTop="30dp"/>
</RelativeLayout>
When this is deployed I dont get any connection errors. The sent bytes are echoed back to the display & the client disconnects with no error. BUT I get no feed back via the Arduino Serial Monitor that anything has been sent!
What's missing here? How come no connection error if the bytes are not being sent/recieved?
Edit #1 I ran the Python code on the Android device from the Termux command line. The code runs, says the socket is open & lets me input direction & PWM but still nothing from the serial monitor.
Edit #2 I can ping the ESP8266 from the Android device using Termux with 0 package loss but still no data being sent by either the Python code or the app.
Edit #3 Python code now works from the Termux command line on the Android device (no idea how I made no changes, it just works now??!!??). The okhttp3 based app still sends no data.
I'm a cocos2dx developer. In this code, server throws error, your data is not a GZIP format. help me on how to convert Gzip Format !
void HelloWorld::requestToserver()
{
string postData ="client side request";
// Setting HTTP Request Header
std::vector<std::string> headers;
vector<string> pHeraders;
pHeraders.push_back("Accept-Encoding:gzip");
pHeraders.push_back("Content-Type:application/json");
pHeraders.push_back("Content-Encoding:gzip");
// Creating a URL
cocos2d::extension::CCHttpRequest * request = new cocos2d::extension::CCHttpRequest();
request->setUrl("http://192.168.1.47:8080/PicL…/PlayerRecordClientInteraction");
// If you want to use GET method, replace kHttpPost to kHttpGet
request->setRequestType(cocos2d::extension::CCHttpRequest::kHttpPost);
request->setResponseCallback(this, httpresponse_selector(HelloWorld::onHttpRequestCompleted));
request->setRequestData(postData, strlen(postData));
request->setHeaders(headers);
request->setTag("POST Request");
// Execute
cocos2d::extension::CCHttpClient::getInstance()->send(request);
// Release the Connection
request->release();
}
void DailyPuzzle::onHttpRequestCompleted(cocos2d::CCNode * sender, void * data)
{
HttpResponse * response = (HttpResponse *)data;
if (!response)
{
return;
}
if (0 != strlen(response->getHttpRequest()->getTag()))
{
CCLog("%s completed", response->getHttpRequest()->getTag());
}
// Check the HTTP Status Code
int statusCode = response->getResponseCode();
char statusString[64] = {};
sprintf(statusString, "HTTP Status Code: %d, tag = %s", statusCode, response->getHttpRequest()->getTag());
CCLog("response code: %d", statusCode);
// A connection failure
if (!response->isSucceed())
{
CCLog("response failed");
CCLog("error buffer: %s", response->getErrorBuffer());
return;
}
// The data will be placed in the buffer.
std::vector<char> * buffer = response->getResponseData();
char * concatenated = (char *) malloc(buffer->size() + 1);
std::string s2(buffer->begin(), buffer->end());
strcpy(concatenated, s2.c_str());
}
I am doing some works with Texas Instruments SensorTag CC2541. I am trying to show the temperature data in the advertising packets.
First, I implemented the temperature service UUID in the advertising data packet. This is done in the SensorTag.c firmware (using IAR Workbench for 8051).
static uint8 advertData[] =
{
// Flags; this sets the device to use limited discoverable
// mode (advertises for 30 seconds at a time) instead of general
// discoverable mode (advertises indefinitely)
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
0x03,
GAP_ADTYPE_16BIT_MORE,
LO_UINT16(IRTEMPERATURE_SERV_UUID),
HI_UINT16(IRTEMPERATURE_SERV_UUID)
};
And here is the Scan Response Array:
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8 scanRspData[] =
{
// complete name
0x0A, // length of this data
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
0x53, // 'S'
0x65, // 'e'
0x6E, // 'n'
0x73, // 's'
0x6F, // 'o'
0x66, // 'f'
0x74, // 't'
0x69, // 'i'
0x61, // 'a'
// connection interval range
0x05, // length of this data
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
0x03,
GAP_ADTYPE_16BIT_MORE,
LO_UINT16(IRTEMPERATURE_SERV_UUID),
HI_UINT16(IRTEMPERATURE_SERV_UUID)
};
Then, I use a sample Bluetooth Low Energy GAT application and modify it to show the data when it is scanning. The original app was used for another beacon device and it showed the beacon name + RSSI + thermometer service when scanning.
Here is the original code:
class TemperatureBeacon {
/* Full Bluetooth UUID that defines the Health Thermometer Service */
public static final ParcelUuid THERM_SERVICE = ParcelUuid.fromString("00001809-0000-1000-8000-00805f9b34fb");
/* Short-form UUID that defines the Health Thermometer service */
private static final int UUID_SERVICE_THERMOMETER = 0x1809;
private String mName;
private float mCurrentTemp;
//Device metadata
private int mSignal;
private String mAddress;
/* Builder for Lollipop+ */
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public TemperatureBeacon(ScanRecord record, String deviceAddress, int rssi) {
mSignal = rssi;
mAddress = deviceAddress;
mName = record.getDeviceName();
byte[] data = record.getServiceData(THERM_SERVICE);
if (data != null) {
mCurrentTemp = parseTemp(data);
} else {
mCurrentTemp = 0f;
}
}
/* Builder for pre-Lollipop */
public TemperatureBeacon(List<AdRecord> records, String deviceAddress, int rssi) {
mSignal = rssi;
mAddress = deviceAddress;
for(AdRecord packet : records) {
//Find the device name record
if (packet.getType() == AdRecord.TYPE_NAME) {
mName = AdRecord.getName(packet);
}
//Find the service data record that contains our service's UUID
if (packet.getType() == AdRecord.TYPE_SERVICEDATA
&& AdRecord.getServiceDataUuid(packet) == UUID_SERVICE_THERMOMETER) {
byte[] data = AdRecord.getServiceData(packet);
mCurrentTemp = parseTemp(data);
}
}
}
private float parseTemp(byte[] serviceData) {
/*
* Temperature data is two bytes, and precision is 0.5degC.
* LSB contains temperature whole number
* MSB contains a bit flag noting if fractional part exists
*/
float temp = (serviceData[0] & 0xFF);
if ((serviceData[1] & 0x80) != 0) {
temp += 0.5f;
}
return temp;
}
public String getName() {
return mName;
}
public int getSignal() {
return mSignal;
}
public float getCurrentTemp() {
return mCurrentTemp;
}
public String getAddress() {
return mAddress;
}
#Override
public String toString() {
return String.format("%s (%ddBm): %.1fC", mName, mSignal, mCurrentTemp);
}
}
As you can see, the program uses the THERM_SERVICE UUID (00001809-0000-1000-8000-00805f9b34fb) and its short form (0x1809). I tried to modify it with the SensorTag IR Temperature UUID service (F000AA00-0451-4000-B000-000000000000). And the result is that, it cannot show neither the name of the scanned device nor the temperature data.
Can you give some suggestions for this problem? Thank you!
The missing part in your question is the scan response structure in your modified SensorTag code. The advertData only notifies the central (iOS) of it's presence and available services (temperature). The scan response may carry more information, such as the value of the temperature. Could you post the scan response array?
I'm wondering if anybody can help me figure out what is causing the data I am sending to become corrupt.
My setup is currently an Arduino pro mini with a HM-10 bluetooth module connected (I have also tried HM-11 Module too) and an Android application to receive the bluetooth data.
Module setup: http://letsmakerobots.com/node/38009
If I send data with big enough intervals then the data is fine, but if I send the data continuously I see messages getting mixed up and lost. To test this I send "$0.1,0.2,0.3,0.4,0.5" to the Android application from the Arduino, sometimes the stream of data appears to send fine but other times it is really quite scrambled. Please see the below graphs that demonstrate this:
Good case:
Bad case:
Arduino code:
String inputString = ""; //Hold the incoming data.
boolean stringComplete = false; //Determines if the string is complete.
boolean realtime = false;
void setup()
{
Serial.begin(9600);
delay(500);
Serial.print("AT+START");
delay(500);
}
void loop()
{
if(stringComplete)
{
if(inputString.equals("rStart"))
{
Serial.println("$startACK");
realtime = true;
}
else if(inputString.equals("stop"))
{
Serial.println("$stopACK");
realtime = false;
}
else{
Serial.print(inputString);
}
inputString = "";
stringComplete = false;
}
if(realtime)
{
Serial.println("$0.1,0.2,0.3,0.4,0.5,0.6");
delay(10);
}
}
void serialEvent() {
while (Serial.available())
{
// get the new byte:
char inChar = (char)Serial.read();
if (inChar == '\n')
{
stringComplete = true;
}
else
{
inputString += inChar;
}
}
}
The Android side just receives the data and then parses it in an IntentService:
#Override
protected void onHandleIntent(Intent intent) {
//Incoming command.
String rawData = intent.getStringExtra(DataProcessingIntentService.REQUEST);
//Append our new data to our data helper.
Log.i(this.getClass().getName(), "Previous Raw: (" + DataProcessingHelper.getInstance().getData() + ")");
DataProcessingHelper.getInstance().appendData(rawData);
Log.i(this.getClass().getName(), "New Raw: (" + DataProcessingHelper.getInstance().getData() + ")");
commandStartIndex = DataProcessingHelper.getInstance().getData().indexOf("$");
commandEndIndex = DataProcessingHelper.getInstance().getData().indexOf("\n");
//Set this as the data starting point.
if(commandStartIndex != -1){
DataProcessingHelper.getInstance().offsetData(commandStartIndex);
}
//Ensure that a command has been found and that the end index is after the starting index.
if(commandStartIndex != -1 && commandEndIndex > commandStartIndex){
//Remove the command structure from the command.
command = DataProcessingHelper.getInstance().getData().substring(commandStartIndex+1, commandEndIndex-1); //Remove the \r\n end command.
DataProcessingHelper.getInstance().offsetData(commandEndIndex+1);
if(command.length() > 1){
//Split the data out of the comand.
splitData = command.split(",");
Log.i(this.getClass().getName(), "Broadcasting the processed data. (" + command + ")");
//Broadcast data.
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(DataProcessingIntentService.RESPONSE);
broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
broadcastIntent.putExtra(DataProcessingIntentService.RESPONSE, splitData);
sendBroadcast(broadcastIntent);
}else{
Log.e(this.getClass().getName(), "Command is less than 1 character long!");
}
}
}
Thank you for any help!
I have now figured out what was causing this problem. It appears that BLE only supports a maximum of 20 bytes per a transaction. The time between these transactions is different depending on what you are using. I'm currently using notifications which means that I can send 20 bytes every 7.5 milliseconds maximum. I have opted for 10 milliseconds to be safe. I will now need to look into breaking up packets into 20 bytes maximum to ensure no data corruption.