Homemade Bluetooth Auto-start Still Trucking!

start

Well, after a year of service, thousands of miles, and a full fall, winter, spring, and summer, my home made Bluetooth auto-start is still trucking! It’s been really convenient as the weather once again turns cold to pull out my phone, press start, and hear my truck fire up!

There was, however, one blip along the way. several months ago, one of the relays inside the control unit failed. It was simple enough to replace, and within a few minutes, the whole ordeal was over. I don’t think that was a design flaw (not that my design is perfect), but rather a part issue with using cheap relays. The relay that I replaced has worked flawlessly since, and none of the other relays failed, either, leading me to believe it was just a defect in that particular relay.

image20180719_054103226

Linux – keep it simple.

BlueFruit Project: Fixed Erratic Crank Behavior

Another problem that I have run into while working with this Bluetooth auto start is an erratic crank behavior. Per the code, it should not start the crank circuit if the engine is already running. However, on 2 occasions, it happened anyways. I was not plugged in with a laptop at the time, so I don’t know what the issue was, and I can’t go back in time to hook up and review the logs.

IMG_20180723_071854

Notice that the white auto start box is gone. I’ve relocated it to the glove box.

I plugged in the laptop and went through the functions and processes again. The only thing I can come up with is if the “runbool” flag did not get set somehow, and it didn’t believe that the truck was running. So, I decided to add yet another layer of safety.

Here is what I came up with:

 

@@ -174,16 +174,16 @@ void loop(void) {


if (startTimer == 0 && startAttempts > 0) {

if (voltVoltage >= 0.9) {

// Turn everything off because it is running.

// Turn everything to a run state because it is running.

// I had to add this as a safety. Once or twice this cranked when it shouldn’t have,

// before this code existed. Now it can’t crank without checking first!

digitalWrite(16, LOW);

digitalWrite(15, LOW);

digitalWrite(7, HIGH);

digitalWrite(11, HIGH);

digitalWrite(7, LOW);

digitalWrite(11, LOW);

crankTimer = -1;

startTimer = -1;

runTimer = -1;

runTimer = 600; // We are here because something messed up, but set the clock to 10 minutes.

startAttempts = -1;

Serial.println(” Already running! “);

} else {
… …
@@ -194,7 +194,7 @@ void loop(void) {

Serial.println (” crankTimer ON “);

}

} else if (startTimer == 0 && startAttempts == 0) {

// Turn everything off from to many attempts.

// Turn everything off from too many attempts.

digitalWrite(16, LOW);

digitalWrite(15, LOW);

digitalWrite(7, HIGH);
… …
@@ -220,7 +220,7 @@ void loop(void) {

Essentially, I am just running one last voltage check right before turning on the cranking power. If the voltage is above 13 volts, the engine must be running, so I don’t want to crank.

Using voltage this way is somewhat risky, because it is possible that the charging circuit of the car is not working, and voltage has depleted, causing the cranking circuit to engage the already running motor that just isn’t charging the battery. That is why I would like to pursue some sort of tachometer sensor input.

Until then, I think this will keep me (relatively) safe, as long as the vehicle charging system works properly.

Linux – keep it simple.

BlueFruit Project: Low voltage safety

IMG_20180720_100112Having tested out the Bluetooth auto start for a little while through regular use, I came to an interesting conundrum. What should the auto start do if the voltage is too low? I “hemmed and hawed” about this for a while and here are my thoughts:

  • If the vehicle is already running, should we shut it off when the voltage gets to low? No, because turning it off will not help the driver in any way (except to alert them to an issue) but they may want it to stay on.
  • If the vehicle has not started yet, should it attempt at all? Yes, we should make at least one start attempt, so that the alternator can kick in and charge the battery.
  • If the vehicle failed to start, should we try again with a low battery? No, I suppose they should manually start the vehicle to ensure cranking goes properly.

With those three thoughts in mind, here is what I came up with:

if (crankTimer == 0) {
digitalWrite(15, LOW);
digitalWrite(11, HIGH);
if (runBool) {

crankTimer = -1;

startTimer = -1;

startAttempts = -1;

runTimer = 600; // 600 seconds = 10 minutes of run time before shutdown.

Serial.println (” crankTimer OFF, runTimer started. “);

} else {

crankTimer = -1;

startTimer = 5; // To start process again.

runTimer = -1;


startAttempts = startAttempts -1;

if (voltVoltage <= 0.5) {

// Voltage is too low to try again!

startTimer = -1;

Serial.println (” Voltage LOW! “);

} else {

startTimer = 5; // To start process again.

}

runTimer = 600; // 600 seconds = 10 minutes of run time before shutdown.

Serial.println (” Not running, try again… “); Serial.println(startAttempts);

}

So it will attempt one start, but not multiple starts. What do you think? Is that reasonable?

Linux – keep it simple.

Bluetooth Breakdown: Sending gatttool commands from my Ubuntu Touch Phone!

Here I am, typing commands from my phone and controlling a Bluetooth Feather!

Of course, the moment of truth! The goal of this whole Bluetooth breakdown project was to figure out how to make my home made auto start work on my Ubuntu Touch phone. Well, here it is, working!

Although the interface could use a face lift.

Last we looked at this, we saw that we could write custom scripts to send the commands from the desktop computer to the BLE auto start, or use interactive mode of gatttool and do the work there. Now we can actually do the same from the terminal of the cell phone.

While this technically counts. We now need a snazzy program that just works with clicky buttons and that sort of thing. So, I suppose that will be the next phase of this project! Stay tuned for adventure!

Linux – keep it simple.

Bluetooth Breakdown: Sending my own commands with gatttool

Yes, there is purposely one too many t’s in GattTool.

bt_success

Last time we looked at the Bluetooth Low Energy (BLE) packets being sent from my Android app to my home made auto start. Here’s what we saw:

214231313a – Button 1 pressed
214231303b – Button 1 released
2142323139 – Button 2 pressed
214232303a – Button 2 released

With a little more digging, I also found that the “handle” is important, and per the Bluetooth packet breakdown in WireShark, that handle is 0x001a. Further, my particular Bluetooth feather’s MAC address is F4:64:8E:90:D8:C3.

With all of this in mind, I entered gatttool in the interactive mode, but I kept having trouble connecting to my device. With further research, I found an article on WordPress by a guy named Jack. He got me pointed in the right direction!

What I needed to do before connecting was this:

# btmgmt le on
# btmgmt bredr off

To set the computer’s Bluetooth manager to the proper Low Energy reading/writing state. Then I entered interactive mode while monitoring my auto start with a USB serial monitor. Here’s what I typed:

root@alaskalinuxuser-OptiPlex-7010:/home/alaskalinuxuser# gatttool -t random -b F4:64:8E:90:D8:C3 -I
[F4:64:8E:90:D8:C3][LE]> connect
Attempting to connect to F4:64:8E:90:D8:C3
Connection successful
[F4:64:8E:90:D8:C3][LE]> char-write-cmd 0x001a 214231313a
[F4:64:8E:90:D8:C3][LE]> char-write-cmd 0x001a 214231303b
[F4:64:8E:90:D8:C3][LE]> char-write-cmd 0x001a 2142323139
[F4:64:8E:90:D8:C3][LE]> char-write-cmd 0x001a 214232303a
[F4:64:8E:90:D8:C3][LE]> char-write-cmd 0x001a 214232303a
[F4:64:8E:90:D8:C3][LE]> char-write-cmd 0x001a 214231303b
[F4:64:8E:90:D8:C3][LE]> char-write-cmd 0x001a 2142323139
[F4:64:8E:90:D8:C3][LE]> char-write-cmd 0x001a 214232303a
[F4:64:8E:90:D8:C3][LE]> char-write-cmd 0x001a 2142323139
[F4:64:8E:90:D8:C3][LE]> disconnect

(gatttool:22352): GLib-WARNING **: Invalid file descriptor.

[F4:64:8E:90:D8:C3][LE]> disconnect
[F4:64:8E:90:D8:C3][LE]> exit
root@alaskalinuxuser-OptiPlex-7010:/home/alaskalinuxuser#

And here is what I saw on the monitor:

Less than 13v, Pin A3: 0.00
Less than 13v, Pin A3: 0.00
Less than 13v, Pin A3: 0.00
Less than 13v, Pin A3: 0.00
Button 1 released
Less than 13v, Pin A3: 0.00
startTimer 4
Less than 13v, Pin A3: 0.00
startTimer 3
Less than 13v, Pin A3: 0.00
startTimer 2
Less than 13v, Pin A3: 0.00

Success! Great! I was able to enter interactive mode, connect, and send the right commands! This is great!

Then I switched to non-interactive mode, by writing a custom script or two. This is the first one, to start the auto start:

#!/bin/bash

btmgmt le on
btmgmt bredr off
gatttool -t random -b F4:64:8E:90:D8:C3 –char-write-req -a 0x001a -n 214231313a
gatttool -t random -b F4:64:8E:90:D8:C3 –char-write-req -a 0x001a -n 214231303b
#gatttool -t random -b F4:64:8E:90:D8:C3 –char-write-req -a 0x001a -n 2142323139
#gatttool -t random -b F4:64:8E:90:D8:C3 –char-write-req -a 0x001a -n 214232303a
exit 0

And one to stop the auto start:

#!/bin/bash

btmgmt le on
btmgmt bredr off
#gatttool -t random -b F4:64:8E:90:D8:C3 –char-write-req -a 0x001a -n 214231313a
#gatttool -t random -b F4:64:8E:90:D8:C3 –char-write-req -a 0x001a -n 214231303b
gatttool -t random -b F4:64:8E:90:D8:C3 –char-write-req -a 0x001a -n 2142323139
gatttool -t random -b F4:64:8E:90:D8:C3 –char-write-req -a 0x001a -n 214232303a
exit 0

And a quick test was successful! Now I can send my commands to start or stop the auto start from the command line with my computer. Now it’s just time to set it up on my Ubuntu Touch phone!

Linux – keep it simple.

Bluetooth Breakdown?

So, in the continuing saga of learning about Bluetooth, I am breaking down some transmissions of Bluetooth signal from my Android phone to the Bluetooth auto start that I built.

btauto

  1. On my Android phone, I went to Settings -> Developer Options -> Enable Bluetooth HCI snoop log. Now my Android phone was creating a dump file on the sdcard of all Bluetooth traffic.
  2. I opened my app, connected to the auto start, and promptly started the truck, and shut it down. Then I waited about 3 seconds, started the truck, and shut it down. Then I disconnected and reconnected 4 times to the auto start.
  3. I turned off the Bluetooth snoop log and then transferred the file to my computer for analysis.
  4. Finally, I opened the file with WireShark, and started reviewing the packets.

From what I understand, the ATT protocol is one that sends and receives actual commands to and from the controlling application to the BLE board itself. So, I sorted the output and looked specifically at the ATT protocol packets.

Further research has lead me to believe that I need to look for btatt.opcode, particularly 0x52, which is for the write command. I found 8 packets that held this special designation.

btauto1

In these packets are values. In order of appearance, they are:

21:42:31:31:3a
21:42:31:30:3b
21:42:32:31:39
21:42:32:30:3a
21:42:31:31:3a
21:42:31:30:3b
21:42:32:31:39
21:42:32:30:3a

Which would correspond to my bluetooth device code of:

// Buttons
if (packetbuffer[1] == ‘B’) {
uint8_t buttnum = packetbuffer[2] – ‘0’;
boolean pressed = packetbuffer[3] – ‘0’;
Serial.print (“Button “); Serial.print(buttnum);
if (pressed) {
Serial.println(” pressed”);
//bluart.print(“pressed”);
analogWrite(19, 50);
} else {
Serial.println(” released”);
analogWrite(19, 0);
}
if (buttnum == 1) {
// Turn on vehicle, by turning on accessory, fuel pump,
// and start timer to crank.
digitalWrite(7, LOW);
digitalWrite(16, HIGH);
startTimer = 5; // Delay time before cranking.
startAttempts = 3; // Number of tries to start.
} else if (buttnum == 2) {
// Turn everything off from the button.
digitalWrite(16, LOW);
digitalWrite(15, LOW);
digitalWrite(7, HIGH);
digitalWrite(11, HIGH);
crankTimer = -1;
startTimer = -1;
runTimer = -1;
startAttempts = -1;
Serial.println(” Kill All – Button pressed. “);
}
}

That’s right! Now we can interpret the signals!

21:42:31:31:3a – Button 1 pressed!
21:42:31:30:3b – Button 1 released!
21:42:32:31:39 – Button 2 pressed!
21:42:32:30:3a – Button 2 released!

That’s great! Now we can use a low level tool like gatt to send the command itself, without the whole interface! Now I just need to implement it!

Linux – keep it simple.

Foray into Bluetooth Programming through C and C++

alaskalinuxuser@alaskalinuxuser-OptiPlex-7010:~/Documents/c++/bluetooth/cbluez$ ./simplescan
FC:58:FA:08:72:E4 CANZ
alaskalinuxuser@alaskalinuxuser-OptiPlex-7010:~/Documents/c++/bluetooth/cbluez$ ./simplescan
FC:58:FA:08:72:E4 CANZ
alaskalinuxuser@alaskalinuxuser-OptiPlex-7010:~/Documents/c++/bluetooth/cbluez$ ./simplescan
00:00:00:00:5A:AD bacon
FC:58:FA:08:72:E4 CANZ
alaskalinuxuser@alaskalinuxuser-OptiPlex-7010:~/Documents/c++/bluetooth/cbluez$

That was the terminal output from the program “simplescan”, which I got from an instructive how to guide. The program itself is rather straight forward, like so:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>

int main(int argc, char **argv)
{
inquiry_info *ii = NULL;
int max_rsp, num_rsp;
int dev_id, sock, len, flags;
int i;
char addr[19] = { 0 };
char name[248] = { 0 };

dev_id = hci_get_route(NULL);
sock = hci_open_dev( dev_id );
if (dev_id < 0 || sock < 0) {
perror(“opening socket”);
exit(1);
}

len = 8;
max_rsp = 255;
flags = IREQ_CACHE_FLUSH;
ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));

num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
if( num_rsp < 0 ) perror(“hci_inquiry”);

for (i = 0; i < num_rsp; i++) {
ba2str(&(ii+i)->bdaddr, addr);
memset(name, 0, sizeof(name));
if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name),
name, 0) < 0)
strcpy(name, “[unknown]”);
printf(“%s %s\n”, addr, name);
}

free( ii );
close( sock );
return 0;
}

But I did run into an error when I executed it. Turns out, I needed to install a few libraries:

# apt-get install libbluetooth-dev

Once that was installed, the #include files could then be found. How people get so smart to put this stuff together is beyond me! But I was rather impressed. My goal is to write an app for my Ubuntu Touch phone that will control my home-made Bluetooth auto start that I put together. I already created the Android app, but now I need something for my UT phone.

simplescan

The problem is, I don’t know anything about Bluetooth from a C or C++ programming standpoint, so I am trying to learn about it by working through various guides and simple tutorials like the one above. I’m hoping to learn a lot, and really looking forward to the adventure!

Linux – keep it simple.

BlueFruit Project: Extend the antenna range!

One of the issues that I have with my home made auto start is range. Obviously, Bluetooth Low Energy is only supposed to travel about 35 feet, when it is unobstructed, of course. The problem that I have here is that the BLE antenna was inside of a metal box, inside of a metal cab (the truck). Even placing the box up on the dash for “best results”, I could only be about 15 feet away from the truck to connect and transmit.

However, I decided to change that today. I decided to un-solder the antenna from the feather and put it on the end of some wire. Unfortunately, when I un-soldered the antenna, I broke it. But, Praise God, it still works after I wired in a makeshift antenna using about 6 feet of twisted, insulated, 20 gauge wire!

A few short tests, but I could now stand about 35 feet from the truck. Not only that, but I was able to successfully connect and start the truck from INSIDE the building, transmitting THROUGH a closed door!

Here are a few pics of the event:

I even took a few videos that you can check out on my GitLab!

Linux – keep it simple.

BlueFruit autostart was a success!

image20180531_074506688

After several series of bench tests, I was finally ready to make the plunge and install my home made autostart into my truck. The vehicle in question is a 1993 GMC K3500 pickup truck. It took about 30 minutes to remove the lower dash portion and properly identify the wires in question. Then, about 15 minutes later, the whole thing was hooked up.

Then came the scary moment of truth.

I opened my app on my phone, and pressed the big orange start button.

The first set of relays engaged, turning on ignition power, fuel pump power, etc. So far so good. After the 5 second delay (purposefully programmed to allow the priming of the fuel) the second set of relays kicked in, the vehicle cranked, and STARTED!

To God be the glory! Wow! I can’t believe it actually worked! Lo and behold, pushing the stop button on my app killed the truck too! Great! By the way, the entire project, all files, apps, sketches, pictures, etc., can be downloaded from the repository I made for this on GitLab.

A few tests showed that I still have some fine tuning to do. As can be seen from the two issues I opened on the repository, there are two enhancements that really would make this better. The first is that the range is limited to about 30 feet, on a good day with nothing between you and the truck. The second is a slight problem with voltage detection for determining if the vehicle is started.

You see, I am using a voltage divider to break down the 12+ vdc to less than 3 vdc for the BlueFruit board. If it is less than 0.9 volts on the board (13 volts on the vehicle), then the alternator is not charging and the vehicle must not be running. This causes a few problems.

  1. If the vehicle’s alternator ever fails, the autostart will attempt to start a running truck numerous times.
  2. During the cranking process, the board keeps checking voltage to see if the engine started, but it will always read low when a huge load like the starter is engaged. So it will always crank the full 3 seconds of crank time, even if the vehicle is started.

Both of these conditions will cause excessive wear on the starter, and in general is just poor design. So I’ll be thinking on a way to make that better. In any event, I’m really glad that the initial run was a success!

Linux – keep it simple.

BlueFruit Project: All boxed in!

Spent a little bit of time with a soldering iron.

 

I put my project into a box, wired in all of the relays, and ran several feet of wire for connecting to the various functions. Hopefully this will work! I’m planning to do some heavy bench testing really soon.

schematic

This was my original  schematic. For the most part, I stuck with it, but I did make a few changes along the way. For one, I replaced the second analog input to be a digital input, just routing the brake lights to activate a relay which allows 3.3vdc to go to the input switch.

Another change was adding a parking lights relay, which is activated from the “key on” relay. I don’t have it hooked up in my box yet, but it is in place, just needs the power wire hooked to it. It wasn’t part of the original plan, so I am not implementing it yet. I don’t want to get too crazy before actually testing if it works.

It is going to be really fun to hook this up. I’ll have to crawl around under the dash of my truck and get these wires put in.

Linux – keep it simple.