I'm using a bluetooth modul (HC-05) to detect if an android phone is in the modul's range.
I tried to connect with HC-05 (as master) and a PIC16f887 to the phone, but I can't. Searched many pages on net how to use HC-05 as master, but no solution.
So, finally I could do this by modul get my phone's BT name. If it could, my phone is in range.
But now I want my phone to detect this "remote name query" and play some sound then.
Sorry for my poor english :)
Im guessing you want something like this: VIDEO
Lets start with the basics:
The typical default factory settings for a new Bluetooth HC-05 module are:
Default Bluetooth Name: “HC-05”
Default Password: 1234 or 0000
Default Communication: Slave Device
Default Mode: Data Mode
Default Data Mode Baud Rate: 9600, 8, N, 1
Default Command Mode Baud Rate: 38400, 8, N, 1
Default firmware: LINVOR
1. To TEST Bluetooth connections from your android device use id suggest you use this APK
2. Connect the HC-05 BT module as shown in the diagram
3. Initialize the UART receiver at the microcontroller end (side)
(code includes 2 leds for pin 33 and pin 34)
/*
* LAB Number: 17
* LAB Name: Bluetooth Module HC-05 Interfacing (Smartphone -> MCU)
* Author: Khaled Magdy
* For More Information Visit My Website # DeepBlueMbedded.com
*
*/
#include <xc.h>
#include <stdint.h>
#include "config.h"
#define _XTAL_FREQ 4000000
//--[ Control Data ]--
#define Blue_LED_ON 49
#define Blue_LED_OFF 50
#define Yellow_Toggle 51
//--------------------------------
// Functions Declarations
void UART_RX_Init(void);
// Globals
uint8_t UART_Buffer = 0;
//--------------------------------
// Main Routine
void main(void)
{
//--[ Peripherals & IO Configurations ]--
UART_RX_Init(); // Initialize The UART in Master Mode # 9600bps
TRISB0 = 0; // Blue LED (Switch)
TRISB1 = 0; // Yellow LED (Toggle)
RB0 = 0; // Initially OFF
RB1 = 0; // Initially OFF
//---------------------------
while(1)
{
}
return;
}
//--------------------------------
// Functions Definitions
void UART_RX_Init()
{
BRGH = 1; // Set For High-Speed Baud Rate
SPBRG = 25; // Set The Baud Rate To Be 9600 bps
// Enable The Ascynchronous Serial Port
SYNC = 0;
SPEN = 1;
// Set The RX-TX Pins to be in UART mode (not io)
TRISC6 = 1; // As stated in the datasheet
TRISC7 = 1; // As stated in the datasheet
//--[ Enable UART Receiving Interrupts ]--
RCIE = 1; // UART Receving Interrupt Enable Bit
PEIE = 1; // Peripherals Interrupt Enable Bit
GIE = 1; // Global Interrupt Enable Bit
//------------------
CREN = 1; // Enable Data Continous Reception
}
void interrupt ISR (void)
{
if (RCIF == 1)
{
UART_Buffer = RCREG; // Read The Received Data Buffer
// This could have been done within the main loop. Since it's not
// Excessive processing, so it's OK to do it here below
if(UART_Buffer == Blue_LED_ON)
RB0 = 1; // Blue LED ON
if(UART_Buffer == Blue_LED_OFF)
RB0 = 0; // Blue LED OFF
if(UART_Buffer == Yellow_Toggle)
RB1 = ~RB1; // Toggle Yellow LED
RCIF = 0; // Clear The Interrupt Flag
}
}
NOTE The Data Bytes (49, 50, and 51) are the ASCII equivalents for the numeric characters (1, 2, and 3 respectively).
4. Download this apk to send commands to your HC05: APK
For more info follow Reference: LINK
Related
Is there a possibility how to "overcome" BLE MAC address randomization and detect presence of my own Android phone(s)?
I'm looking for a solution how to detect presence of my phone in close-range to ESP32 without installing something like iBeacon app which would drain my battery.
I've started with example for BLE sniffer which works nice but with MAC randomization on Android it is useless.
Then I moved to the solution using emulation of a HID keyboard. After pairing it, it is nicely reconnecting when the phone comes into the range. Once it is connected I can trigger needed action and then I can turn ESP32 Bluetooth off not to be connected whole time. When I need check the phone again I just can turn the server back on. It would be neat solution but... I need to check more (at least two) phones. I've tried to duplicate BLEServers to swith between or run two simoutinasly but without success - either it is not possible or it is exceeding my knowladge about this BLE advertising/pairing/connecting magic.
Third solution would be to have separate ESP for each phone - doable but only as a last resort
Has somebody solved such task somehow already?
For the keyboard solution I'm using this code found online:
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
#include "BLE2902.h"
#include "BLEHIDDevice.h"
#include "HIDTypes.h"
#include "HIDKeyboardTypes.h"
#include <driver/adc.h>
BLEHIDDevice* hid;
BLECharacteristic* input;
BLECharacteristic* output;
BLEAdvertising *pAdvertising;
BLEServer *pServer;
bool connected = false;
bool restart = false;
class MyCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer* pServer){
connected = true;
Serial.println("Connected");
BLE2902* desc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
desc->setNotifications(true);
// NEEDED ACTIONS
}
void onDisconnect(BLEServer* pServer){
connected = false;
Serial.println("DisConnected");
BLE2902* desc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
desc->setNotifications(false);
restart = true;
}
};
void setup() {
Serial.begin(115200);
Serial.println("Starting BLE work!");
BLEDevice::init("Backpack-MeowMeow");
pServer = BLEDevice::createServer();
pServer->setCallbacks(new MyCallbacks());
pServer->getPeerDevices(true);
hid = new BLEHIDDevice(pServer);
input = hid->inputReport(1); // <-- input REPORTID from report map
output = hid->outputReport(1); // <-- output REPORTID from report map
std::string name = "ElectronicCats";
hid->manufacturer()->setValue(name);
hid->pnp(0x02, 0xe502, 0xa111, 0x0210);
hid->hidInfo(0x00,0x02);
BLESecurity *pSecurity = new BLESecurity();
// pSecurity->setKeySize();
pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND);
hid->startServices();
pAdvertising = pServer->getAdvertising();
pAdvertising->setAppearance(HID_BARCODE);
pAdvertising->addServiceUUID(hid->hidService()->getUUID());
pAdvertising->start();
hid->setBatteryLevel(7);
//ESP_LOGD(LOG_TAG, "Advertising started!");
//delay(portMAX_DELAY);
}
void loop() {
if(connected){
delay(10);
}
if (restart) {
restart = false;
pAdvertising->start();
}
delay(50);
}
I am working on connecting an Arduino nano 33 iot to an android app via the Bluetooth capabilities of the iot device. I have seen many resources referring to the use of a Bluetooth module, but no resources about using the nano 33 iot Bluetooth capabilities.
I am wanting to receive data from the Arduino via Bluetooth connection and display it in an android app. I had developed an app that can see the Arduino in a list of Bluetooth devices but am unable to connect to the Arduino due to it not being able to be paired with the phone.
Thanks
Did you found a solution? I think you need to be sure, that you are connect with Bluetooth Low Energy with the Nano Board from Arduino. The way, which is descripted in your posted Tutorial, is not Low Energy. Because of that, you cannot pair.
To connect the Arduino nano 33 IoT via BLE you can use the Demo by Bernardo Giovanni as a template code for your project.
https://www.settorezero.com
*/
// Voltage divider definitions.
// Here I've reported my precise values for R1 (47K) and R2 (33K)
// remember: you cannot apply more than 3.3V on analog input.
// Having a voltage divider with those values (47K and 33K)
// consent to apply on the voltage divider input a maximum of:
// 3.3/VDK = 3.3/0.4125 = 8V
#define R1 46.2F
#define R2 32.86F
#define VDK (R2/(R1+R2))
// since I'm using a 4xAA battery holder and you cannot apply
// less than 5V on Vin pin, I define my "battery full" value as 6V
// and "battery low" value as 5V
#define BAT_FUL 6
#define BAT_LOW 5
// analog pin connected to the voltage divider for battery
// voltage reading
#define AN_BAT A7
#include <ArduinoBLE.h> // Arduino BLE library
#include <Arduino_LSM6DS3.h> // Use Arduino library for the IMU on the Nano 33 IOT
// UUid for Service
const char* UUID_serv = "84582cd0-3df0-4e73-9496-29010d7445dd";
// UUids for accelerometer characteristics (I separated x, y and z values)
const char* UUID_ax = "84582cd1-3df0-4e73-9496-29010d7445dd";
const char* UUID_ay = "84582cd2-3df0-4e73-9496-29010d7445dd";
const char* UUID_az = "84582cd3-3df0-4e73-9496-29010d7445dd";
// UUids for gyroscope characteristics (as above)
const char* UUID_gx = "84582cd4-3df0-4e73-9496-29010d7445dd";
const char* UUID_gy = "84582cd5-3df0-4e73-9496-29010d7445dd";
const char* UUID_gz = "84582cd6-3df0-4e73-9496-29010d7445dd";
// UUid for battery values (bap=percent, ba=voltage)
const char* UUID_bap = "84582cd7-3df0-4e73-9496-29010d7445dd";
const char* UUID_ba = "84582cd8-3df0-4e73-9496-29010d7445dd";
// BLE Service
BLEService myService(UUID_serv);
// BLE Characteristics
BLEFloatCharacteristic chAX(UUID_ax, BLERead|BLENotify);
BLEFloatCharacteristic chAY(UUID_ay, BLERead|BLENotify);
BLEFloatCharacteristic chAZ(UUID_az, BLERead|BLENotify);
BLEFloatCharacteristic chGX(UUID_gx, BLERead|BLENotify);
BLEFloatCharacteristic chGY(UUID_gy, BLERead|BLENotify);
BLEFloatCharacteristic chGZ(UUID_gz, BLERead|BLENotify);
BLEFloatCharacteristic chBAP(UUID_bap, BLERead|BLENotify);
BLEFloatCharacteristic chBA(UUID_ba, BLERead|BLENotify);
void setup()
{
Serial.begin(115200);
uint32_t t=millis();
while (!Serial) // wait 5 seconds for serial connection
{
if ((millis()-t) > 5000) break;
}
bool err=false;
pinMode(LED_BUILTIN, OUTPUT); // onboard led
digitalWrite(LED_BUILTIN, LOW); // led off
// init IMU
if (!IMU.begin())
{
Serial.println("IMU: failed");
err=true;
}
Serial.println("IMU: ok");
// init BLE
if (!BLE.begin())
{
Serial.println("BLE: failed");
err=true;
}
Serial.println("BLE: ok");
// error: flash led forever
if (err)
{
Serial.println("Init error. System halted");
while(1)
{
digitalWrite(LED_BUILTIN, HIGH); // led on
delay(500);
digitalWrite(LED_BUILTIN, LOW); // led off
delay(500);
}
}
// BLE service
// correct sequence:
// set BLE name > advertised service > add characteristics > add service > set initial values > advertise
// Set BLE name
BLE.setLocalName("Settorezero_IMU");
BLE.setDeviceName("Arduino"); // Arduino is the default value on this module
// Set advertised Service
BLE.setAdvertisedService(myService);
// Add characteristics to the Service
myService.addCharacteristic(chAX);
myService.addCharacteristic(chAY);
myService.addCharacteristic(chAZ);
myService.addCharacteristic(chGX);
myService.addCharacteristic(chGY);
myService.addCharacteristic(chGZ);
myService.addCharacteristic(chBAP);
myService.addCharacteristic(chBA);
// add service to BLE
BLE.addService(myService);
// characteristics initial values
chAX.writeValue(0);
chAY.writeValue(0);
chAZ.writeValue(0);
chGX.writeValue(0);
chGY.writeValue(0);
chGZ.writeValue(0);
chBAP.writeValue(0);
chBA.writeValue(0);
// start advertising
BLE.advertise();
Serial.println("Advertising started");
}
void loop()
{
static long preMillis = 0;
// listen for BLE centrals devices
BLEDevice central = BLE.central();
// central device connected?
if (central)
{
digitalWrite(LED_BUILTIN, HIGH); // turn on the onboard led
Serial.print("Connected to central: ");
Serial.println(central.address()); // central device MAC address
// while the central is still connected to peripheral:
while (central.connected())
{
// additional placeholder for writing command from central
// to this device. "myCharacteristic" is a characteristic initialized
// in write mode (BLEwrite) with his own UUid
/*
if (myCharacteristic.written())
{
command = myCharacteristic.value(); // retrieve value sent from central
Serial.print(F("commmand value: "));
Serial.println(command);
}
*/
long curMillis = millis();
if (preMillis>curMillis) preMillis=0; // millis() rollover?
if (curMillis - preMillis >= 10) // check values every 10mS
{
preMillis = curMillis;
updateValues(); // call function for updating value to send to central
}
} // still here while central connected
// central disconnected:
digitalWrite(LED_BUILTIN, LOW);
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
} // no central
}
void updateValues()
{
uint8_t averages=10; // average on this values count (accelerometer and gyroscope)
uint16_t b_averages=500; // average for battery
// accelerometer averaged values/actual values
static float ax=0;
static float ay=0;
static float az=0;
float ax1, ay1, az1;
// gyroscope averaged values/actual values
static float gx=0;
static float gy=0;
static float gz=0;
float gx1, gy1, gz1;
// battery averaged value/actual value
static float anBa=0;
float anBa1;
static uint8_t i_a=0; // accelerometer readings counter
static uint8_t i_g=0; // gyroscope readings counter
static uint16_t i_b=0; // battery readings counter
// read accelerometer values if available
if (IMU.accelerationAvailable())
{
i_a++;
IMU.readAcceleration(ax1, ay1, az1);
ax+=ax1;
ay+=ay1;
az+=az1;
if (i_a==averages) // send average over BLE
{
ax/=averages;
ay/=averages;
az/=averages;
//Serial.println("Accelerometer: "+String(ax)+","+String(ay)+","+String(az));
chAX.writeValue(ax);
chAY.writeValue(ay);
chAZ.writeValue(az);
ax=0;
ay=0;
az=0;
i_a=0;
}
}
// read gyroscope values if available
if (IMU.gyroscopeAvailable())
{
i_g++;
IMU.readGyroscope(gx1, gy1, gz1);
gx+=gx1;
gy+=gy1;
gz+=gz1;
if (i_g==averages) // send average over BLE
{
gx/=averages;
gy/=averages;
gz/=averages;
//Serial.println("Gyroscope: "+String(gx)+","+String(gy)+","+String(gz));
chGX.writeValue(gx);
chGY.writeValue(gy);
chGZ.writeValue(gz);
gx=0;
gy=0;
gz=0;
i_g=0;
}
}
// read battery value
anBa1=analogRead(AN_BAT);
anBa+=anBa1;
i_b++;
if (i_b==b_averages)
{
anBa/=b_averages; // averaged analog value
float voltage=anBa*(3.3/1023); // voltage on pin (if 3.3V => ADC gives 1023)
voltage=voltage/VDK; // real voltage on the voltage divider input = battery voltage
// send voltage in V to BLE
chBA.writeValue(voltage);
/*
Serial.print("Battery: ");
Serial.print(voltage,2);
Serial.print("V (");
*/
// calculate percentual battery
// we must consider BAT_FUL=100% and BAT_LO=0%
// report voltage to range having 0 as lower limit and (BAT_FUL-BAT_LO) as higher limit
// for having percent value
voltage-=BAT_LOW;
voltage/=(BAT_FUL-BAT_LOW);
anBa=voltage*100;
// keep percent value in the range 0-100
if (anBa<0) anBa=0;
else if (anBa>100) anBa=100;
// send % value to BLE
chBAP.writeValue(anBa); // percent voltage
/*
Serial.print(anBa,1);
Serial.println("%)");
*/
i_b=0;
anBa=0;
}
}
There is also a good tutorial about BLE on the Arduino website
https://docs.arduino.cc/tutorials/nano-33-iot/Bluetooth
and an excellent ultimate Android to BLE guide here:
https://punchthrough.com/android-ble-guide/
other really useful guides, tutorials and OS code can be found on the links below:
https://github.com/nenovmy/arduino
https://www.thinker-talk.com/post/bluecard-part-6-controlling-the-arduino-nano-bluetooth-module-from-android-device
I am working on a project for college and I am using android and arduino. The project I am trying to build is a quad copter flight controller in arduino. I have all the necessary equipment for the project but, I've hit a road block with the code I am using. The idea is to have the an android phone control the quad copter and I have a HTTP server on the arduino that can communicate with my phone. The only problem is when I create the required servo motors in the arduino sketch and assign them pins the http server will not run in the setup of the arduino sketch. I have not idea why this is happening and would appreciate any help necessary. Thanks in advance. A copy of my code will be displayed below.
/***************************************************
Adafruit CC3000 Breakout/Shield Simple HTTP Server
This is a simple implementation of a bare bones
HTTP server that can respond to very simple requests.
Note that this server is not meant to handle high
load, concurrent connections, SSL, etc. A 16mhz Arduino
with 2K of memory can only handle so much complexity!
This server example is best for very simple status messages
or REST APIs.
See the CC3000 tutorial on Adafruit's learning system
for more information on setting up and using the
CC3000:
http://learn.adafruit.com/adafruit-cc3000-wifi
Requirements:
This sketch requires the Adafruit CC3000 library. You can
download the library from:
https://github.com/adafruit/Adafruit_CC3000_Library
For information on installing libraries in the Arduino IDE
see this page:
http://arduino.cc/en/Guide/Libraries
Usage:
Update the SSID and, if necessary, the CC3000 hardware pin
information below, then run the sketch and check the
output of the serial port. After connecting to the
wireless network successfully the sketch will output
the IP address of the server and start listening for
connections. Once listening for connections, connect
to the server IP from a web browser. For example if your
server is listening on IP 192.168.1.130 you would access
http://192.168.1.130/ from your web browser.
Created by Tony DiCola and adapted from HTTP server code created by Eric Friedrich.
This code was adapted from Adafruit CC3000 library example
code which has the following license:
Designed specifically to work with the Adafruit WiFi products:
----> https://www.adafruit.com/products/1469
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Limor Fried & Kevin Townsend for Adafruit Industries.
BSD license, all text above must be included in any redistribution
****************************************************/
#include <Adafruit_CC3000.h>
#include <Adafruit_VC0706.h>
#include <SoftwareSerial.h>
#include <SPI.h>
#include "utility/debug.h"
#include "utility/socket.h"
#include <Servo.h>
// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ 3 // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 10
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIVIDER); // you can change this clock speed
#define WLAN_SSID "AndroidAP" // cannot be longer than 32 characters!
#define WLAN_PASS "tyhv5688"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY WLAN_SEC_WPA2
#define LISTEN_PORT 80 // What TCP port to listen on for connections.
// The HTTP protocol uses port 80 by default.
#define MAX_ACTION 10 // Maximum length of the HTTP action that can be parsed.
#define MAX_PATH 64 // Maximum length of the HTTP request path that can be parsed.
// There isn't much memory available so keep this short!
#define BUFFER_SIZE MAX_ACTION + MAX_PATH + 20 // Size of buffer for incoming request data.
// Since only the first line is parsed this
// needs to be as large as the maximum action
// and path plus a little for whitespace and
// HTTP version.
#define TIMEOUT_MS 500 // Amount of time in milliseconds to wait for
// an incoming request to finish. Don't set this
// too high or your server could be slow to respond.
Adafruit_CC3000_Server httpServer(LISTEN_PORT);
Servo m1, m2, m3, m4;
uint8_t buffer[BUFFER_SIZE+1];
int bufindex = 0;
char action[MAX_ACTION+1];
char path[MAX_PATH+1];
int speed = 0;
void setup(void)
{
// Give name to robot
Serial.begin(9600);
Serial.println(F("\nHello, CC3000!\n"));
Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
// Initialise the module
Serial.println(F("\nInitializing..."));
m1.attach(5);
m2.attach(9);
m3.attach(10);
m4.attach(11);
if (!cc3000.begin())
{
Serial.println(F("Couldn't begin()! Check your wiring?"));
while(1);
}
Serial.print(F("\nAttempting to connect to ")); Serial.println(WLAN_SSID);
if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
Serial.println(F("Failed!"));
while(1);
}
Serial.println(F("Connected!"));
Serial.println(F("Request DHCP"));
while (!cc3000.checkDHCP())
{
delay(100); // ToDo: Insert a DHCP timeout!
}
// Display the IP address DNS, Gateway, etc.
while (! displayConnectionDetails()) {
delay(1000);
}
// Start listening for connections
httpServer.begin();
Serial.println(F("Listening for connections..."));
}
void loop(void)
{
// Try to get a client which is connected.
Adafruit_CC3000_ClientRef client = httpServer.available();
if (client) {
Serial.println(F("Client connected."));
// Process this request until it completes or times out.
// Note that this is explicitly limited to handling one request at a time!
// Clear the incoming data buffer and point to the beginning of it.
bufindex = 0;
memset(&buffer, 0, sizeof(buffer));
// Clear action and path strings.
memset(&action, 0, sizeof(action));
memset(&path, 0, sizeof(path));
// Set a timeout for reading all the incoming data.
unsigned long endtime = millis() + TIMEOUT_MS;
// Read all the incoming data until it can be parsed or the timeout expires.
bool parsed = false;
while (!parsed && (millis() < endtime) && (bufindex < BUFFER_SIZE)) {
if (client.available()) {
buffer[bufindex++] = client.read();
}
parsed = parseRequest(buffer, bufindex, action, path);
}
// Handle the request if it was parsed.
if (parsed) {
Serial.println(F("Processing request"));
Serial.print(F("Action: ")); Serial.println(action);
Serial.print(F("Path: ")); Serial.println(path);
// Check the action to see if it was a GET request.
if (strcmp(action, "GET") == 0) {
// Respond with the path that was accessed.
// First send the success response code.
client.fastrprintln(F("HTTP/1.1 200 OK"));
// Then send a few headers to identify the type of data returned and that
// the connection will not be held open.
client.fastrprintln(F("Content-Type: text/plain"));
client.fastrprintln(F("Connection: close"));
client.fastrprintln(F("Server: Adafruit CC3000"));
// Send an empty line to signal start of body.
client.fastrprintln(F(""));
// Now send the response data.
client.fastrprintln(F("Connected"));
}
else if (strcmp(action, "POST") == 0) {
bool start = true;
startMotors(start);
client.fastrprintln(F("HTTP/1.1 200 OK"));
// Then send a few headers to identify the type of data returned and that
// the connection will not be held open.
client.fastrprintln(F("Content-Type: text/plain"));
client.fastrprintln(F("Connection: close"));
client.fastrprintln(F("Server: Adafruit CC3000"));
// Send an empty line to signal start of body.
client.fastrprintln(F(""));
// Now send the response data.
client.fastrprintln(F("Motors are starting"));
}
else {
// Unsupported action, respond with an HTTP 405 method not allowed error.
client.fastrprintln(F("HTTP/1.1 405 Method Not Allowed"));
}
}
// Wait a short period to make sure the response had time to send before
// the connection is closed (the CC3000 sends data asyncronously).
delay(100);
}
client.close();
}
void startMotors(bool start)
{
if(start == true)
{
for (speed = 0; speed<60; speed++)
{
m1.write(speed);
m2.write(speed);
m3.write(speed);
m4.write(speed);
}
}
}
// Return true if the buffer contains an HTTP request. Also returns the request
// path and action strings if the request was parsed. This does not attempt to
// parse any HTTP headers because there really isn't enough memory to process
// them all.
// HTTP request looks like:
// [method] [path] [version] \r\n
// Header_key_1: Header_value_1 \r\n
// ...
// Header_key_n: Header_value_n \r\n
// \r\n
bool parseRequest(uint8_t* buf, int bufSize, char* action, char* path) {
// Check if the request ends with \r\n to signal end of first line.
if (bufSize < 2)
return false;
if (buf[bufSize-2] == '\r' && buf[bufSize-1] == '\n') {
parseFirstLine((char*)buf, action, path);
return true;
}
return false;
}
// Parse the action and path from the first line of an HTTP request.
void parseFirstLine(char* line, char* action, char* path) {
// Parse first word up to whitespace as action.
char* lineaction = strtok(line, " ");
if (lineaction != NULL)
strncpy(action, lineaction, MAX_ACTION);
// Parse second word up to whitespace as path.
char* linepath = strtok(NULL, " ");
if (linepath != NULL)
strncpy(path, linepath, MAX_PATH);
}
// Tries to read the IP address and other connection details
bool displayConnectionDetails(void)
{
uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
{
Serial.println(F("Unable to retrieve the IP Address!\r\n"));
return false;
}
else
{
Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
Serial.println();
return true;
}
}
I 'm not sure of this, but it would seem that you are trying to use pins 5 and 10 both in the motor drivers and the CC3000 shield. You should try to use separate pins for each (e.g. drive the motors with pins 7,8,9,11).
I have battled this issue for a while now and it is driving me nuts:
I am trying to communicate very simply with an Arduino Mega 2560 (via USB as a serial device) from pc running Linux (Knoppix on a usb-dok) when all I am trying to accomplish at this stage is that for each number sent by the laptop to the Arduino, a 'stobe' signal will switch for High to Low or the other way around, and i use this strobe to light turn an LED on and off.
pc side C code:
#include <stdio.h>
int main ()
{
FILE * Device = NULL;
int counter = 0;
Device = fopen("/dev/ttyACM0", "w+");
if(Device == NULL)
{
printf("could not open Device\n");
return -1;
}
while (counter < 10)
{
fprintf(Device, "%d\n", counter);
printf("Sent to Device: %d\n", counter);
counter++;
sleep(2);
}
fclose(Device);
return 0;
}
Arduino code:
int cnt = 0;
int strobe = 0;
int num;
int ValidInput = 0;
char intBuffer[12];
String intData = "";
int delimiter = (int) '\n';
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(3, OUTPUT);
}
int input;
void loop()
{
while(num = Serial.available())
{
delay(5);
// Serial.println(num);
int ch = Serial.read();
if(ch == delimiter)
{
ValidInput = 1;
break;
}
else
{
intData += (char) ch;
}
}
int intLen = intData.length() + 1;
intData.toCharArray(intBuffer, intLen);
intData = "";
int i = atoi(intBuffer);
if(ValidInput)
{
if(i == 0)
{
strobe = 0;
Serial.print("Initializing strobe");
}
else
{
strobe = !strobe;
}
digitalWrite(3, (strobe) ? HIGH : LOW);
Serial.println(i);
ValidInput = 0;
}
}
The problems I am having:
Not sure if fopen is the correct way to communicate with a serial device in Linux, and if so in which mode?
This is the main issue - I am experiencing non-deterministic behavior:
if i run this code right before opening the Arduino editor's 'Serial monitor' it doesn't work as I explained above, instead - it will turn the LED on and then off right away, for each incoming new number.
but once I open the 'Serial monitor' it would act as I want it to - changing the LED's state for each new incoming number.
I am thinking this has something to do with the Arduino's reset or something of that sort.
I looked in many threads here and other forums and couldn't find any solution to this problem.
I'd really appreciate your insight.
First of all, the arduino side looks ok. On the Linux side you need to do some reasearch since the serial communication on posix systems is a little bit more complicated than only opening a file and writing to it. Please use the linux man pages for termios where you can find information on how to setup the communication port parameters and use this document http://tldp.org/HOWTO/Serial-Programming-HOWTO/ for actually learning how to put everything altogether. The serial programming howto will guide you through the process of setting up a port, learning how to control it and learn how to accept input from multiple sources. Also in order to access successfully the serial port from an unprivileged account, you might need to add that user (your user) to a specific group (dialout group in Ubuntu and Fedora). You can search on Google about serial port access under linux and you can fine a lot of code samples ready for you to integrate in your application. You can find an excellent reference and a full documented implementation at the bottom of this thread , also on SO How do I read data from serial port in Linux using C?
A simple fopen doesn't setup any of the serial ports communication parameters. You need to set the baud rate, number of bits, parity, and number of stop bits. And, if you want to use the linux line discipline or not. The termio structure is used to do this.
There are a couple good tutorial on how to use serial between linux and arduinos.
http://chrisheydrick.com/2012/06/12/how-to-read-serial-data-from-an-arduino-in-linux-with-c-part-1/
http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/
I'm trying to control a servo with an android phone and an arduino via bluetooth but the data in the arduino is received as a char, and the arduino doesn't know when all the data is received and the servo don't move properly. The arduino code is this:
#include
Servo myservo;
char val; // variable to receive data from the serial port
int ledpin = 13; // LED connected to pin 48 (on-board LED)
void setup() {
pinMode(ledpin, OUTPUT); // pin 48 (on-board LED) as OUTPUT
Serial.begin(9600); // start serial communication at 9600bps
myservo.attach(9);
}
void loop() {
if( Serial.available() ) // if data is available to read
{
val = Serial.read(); // read it and store it in 'val'
}
if( val - 0 >= 0 && val - 0 <= 180){
}
// Serial.print("Recibido");
delay(100); // wait 100ms for next reading
}
What can I do to get the correct value from "val" to control the servo?
You can send multiple chars if you need them. Simple store each new char into an array and program your android program to send a specific byte that indicates the ending of the val reading.
Checking this "ending" byte each time you perform a read from serial will tell you if this char is to store or to convert the previous stored chars into an integer or whatever data type you need it.
Than simply converting that array will tell you the correct val.