Mobilize a train app BLE

Not sure how to set a variable on my arduino from Blynk. I apologize for reposting, I put this on the announcement because I really need to use blynk to mobilize app over BLE.

am using Adafruit Motor Shield V2 and need to use sliders and switches on Mobile device to control 4 motors.
I need to set the variables for speed and direction of each.
I can make this work with hardwired switches and POTs

I need to create 4 sliders that set a variable from 0-255 to control speed of DC motor. 4 switches that control direction. 1 switch that controls train/trolly mode of the 4th train. and 1 switch that controls a delay if in trolley mode of 30 or 60 seconds.

My current arduino code works with everything described hardwired. I’m hoping to use this new add-on to mobilize this and recreate everything in a mobile interface. Not sure where to start.

The site linked to is just a framework not a completed site. I just threw this up so I could share the code via link instead of loading page down here.

The values are confusing in blynk as it refers to virtual pins…I need to set a variable value from sliders and switches.

Link to my current code that works hardwired

Basically with Blynk you have a choice of two ways of thinking:

  • Wire the widgets directly to the analogue / digital IO pins. This is great for simple logic: press a button to make an LED go on, display an analogue value in a widget.

  • Wire the widgets to virtual pins. In this case Blynk will make sure that when you change the widget in the GUI the arduino is notified, but it’s up to you to make something useful happen after that.

Since your use case is not-quite-trivial you’ll probably need virtual pins. Looking at your code, you want to do something like this:

Adafruit_DCMotor *train = AFMS.getMotor(1);
int speed; 
int direction;
//Create a slider and attach it to pin V1
BLYNK_WRITE(V1) { //will be called whenever V1 changes in the app
  speed = param.asInt();
}
//Create a button and attach it to pin V2
BLYNK_WRITE(V2) { //will be called whenever V2 changes in the app
  direction = param.asInt();
}

void loop()
{
  Blynk.run();
  controlTrain();
}

void controlTrain()
{
  // set direction
  if (direction == 0)
    train->run(FORWARD);
  else
    train->run(BACKWARD);
  // set speed
  train->setSpeed(speed);
}

With a bit of luck / tinkering, the rest of your code could hopefully remain the same. [Though this is untested psuedocode, but I’m sure you get the idea]. I’d suggest starting small (one train, very simple logic) to proove the concept and then take it from there.

2 Likes

Thanks for the start.

After I prove the concept, do you think it’s best to read the values into an array as I’m doing in my current code?

Also, what way do you think is best to keep the hard wired switches and sliders in place. Should I add a switch that I can key on to have the code choose which to use, hardwired or virtual?

Thanks again, I really appreciate your help, I’ve been struggling with this and this may make it easier than writing all the code for BLE from scratch and parsing through a bunch of stuff.

Arrays are always neater :slight_smile: - but it’s entirely up to you!

You could do this. Or you could make it smart so that whichever control was adjusted last wins. You could even make it so that when the physical controls are touched the app updates. Again it’s up to you! Personally I’d probably stick with just one control scheme though :wink:

1 Like

I have something similar, but with Lego trains. I have a make-shift decoder which has an infrared LED attached to it to send signals to the Lego trains. I presume the principle is more or less the same.

I use buttons in Push mode. This way you can have your loop empty and have your program react when a button is pushed instead of putting stuff in the main loop. I think you will run into latency issues in the end or other weird stuff if you do it like this.

int speed; // Global declaration, so you can use this variable anywhere
int direction; // Global declaration

//Create a slider and attach it to pin V1
BLYNK_WRITE(V1) { //will be called whenever V1 changes in the app
  speed = param.asInt();
  controlTrain(direction, speed);
}

//Create a button and attach it to pin V2
BLYNK_WRITE(V2) { //will be called whenever V2 changes in the app
  direction = param.asInt();
  controlTrain(direction, speed);
}

void loop()
{
  Blynk.run();
}

void controlTrain(int direction, int speed)
{
  // set direction
  if (direction == 0)
    train->run(FORWARD);
  else
    train->run(BACKWARD);
  // set speed
  train->setSpeed(speed);
}

This seems a more robust, and elegant way to control your motors :slight_smile: