I am trying to take input from the arduino and separate the number inputs into variables speed, length, pause, and then feed those into an analogwrite and delay. I think my goal is fairly straight forward looking at my code but what appears to happen is that the variable I declare isn't stored and therefore my code below my if statements does not execute properly. Any guidance or help problem solving would be great.
The most important thing is a good description of what you want and what you want to type in the Serial Monitor.
Do you put commas between the numbers or spaces or both ? Is there a Carriage Return or Line Feed at the end, or both, or one of the two ?
What you type in the Serial Monitor, let's call that the "protocol".
Without a good description of the protocol, there can be no sketch.
The goal is the have an app send numbers within these ranges and have the app compile the input ranges, which is why I separated the ranges to avoid collisions. So each number is fed to the arduino individually. i then need the arduino to convert the serial strings to ints, and pass those through the if statements to get the new value for each integer (vibeSpeed, vibeStrength, vibePause). Then I need those to accurately process in the last phase with the analogWrite and delays.
Once I've accomplished that I need to manipulate the variables to get the actual speeds I want, for example vibePause = (numVibe*4);
right now when I execute the program and connect my app via BLE the serial monitor shows continuous zeros one at a time on each line. When I send data from my phone the numbers are received and printed in the serial correctly, but the vibrations from the motor are inconsistent, and don't correlate with the variable integers.
EDIT: the serial monitor will also continously write the last variable received by the app. I really am still unsure how BLE works and am stripping an example app and trying to alter it to fit my needs.
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
int motorPin = 2;
int vibeSpeed;
int vibeStrength;
int vibePause;
String vibeState = "";
int numVibe;
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
class MyCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue();
if (value.length() > 0) {
//Serial.println("*********");
// Serial.print("New value: ");
for (int i = 0; i < value.length(); i++)
//Serial.print(value[i]);
vibeState = value.c_str();
//Serial.println(numVibe);
}
}
};
void setup() {
Serial.begin(9600);
BLEDevice::init("Tapper V1.2");
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE);
pCharacteristic->setCallbacks(new MyCallbacks());
pCharacteristic->setValue("");
pService->start();
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
pinMode(motorPin, OUTPUT);
}
void loop() {
numVibe = vibeState.toInt();
if (numVibe >= 300 && numVibe <= 600) {
vibeSpeed = numVibe;
Serial.println(vibeSpeed);
}
if (numVibe >= 1 && numVibe <= 160) {
vibeStrength = numVibe;
Serial.println(vibeStrength);
}
if (numVibe >= 650 && numVibe <= 750) {
vibePause = numVibe;
Serial.println(vibePause);
}
analogWrite(motorPin, vibeStrength);
delay(vibeSpeed);
analogWrite(motorPin, 0);
delay(vibeSpeed);
delay(vibePause);
}
I think that you have to re-write parts of the sketch.
This code will always be executed, regardless if something was received or not:
void loop() {
numVibe = vibeState.toInt();
You should only process a command when a new command was received.
Which Arduino board do you use ? I assume a ESP32.
I suggest to find an example for Bluetooth for the ESP32 and then try step by step to change it for your own needs.
Hey thanks for the input. I am using the Seeed XIAO ESP32C3 and BLE. That shouldn't be an issue for that to be executed every loop because that just converts the serial input to an integer, then numvibe is passed through each if statement to determine which new integer it is converted to. I don't know where else I would put it to make sure that the input is constantly converted from string to int.
Your code is so different from other code, I'm afraid that I can not help any further
I have not used BLE myself, but the other examples that I see have a value that is not empty.
Have you seen this: https://github.com/espressif/arduino-esp32/issues/5560 That code seems similar to your code.
The "value.c_str()" has the whole incoming string. You don't need a for-loop to assign that to a Arduino String 'vibeState'.
Perhaps you could first make a demonstration sketch for the ESP32 that has normal zero-terminates strings, Arduino String and std::string.
Then use a existing working example for BLE.
Them make small changes step-by-step, and keep it working. Don't remove too much.