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.

Advertisements

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.

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.

BlueFruit Project: Added kill on too many start attempts

One of the perks of bench testing your newfangled autostart project is that you can start to see patterns of use that may lead to trouble. The other is that when you hook up a multi-meter to the relays with the diode audio turned on, you can listen to the hum of your machine!

IMG_20180424_122308

One such test, though, proved insightful. One would surmise that if you attempt to start the vehicle, that after the prescribed number of attempts, it would simply give up and stop. However, my code only stops it from cranking after the three failed attempts. That means the accessory/fuel pump relays are still on!

I realized this when the hum from the multi-meter didn’t stop. But it should have.

While you can check out the whole commit on my GitLab, but here is the relevant portion:

if (startTimer == 0 && startAttempts > 0) {
digitalWrite(11, LOW);
digitalWrite(15, HIGH);
crankTimer = 3;
startTimer = -1;
Serial.println (” crankTimer ON “);
} else if (startTimer == 0 && startAttempts == 0) {
// Turn everything off from to many attempts.
digitalWrite(16, LOW);
digitalWrite(15, LOW);
digitalWrite(7, HIGH);
digitalWrite(11, HIGH);
crankTimer = -1;
startTimer = -1;
runTimer = -1;
startAttempts = -1;
Serial.println(” Kill All – Too many attempts. “);
} else if (startTimer > 0) {
startTimer = startTimer -1;
Serial.print (” startTimer “); Serial.println(startTimer);
}

Before, if the startTimer reached zero, it would check if the startAttempts was greater than, or equal to zero, and then try to crank. Now, I have it only attempt to crank if the startAttempts is greater than 0. If it is 0, it will send the kill signal and stop all attempts.

Short and simple, but that’s usually the best kind of fix!

Linux – keep it simple.

BlueFruit Project: Stage 1 Relays!

autostart

Blinking lights! Yes, the first prototype of the first stage relay setup for my home made autostart is assembled. As you know, a small 3 to 5 vdc BlueFruit Feather can’t crank an engine starter. That’s just too much current to flow through such a small board. To make this work, I have to step up through relays in stages to get to the big relays that can actually do the work.

So, stage 1 relays are actually Latching Relay Featherwings that are joined to the BlueFruit feather via soldered wire connections. These latching connections only need about 10ms of signal to turn on or off the 3.3 vdc relays, which will hold the 12 vdc power supply to the stage 2 relays.

The stage 2 relays will then use minimal current at 12 vdc to drive the vehicle relays that actually engage things like the key on and cranking power. Don’t worry, at the end of the project I will follow this up with a diagram and parts list. Looks like the overall price is about $60 worth of material, pending finding a used container or box for free.

Linux – keep it simple.

BlueFruit Project: Time Out!

Zip created at /tmp/arduino_build_587243/sketch_dec29a.ino.zip
Using library Bluefruit52Lib at version 0.7.5 in folder: /home/alaskalinuxuser/.arduino15/packages/adafruit/hardware/nrf52/0.7.5/libraries/Bluefruit52Lib
Using library nffs at version 1.0.0 in folder: /home/alaskalinuxuser/.arduino15/packages/adafruit/hardware/nrf52/0.7.5/libraries/nffs
Sketch uses 59352 bytes (35%) of program storage space. Maximum is 167936 bytes.
Global variables use 4852 bytes (9%) of dynamic memory, leaving 46220 bytes for local variables. Maximum is 51072 bytes.
nrfutil –verbose dfu serial -pkg /tmp/arduino_build_587243/sketch_dec29a.ino.zip -p /dev/ttyUSB0 -b 115200
Upgrading target on /dev/ttyUSB0 with DFU package /tmp/arduino_build_587243/sketch_dec29a.ino.zip. Flow control is disabled.
Starting DFU upgrade of type 4, SoftDevice size: 0, bootloader size: 0, application size: 59764
Sending DFU start packet
Sending DFU init packet
Sending firmware file
######################################################################################################################
Activating new firmware
#
DFU upgrade took 11.5461740494s
Device programmed.

Time out! Well, not really, but it sounds catchy! Timing is really important. And that is what I had to adjust with this commit. I had a 500 ms delay between program runs, which takes about 500 ms to run. So, each run of the program takes roughly 1 second, which is great for setting the timing of the program.

Here’s the interesting part: the relays that I am using are the latching relay featherwings. They only need the power applied to set or unset the relay for 10 ms, then they will hold their last position. This is great for power savings. In my program, I want to capitalize on this power savings by having the outputs off all the time, when they are not specifically latching the relays.

2923-00

To make that happen, at the beginning of the loop of my program, I added a few lines to set all of the output pins low (15, 16, 7, and 11). While this will cut down on the power the board puts out (saving electricity, but also saving wear and tare, as well as making the code cleaner, since the state of the pins will always be known), it may cause me a slight issue. I don’t want it to cut down on the actually needed signal for when the outputs should be high to latch or unlatch a relay.

Confused yet? Well, let me explain. Here is how the program looks functionally:

  1. Set all pins low.
  2. delay 500ms.
  3. run program, like setting some pins high.

As you can see, there is actually no time between running the program and setting all the pins back to low. I needed to ensure there was at least 10 ms after the program sets the pins high before the loop sets them all low again. I thought I could swap 1 and 2, making the delay first, but then there was no time between the setting of low pins and running the program. So I edited it like this:

  1. delay 250 ms.
  2. set all pins low.
  3. delay 250 ms.
  4. run program, like setting some pins high.

Now there will always be at least 250 ms (1/4 of a second) for the relays to latch before given a command to set the pins low. Conversely, after being set low, there is 250 ms before the program runs, allowing me to keep my (roughly) 1 second timing on the circuit. Probably a little overkill for what I need, but at least I know this will work, making the program more robust.

Linux – keep it simple.