Showing posts with label bluetooth. Show all posts
Showing posts with label bluetooth. Show all posts

Sunday, March 29, 2015

Modding WiFiChron with GPS or Bluetooth

The latest revision of WiFiChron has an XBee socket (beside the ESP8266 8-pin socket), which allows the addition of a few individual features:
  1. GPS-based time synchronization, by using the GPSBee;
  2. displaying messages sent from a Bluetooth device, by using the BTBee/BLEBee;
  3. displaying data acquired from an XBee/ZigBee network of sensors (not implemented yet);


Things did not go smoothly, without some drama though. Naively (I always seem to forget that there is a difference between theory and practice), I designed the XBee/ESP to connect to the serial port, with the expectation that once the development (including testing with debug statements to the serial monitor) is done, I will just plug in the serial module (either XBee of ESP8266) and things will work properly. Well, I had to re-consider this approach once again. Luckily, I had two pins left available (D7 and D17), which I could use for software serial. I re-wired those to the XBee/ESP and used the hardware serial for console communication. Until the next board revision, anyone wanting to follow will need to re-route a couple of traces manually, as shown in the photos below (cuts are red-circled).


A few details on my implementation of the GPS time sync (so that one doesn't need to look at the code to figure it out):
  • user can set a timezone (stored in eeprom, default is -1); there is no (easy) way to determine if the timezone was set or not, since -1 (eeprom byte being 255) is a valid value;
  • estimate the timezone from the longitude, assuming that a every 15 degrees is an hour difference;
  • a difference between GPS estimated timezone and the user-set timezone of more than 2 hours would mean that the time is way off and the user did not set the timezone; in this case, blink the display; a difference of 2 hours or less would be acceptable (for many reasons, including summer-time, or variations from the "15-degrees-longitude-per-hour" approximation);
  • in any case, the minutes and seconds are set from the GPS data;
  • date and day are not set/synchronized at all (currently);
  • the GPS sync is scheduled to happen every 10 hours (and also after a reset);
  • a successful sync is indicated by an up arrow at the end of the scrolling date (e.g. March 29, 2015 ^).
I will publish the code as soon as I have a chance to polish it (and also test it with BTBee).

As you can see in the photo below, the GPS antenna fits well in the case. It also works well: the GPS has good reception inside the house, 5 meters from the closest window.


Monday, February 17, 2014

"Method and apparatus" for mass-synchronizing clocks

Most of my clocks (e.g. this Nixie clock, this other Nixie clock, BookClock, and obviously Wise Clock 4) have on-board Bluetooth, intended mainly for setting up the time, without the need for buttons (the lousy holes I would drill may negatively impact the aesthetics).
To set up the time, simply send the command TIME=hh:mm:ss, where "hh", "mm", "ss" are the hours, the minutes and the seconds, respectively.

Setting up multiple clocks is a tedious process: pair your Android tablet with one at a time, then (from BlueTerm) send the command that includes the correct time. Then repeat for each clock.

What if you could broadcast the TIME=... command? And that command to include the most accurate time, acquired from GPS? This is what this post is about. Now you have the "method".

Next, to the "apparatus". It consists essentially of 3 parts: GPS receiver, microcontroller and Bluetooth master module. Putting them together is trivial, since both GPS receiver and Bluetooth module communicate through serial ports.


I used an old (now discontinued at the major online stores, but still available on ebay) Fastrax UP-501 GPS module I already had laying around. But any GPS receiver should work as well, including the Adafruit Ultimate GPS Breakout.

The "Bluetooth master module" is a re-programmed HC-05 (see the datasheet) as master, with CMODE=1 (for broadcasting).

The sketch, presented below, uses SoftwareSerial library to communicate with the GPS module (Rx on D3, Tx on D4) and TinyGPS library to extract the time from the NMEA sentence. The BTBee module is connected to the hardware serial port (D0, D1).


#include "TinyGPS.h"
#include "SoftwareSerial.h"
SoftwareSerial GPSSerial(4, 3);

// GPS Fatrax UP501, connected as follows:
// - power pin to 3.3V
// - ground pin to ground
// - VBAT pin to 3.3V if no battery is used
// - TX pin to D4
// - RX pin to D3 through a voltage divider (2 resistors, 10k + 4k7)

#define _DEBUG_  true

// commands  for GPS module;
#define PMTK_SET_NMEA_UPDATE_1HZ  "$PMTK220,1000*1F"
#define PMTK_SET_NMEA_UPDATE_5HZ  "$PMTK220,200*2C"
#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F"

// turn on only the second sentence (GPRMC)
#define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
// turn on ALL THE DATA
#define PMTK_SET_NMEA_OUTPUT_ALLDATA "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"

// MTK command datasheet at http://www.hhhh.org/wiml/proj/nmeaxor.html

TinyGPS gps;

void setup()  
{
  // default baud rate for BTBee (on hardware serial);
  Serial.begin(9600);

  // default baud rate for UT501 (on software serial);
  GPSSerial.begin(9600);
  
  // turn on all the available data (for 9600 baud you'll want 1Hz rate);
  GPSSerial.println(PMTK_SET_NMEA_OUTPUT_ALLDATA);
  
  // set update rate to 1Hz
  GPSSerial.println(PMTK_SET_NMEA_UPDATE_1HZ);

#ifdef _DEBUG_
  Serial.println("ready for reading GPS...");
#endif
}

void loop()
{
  acquireTimeFromGPS();
  delay(5000);
}

void acquireTimeFromGPS()
{
  unsigned long age;
  int Year;
  byte Month, Day, Hour, Minute, Second, Hundredths;

  if (feedgps())
  {
#ifdef _DEBUG_
    Serial.println("GPS feed acquired...");
#endif
    gps.crack_datetime(&Year, &Month, &Day, &Hour, &Minute, &Second, &Hundredths, &age);
    char buf[20] = {0};
    sprintf(buf, "TIME=%02d:%02d:%02d", Hour, Minute, Second+1);
    Serial.println(buf);
  }
}

bool feedgps()
{
  while (GPSSerial.available())
  {
    char c = GPSSerial.read();
#ifdef _DEBUG_
    Serial.print(c);
#endif

    if (gps.encode(c))
      return true;
  }
  return false;
}

As protoboard I used the XBee Shield from seeedstudio because it had a socket for my BTBee (plus 3V3 regulator) and also ample space for processor and GPS. (It could even fit in a Altoids tin if  the GPS receiver is soldered directly to the board, without headers.)

Future improvements should include a couple of status LEDs, one to show that the data was being acquired from GPS, another to indicate that the "TIME" command was successfully built and broadcast. Similarly but more expensively, a small OLED screen could be used to display the activity.
On the software side, the time, which comes as UTC in the NMEA sentence, should be adjusted to the current time zone, probably based on the longitude.

Monday, January 13, 2014

Chumby Nixie clock

With my limited (read "non-existent") crafting resources (e.g. space, tools), the easiest way to enclose my Arduinix clock was by recycling my late Chumby's shell. Things almost magically fit together, with minimal thinking and work. I was able to cram inside the box a hand-wired Wiseduino with an Arduinix-remix shield and a 4-tube board.


The old Wiseduino would have come in handy if I had any left. I made one using the protoshield from Sparkfun, which also has a connector for the Bluetooth JY-MCU module. Beside the ATmega328, this pseudo-Wiseduino board includes a DS1307 with coin backup battery and a 7805 voltage regulator.

The tube board is attached with screws to an empty board that plugs in the Arduinix-remixed shield. (Note that one reason for "remixing" Arduinix was to re-arrange the parts sticking out, namely the mosfet and the capacitors, so that it allows another shield to be stacked on top.)


The clock has no user button (I glued the original snooze button on top, would have required extra work to re-use it), so the time is set through the bluetooth interface, similarly to my other Arduino Nixie clock.


The sketch (compiled with Arduino 1.0.4) is available here. Note that, unlike the original Arduinix sample sketch, the nixie-driving code is now using interrupts. This decouples the display logic from the clock functionality, also allowing for the addition of a buzzer alarm.

Monday, November 18, 2013

Another Nixie clock

For "unknown" reasons, these days things don't move as fast as they used to. I have a dozen or so unfinished projects on my desk, most of them waiting for parts to arrive. And usually and unfortunately, when I get the long awaited part, something else is missing... or not fitting,... or not working.
Today I was finally able to finish the "Open Source Nixie Tube Shield", for which I pledged $15 on kickstarter in return for the PCB.
Without paying attention to the schematic (was it even published before the campaign ended?), I thought it was just another variation of the same Nixie theme, which it really was. I expected to have all parts on hand already, including the Nixie K155ID1 driver Russian IC. Surprise! Instead, the circuit uses CD4028 decoder plus HV transistors. And that's where the 4 week wait is coming from.

I liked the compactness of the board even before I soldered the almost 100 components. But I was a bit disappointed when I realized the shield had a (minor) flaw: the area above Arduino's USB A connector is as highly populated as the rest, if not more. Not only the metal encasing of the USB connector will short the high voltage components on the shield above, but the shield cannot be even pushed all the way in.
A workaround (which I ended up using) is to have an intermediary shield between Arduino and the Nixie tube shield. Another solution is to use an Arduino variant with the mini B USB, like Seeeduino or Leonardo.

But all's well that ends well. To cut the story short, the sample sketch provided worked just fine without interventions. Hardware-wise, I added a DS1307 RTC (since I was going to build a clock), a buzzer (for alarm and chime) and a Bluetooth module (to set up the time without buttons). The only kludge required was a change in the core file Tone.cpp, where I replaced Timer2 with Timer1.

Below are a few photos. For enclosure, I (again) went for the the poor-man's solution, this time hand-cut (as opposed to laser-cut) transparent acrylic plates. (The long standoffs are 60mm, in case one wants to reproduce the experiment.)


I was happy to "upcycle" my Arduino Duemilanove, with the nice bottom exposed and visible :)
The prototype shield was something that I thought I will never use again, but it came in handy.


I also borrowed an idea from akafugu, with the bigger front plate creating a nice slope.



One thing I skipped (because I don't like the combination) is the blue (or any other color, for that matter) LEDs under the tubes.

A working version of the code is available here. It is based on Tyler's code (timer-based multiplexing of the digits, anti-cathode poisoning etc), with added support for RTC (DS1307) and functionality for setting up the time, alarm time, enabling/disabling alarm etc through Bluetooth (using an Android phone or tablet, for example).
The clock can execute the following commands, sent from BlueTerm (after pairing with the device):

  • TIME=hh:mm - sets the current time (second is set to 0);
  • ALARM TIME=hh:mm - sets the alarm time; the alarm hour and minute are also saved to eeprom (and retrieved from there whenever the clock is powered back on);
  • SHOW ALARM - sends back to BlueTerm the alarm hour and minute
  • ALARM ON - enables the alarm; this is also saved to eeprom; the Alarm On/Off status can be shown with a LED connected to A0;
  • ALARM OFF - disables the alarm;
  • STOP ALARM - turn off the sound after the alarm starts beeping;

Note that all commands must be upper case.

The "Stop alarm" feature is reminiscent of Rami's "Deep Sleep iPhone app" and also of Ramos alarm clock (coincidentally, another Nixie clock, close source though), where both of them are asking for user interaction to stop the sounding alarm. Well, in order to stop this Nixie clock from beeping, one needs to open BlueTerm, pair the devices, then type in "STOP ALARM", a sequence of actions that requires anyone to be pretty much awake.

Sunday, September 29, 2013

Play Tetris on Wise Clock 4

No kidding.
I was looking for a suitable application to demo with Wise Clock 4 placed vertically (that is, standing on its shortest side), when I found this hackaday post about Tetris on a LED matrix. The code, already written for Arduino, clean and easy to understand (kudos to Jianan), was a breeze to port. I only had to change a few functions (display, user buttons), comment out a few more (sound, text etc) and downsize from 7 colors to just 3.
Commands come from Bluetooth terminal ("BlueTerm" app on Android), basically replacing the buttons with letters (U, R, L, D; you got the idea).


The Wise Clock 4 vertical stand is possible thanks to the enclosure-mounted power jack, wired to the display's screw terminals, as shown in the photo below (that also captures a part of my messy desk).



(This is a typical example of how one thing leads to another. I don't usually play games, but when I do, I use my implementations. "Time well wasted", as the saying goes.)

Friday, June 1, 2012

Wise Clock 4 with integrated Bluetooth

Wise Clock 4 can now hold a Bluetooth module outside of the XBee socket, as shown in the pictures below.




























The communication with the BT module uses SoftwareSerial on pins D20/PC4 (Tx) and D21/PC5 (Rx).
The module is powered with 3V3 and the Rx line is level-shifted.

I bought a few of these Bluetooth modules from different sources, mostly ebay. Some of them did not work: my PC's Bluetooth could not "discover" them. Once SMD-soldered to the board, it is very difficult to figure out what's wrong and even de-solder and remove them. My advice for anyone using these modules is to check them before soldering them to any board/breakout. An easy way to do this is to solder wires on pins 12 (Vcc) and pin 13 (ground), as shown in the photo below (left), power with 3.3V, then try to pair it with a Bluetooth host (PC, Android; iPhone won't work since it requires an Apple-approved chip).















The module's relevant pins are shown in the diagram below (photo from ebay seller):












I did not test this myself (the experiment may cost about $7), but it seems that these Bluetooth modules only tolerate approx 3.3V and powering with 5V will fry them.

If you already have an Wise Clock 3/4 and want to add Bluetooth functionality (simultaneous to WiFi or XBee), you can add this module to the clock. Connections are through 4 wires: Rx/Tx go to D20/D21 (pins 26 and 27 of the processor), VCC to 5V, GND to ground. Note that this module has on-board power adapter for 3.3V and level-shifter for the logic lines.

Thursday, April 19, 2012

Wise Clock 4 with remote "Alarm stop" button

The Ramos project brought the novel idea of a wireless alarm-stop button: instead of just reaching out to  press on the top of your nightstand alarm clock, you now have to actually get out of the bed and walk to a remote corner of your dwelling to click on a keypad. No chance you will return to sleep afterward :)

This remote alarm-stop feature for Wise Clock 4 can be implemented in several different ways, all of them using of the on-board XBee socket:
  • through a Bluetooth module;
  • through WiFi, using the Roving Networks WiFly module;
  • through XBee radios.
The cheapest and easiest would be the Bluetooth solution, providing that you already have a BT device (e.g. Android phone/tablet) to communicate with. In pseudo-code, it should look like this:

if (alarm is ON)
{
    while (Serial1.available())
    {
       read characters received;
       if (it is the expected string)
       {
            set alarm OFF;
        }
    }
}

The WiFi solution would require a second WiFi device (phone/tablet) to access a web site, or maybe they could talk directly (sockets), using their IP addresses.

The solution based on XBee relies on direct communication between two XBee radios. One would have to build the remote device, probably around an Arduino, with a keypad and an XBee.

Updated Feb 26, 2018: A good XBee remote control would be the SparkFun Wireless joystick.
Another, much cheaper solution, that does not requires software changes, would use the M4 backpack, as detailed here.

Sunday, April 8, 2012

Scrolling message sign with Bluetooth

A simple application for Bluetooth was suggested a while back by fellow arduinoer evanrich (who also created a home for his project on github): a scrolling sign using several cascaded 3216 displays and controlled through Bluetooth from an Android phone. His intention was to use it as a wireless sign that can be put in the back of the car to tell drivers to get off his tail.

I gave it a try myself, using Wise Clock 4 with Bluetooth and two 3216 displays, as shown in this photo (the blue LED on the BTBee is power, the orange one is communication status).


















The code is a modified version of the one posted here.

This message sign, especially if it is made with the larger (5mm) 3216 displays, can be also used in waiting rooms, call centers, stores etc, to show dynamic and easily-changeable messages.


Related posts:

Thursday, April 5, 2012

Wise Clock 4 with Bluetooth

Another thing that was supposed to be easy, but it wasn't: Arduino communicating with Windows XP through Bluetooth.

Like everybody, I purchased the cheap and ubiquitous Bluetooth module from dealextreme.
I soldered it myself on the XBee-footprinted PCB (bare BTBee from IteadStudio), for a total price of about $8 (compare that to at least $15 as these Bluetooth XBees go for).

Without knowing much about Bluetooth, I plugged this new "BTBee" module in Wise Clock 4 expecting it to be "discovered" by XP (which has an USB Bluetooth dongle). Discovered it was: the name "linvor" appeared in the list of BT devices, with two serial ports attached to it.

Communication between XP and BT module is performed through the serial ports, I figured. Tried CoolTermWin, HyperTerminal, Putty, on both ports, nothing seemed to work. Time to read the documentation (which always reminds me of that joke). I learned that others had similar problems, and some have solved them by installing new BT drivers. The best advice came from this post. Putty did not work for me, so I stuck with what I had, namely HyperTerminal.

So here is my own step-by-step tutorial on how to make an Arduino communicate with Windows XP via a Bluetooth module.
Note: From the Bluetooth perspective, Wise Clock 4 I used for my testing is similar to Arduino.

1. Upload this simple sketch that "echos" what it reads from Bluetooth and also broadcasts a message periodically. The communication between Arduino and the BT module is serial, with a baud rate of 9600, according to the documentation.

#if ARDUINO < 100
  #include
#else
  #include
#endif


void setup()
{
  Serial.begin(9600);
}


void loop()
{
  while (Serial.available())
  {
    // get char from bluetooth;
    char inChar = (char) Serial.read();
    // output it back, between brackets;
    Serial.print('[');
    Serial.print(inChar);
    Serial.print(']');
  }
  // broadcast message;
  Serial.print("millis() from Arduino: ");
  Serial.println(millis());
  delay(2000);
}

2. Power Arduino, with the BT module connected, and let it run the sketch.

3. Make the BT module (on the Arduino) visible to XP, by adding it to the list of Bluetooth devices. For this, click on the "Bluetooth Devices" icon in the tray (bottom right corner of the XP's desktop). You will see this box.
















Next, you will see the BT device added to the list, under the name "linvor".















Then select the last option, "Don't use a passkey". Although it makes little sense at this point (since you know that the passkey is 1234, according to the documentation), it is very important to not use a passkey here.















The last step of the wizard shows the two ports that have been added. Write down the "Outgoing COM port", since this is the one we will be using for communication (step 4).















4. Open HyperTerminal to establish the 2-way communication between XP and Arduino, via Bluetooth.
Select, from the list, the COM port specified as "outgoing" for the BT device.


















Next, you will be shown this pop-up.






After you click on it, you are prompted to enter the passkey, the one you (reluctantly) skipped in the process of setting up the BT device. Type "1234", as specified in the BT module documentation.















After hitting "Next", you are shown this last confirmation box.















In the same time, the HyperTerminal starts displaying the message coming from Arduino.














Note that, when the COM port was opened in Auto mode, no parameters (baud rate etc) being specified.
Interestingly, after the communication is established, the baud rate is reported as 2400 for some unexplained reason.
You can also type characters in HyperTerminal and they will be echoed back, between brackets, by Arduino.

Optionally, if you want to see what you typed (before the echoing from Arduino takes place), you can enable local echo, by selecting "Properties", then "ASCII Setup".





































Once the communication between XP (HyperTerminal) and Arduino is established via Bluetooth, the "Status" LED (if you have it soldered) is on continuously. When the BT module is not communicating, the "Status" LED is blinking at a frequency of about 2Hz.

The next time a HyperTerminal session is opened, XP remembers the BT device and the communication params (ports, passkey) and does not ask to set it up again. (I guess that's why it is called "pairing", although this word does not appear anywhere in the process.)


Time to write some serious applications using Bluetooth:)