As with most hobbies, blogging takes a lot of valuable time. I registered this website in 2006 while in university as a place to share ideas, notes and technical documentation. It ended up being used by my fellow classmates for skipping class. Oops.

Since then it has mainly been host to my custom WordPress plugins (like Mass Page Maker) and some of my Arduino creations (like CoffeeBot). Most of the time those posts come with months or even years in between, so clearly I didn’t give the blog the attention it deserved.

The reason for that is because I picked up many other hobbies or time-sinks. Things like cycling, other electronic creations and driving took higher priority. So today this post is just to say that there won’t be any additional new posts. All of the archived content is still available (like this one about C programming that still gets most of the traffic?) and comments are disabled.

Thanks, internet!

It only took 4 years, but I finally found enough time to build a new mobile app and update an existing one. Things have been busy to the point where my weeknights are taken up with other things, and any software development has to be done during the day. Sometime last year I had another idea for a mobile app utility and decided to build it properly to learn about Android store processes and online advertising. Here’s what I built and how the process worked.

Log – flexible data tracking

Like the name says, this is the app idea I came up with last year to solve a problem I couldn’t find an existing app for. It’s a data journal that provides the ability to create custom streams of data and track those over time. The streams can contain multiple inputs like numbers, text or dates, and get added to the list. For example, track driving trip distance or count the number of times you go to the gym. It’s all manual and offline.

Learn a lot more about it at

Equation Library

This was an app I wrote back in 2014 and it received a surprising number of downloads. I ended up not having enough time to commit to its maintenance and let it sit for too long. Recently I reviewed the tech needed for it to work and decided it was new enough that I could do that. So I spent a few evenings rebuilding it with the latest SDK and made some improvements.

The application itself works by including a number of math categories that have equations I’ve collected from my textbooks and online sources. Each equation can solve for the primary variable and most provide the ability to solve for additional variables. My hope is that as people use it and start to request categories I can slowly build a much larger database. Fortunately the new system is much easier to update and maintain than it was previously.

The hard part comes after

If you’re proficient at mobile development, building the apps themselves isn’t that difficult. I wanted to use the process of updating the apps to learn about online marketing and advertising, so it turns out that the hard part is just getting noticed. I think the market has shifted significantly since I started building small utilities in 2011 and I’m surprised at how much people don’t want to spend on apps now. So far targeting ads with Facebook and Google has not resulted in many sales, but I’m still learning so hopefully that starts going up as I do more.

Give the apps a try!

Tagged with: , , , ,

Coffee pot and sensorsLike most tech offices, we go through a lot of coffee during the day. We have about 15 people spread between 2 rooms upstairs, and a single coffee pot between us. Generally this means someone makes a pot early in the morning and it’s done by lunch time, when someone else makes another. The problem is that it’s difficult to time your coffee intake with a fresh pot. Wouldn’t it be great if we could get some kind of alert when the pot was ready?

How to get that notification was pretty straightforward: we use HipChat, a very well done message platform from the folks at Atlassian. Even better is that HipChat offers an extensive API, with the simplest method being something called Integrations. These provide a self-contained URL request to make to a particular room and alert all of its members. All I’d need to do is track the coffee pot cycle and send an alert at the appropriate time.

Choosing the hardware

The first step is determining what method to use for tracking the cycle. Looking around online, people have done similar things by looking at the weight of the pot, the level of coffee in the pot and the current consumed by the maker itself. I don’t want to deal with weight (yet) and I find level monitoring overly complicated so I decided on current. Ideally I would be able to determine the cycle based on either the on/off times or the actual current consumption.

I have amassed a pretty large collection of Arduinos at this point, so choosing that platform was pretty easy. I also wanted to have everything self contained as much as possible, which meant looking for something with the following capabilities:

  • Analog inputs for connecting the current sensor
  • Digital output for local monitoring (LED, LCD)
  • Network connectivity for sending a notification
  • Logging to collect enough current data to notice a pattern

The only Arduino that satisfies these requirements is the Arduino YUN. The YUN is different from other Arduinos in that it is actually two chips in one, with a standard ARM chip on one side running the Arduino bootloader and a dedicated Linux board on the other side to run more complex operations. The advantage of this setup is that you can collect sensor input on one side and transfer that to Linux for processing.

For actual sensor monitoring I decided on the SCT-013-010 non-invasive current sensor. This is a version of the fairly popular SCT series, has capacity up to 10A and provides scaled 1V output. That last point is important, because I find it simpler to take analog voltage input than creating a circuit to make the scaled current output provide meaningful data.

Finally I added in a 128×32 OLED LCD I had from a previous project, for local monitoring of the current consumption. With that in place, I might even notice a pattern by glancing at the screen.

Collecting the data

While the current sensor is technically “non-invasive”, it does require some wire hacking to work properly. It works on the principle that a voltage can be induced in a neighbouring wire through an electric field. However since it works with AC lines, that power fluctuates through both wires at opposite time, effectively cancelling each other out. The solution is to split your appliance wire apart and wrap the sensor around only one of them.

After assembling a circuit according to numerous other current tutorials (like the Open Energy Monitor project), I was receiving current data to the screen, but it did not appear very useful. In fact, this was what I call Road block #1. I was reading the current data as if it was DC, but since AC power is a wave, I was effectively reading a single point in the wave and not the proper current. Fortunately the solution was to better follow that tutorial, and use the Emonlib Arduino library. This library monitors the entire power wave and does the correct math to give you a current value in amps.

With the current readings accurate, I needed to log them somewhere for later processing. To do that I used a MicroSD card in the YUN along with the example sketch called DataLogger. I modified that script to only save current when the reading is 0.1A or higher and to create a new file every day to keep things organized. After a day in the office, I had useful data, but I immediately ran into Road Block #2.

Setting a minimum threshold of 0.1A seemed to make sense, but after seeing the power consumption through the cycle, our particular coffee marker consumes 0.17A at idle. With a logging interval of 1 second, I ended up collecting a row of data every second for 2 days! It was not very useful so I cleared the SD card, reset the threshold to 0.2A and tried again.
This is the data that resulted from a day of coffee pot monitoring. The Arduino provided a column containing the current time and the current usage, plus a filtered current value I didn’t end up using. I imported the data into Excel and added the column to the right, which is the difference between any one row and the time above it. Since there is no data logged when the machine is off, it became very easy to see the gaps. I also added the conditional formatting to highlight rows that are more than 2 seconds.

Looking through the rows, I was able to find this pattern for a typical coffee cycle:

  • It idles at 0.17A (idle meaning plugged in but not actively brewing)
  • At the start of the brewing cycle, the current changes to approx. 7.5A for 8-10 minutes
  • The end of the brewing cycle is indicated by 25 seconds on and 25 seconds off, twice
  • Once brewed, it repeats a cycle of 15 seconds on, 2 minutes off until someone turns the power off

With such clearly defined points along the cycle, it turned out to be pretty straightforward to detect. The notable complication is that the times are not precise, and it might be on for 8 minutes instead of 10 or heat for 25 seconds instead of 15. I was somewhat disappointed that it did not cycle differently depending on the volume of coffee to heat. I was hoping that it would heat less as the coffee level dropped and I could determine how many cups remained.

Doing the math

To detect the brewing cycle, I set the Arduino timer to compare current usage every second. I stored the previous value and used that to save a time reference for when the current level went above the threshold (set to 6A). By comparing those values, I could get an event when the coffee maker turns on and off, while checking the time between the two. If the appliance is on for more than 8 minutes, that’s considered the actively brewing stage. After that, if there is an on period of less than 30 seconds, that would be the start of the heating stage. The message alert would go out at the end of the brewing stage. I started with a 10 minute brewing cycle but ended up changing it to 8 when I found that the heater wasn’t always consistent. It turned out to be pretty accurate, though!

Triggered by the 1 second timer is this method

void logCurrent() {
  long timestamp = getTimestamp();
  boolean turningOff = false;
  boolean turningOn = false;
  // track the change in current
  if (prevCurrentReading < onThreshold && currentReading > onThreshold) {
    lastOnTime = timestamp;   
    turningOn = true;
    turningOff = false;
  } else if (prevCurrentReading > onThreshold && currentReading < onThreshold) {
    lastOffTime = timestamp;
    turningOn = false;
    turningOff = true;
  } else {
    turningOn = false;
    turningOff = false;

  bool currentlyOn = (currentReading >= onThreshold);
  bool currentlyOff = (currentReading < onThreshold);

  // determine the brewing cycle
  if (mode != Brewed && turningOff && (lastOffTime - lastOnTime) >= brewDuration) {
    mode = Brewed; 
  } else if (mode != Brewing && currentlyOn && (timestamp - lastOnTime) >= heatingDuration) {
    mode = Brewing;
  } else if (mode == Brewed && lastOnTime != 0 && turningOff && (lastOffTime - lastOnTime) <= 45) {
    mode = Heating; 
  } else if (mode != Off && lastOffTime > lastOnTime && (timestamp - lastOffTime) >= offDuration) {
    mode = Off; 
    logEvent("Power off");
  prevCurrentReading = currentReading;

First I receive a UNIX timestamp from the Linux processor. This makes comparing times easy. Next I set a few variables based on whether the current usage is above or below the threshold set at the start. This is important because events are generally only triggered when things change. The logEvent() method logs the event to the SD card for future comparison and sendEventMessage() sends a notification to a HipChat room I set up specifically for monitoring my projects.

The brewing cycle checking works by using the current mode and checking the time between when the coffee maker when on or off. If it’s determined to be on for more than a minute nonstop, it’s considered “brewing”. Once it turns off and the gap between events is more than 8 minutes, that’s the end of the brewing cycle and the method sendMessage() is triggered to actually send a HipChat notification. After that a short on/off cycle is checked to look for heating and if it goes off longer than 5 minutes, the coffee maker is idle. The trick is generally to not detect another stage in the cycle if that stage is currently active. That usually removes the issue of sending a message continuously instead of once.

Sending a message

The YUN provides multiple ways of sending an HTTP request, but the easiest thing is to trigger a bash script inside Linux, instead of using Arduino directly. Finding that out was the solution to Road block #3. Throughout the internet, keyboard warriors warn about using Arduino’s string object and how inefficient it is. I started by generating a cURL request with a single String object, but that never worked. It turns out that I ran up against what appeared to be a memory limitation inside Arduino that probably limits string length to 256 characters. The cURL command I wanted to run was about 260 and would exit without error, but without actually sending a message. The solution to that problem is to move the cURL command to a separate bash script on the SD card and trigger that script from Arduino instead.

The last problem was that cURL would try to verify the SSL certificate that HipChat was using but was unable to. While probably not proper, the easiest thing is to disable that check using the -k flag in the command. After that, I set up the monitor and 10 minutes after brewing started, this appeared in our All Teams chat:
After a few days of operation, it seems to be fairly accurate and people have responded well to the little machine we call Coffee Bot.

Next steps

As mentioned I was hoping to be able to retrieve coffee levels from the current interval but since our particular coffee maker doesn’t do that, I’ll have to add a scale. With weight data available, I could know right away that a new pot is brewing and how many cups are left. It would even be possible to make the HipChat integration accept requests to know how many cups are left. You could write /coffee cups to know the number or /coffee time to know how long it’s been heating.

We also have tea drinkers so it would be reasonably straightforward to add a tea pot sensor. That cycle is even easier because it is either on and heating or off.

Finally I might make the hardware collection a little prettier for the shelf by maybe 3D printing an enclosure and making a proper PCB but that’s now pretty far down my list of electronics projects.

Finished product
My apartment uses baseboard heaters and anyone who’s paid for hydro can tell you, they’re pretty inefficient. I wanted to collect some information about the inside conditions of my apartment so that I could better understand when and how to turn the heaters on. Normally a simple thermostat would do, or even a Nest, but my equipment is so basic, there is no read out available.

So I built my own. Here’s what I did.

In high level terms, I have an Arduino UNO using a WiFi shield and custom PCB connected to a DHT22 temperature and humidity sensor and photocell. This information is sent to and is displayed in snapshot, table and graph form on my iPhone.

Setting up the Arduino

The components with the Arduino are all fairly well known, but I had not made anything with them together. Here are the parts and links to where to get them

I put them together on a breadboard and build the code. I can provide code if interested, but essentially I assembled individual modules in order to upload the data every 5 minutes. As far as the program goes, it’s laid out like this

  1. Include all libraries — this uses DHT, Timer, Wifi, SPI WifiClient, WifiServer and medianFilter
  2. Define base variables — Wifi shield configuration, website, pins, etc
  3. Create objects — Timer, client, server, filters
  4. run setup() — set pin modes, connect to Wifi and set the timers
  5. loop() only updates the timer
  6. Every 30 seconds all sensors are read and added to a filter
  7. Every 5 minutes the filtered data is sent to

Creating a circuit

schematicA breadboard is fun for prototyping, but it wouldn’t look so good on a shelf, so I took the opportunity to test out a new PCB manufacturing website by building my own circuit. The pinouts of all components is fairly easily available online, or better yet, in EAGLE itself. The board doesn’t have many pieces, just some 0.1″ header holes, but the tricky bit is making sure that there are no pin conflicts with the Wifi shield.

Moving to a PCB

EAGLE provides a nice way to import a schematic to a board, and since I started with an Adafruit shield piece, there was a nice outline ready for me. At that point it was a matter of making sure that all traces have clean paths and there are 5V and GND planes.

I tried a PCB service previously called but was unhappy with the cost and lead time required. A friend pointed me towards and that turned out to be a great choice. The name is basically entirely what you get: printed circuit boards at affordable prices, with a very reasonable 1 week lead time. I was also impressed with the shipping from China, as it was no more than an additional week with DHL. That’s 2 weeks for 10 custom boards.

Displaying it all on a phone

The data is sent to, which provides a nice free way to store key-value data (eg. temperature=25,humidity=38, etc) and a way to retrieve it. During the day I work for a mobile software company, so building something to retrieve the data was fairly straightforward. I ended up with a way to view different properties in the latest data, table and graph form.
This is the home page where the latest data point is displayed front and centre, along with the time it was retrieved. The time is relative, so a timer runs every second to indicate how old it is, but clicking the label shows the actual timestamp. Below that is some related information that might be useful: the 24 hour high value, 24 hour low value, and the current outside temperature according to
Additionally the menu button at the top left presents a slide out “hamburger menu” that can switch between the different properties collected.
The middle tab shows the last hour of data in table format and as you scroll downward, will load the next block from Core Data. In order to keep the actual internet request simple, the app retrieves the timestamp of the most recent datapoint and only requests points from Sparkfun that are after that. All points are stored in Core Data and loaded on demand.
Finally the right most tab shows a graph of whatever property is displayed at the time, with options for last 4 hours, last day or last 4 days. At first I had last hour but I realized the data I was collecting wasn’t really changing in that time frame so it was largely useless.

For the most part the graphs are consistent, with my heater keeping the temperature at about 19-20C through the day. The light graph is very interesting because it clearly shows when the light goes off and how sunlight filters through the curtains in the morning.

Next plans

There’s one thing I’d change about the PCB design, and that would be to replace the fixed photo cell resistor with a potentiometer to adjust the threshold. Right now I’m using a 16k ohm (I think, something about 10k) and that produces a nice range between full bright and darkness, but it would be good to adjust as required.

With the data collected, I’d like to now make use of it somehow. You might notice how the board has 4 pins showing “relay” on it, which is so that I can connect an AC relay and control my lights or humidifier. Ultimately I’d like to work in some geocoding to my app so that I never come home to a dark apartment and have my light be smarter so that it doesn’t turn off while I’m still at my desk.

Tagged with: , , ,

Screenshot 2014.01.30 20.57.11As part of my 2014 challenge to become proficient at robotics, I’m building a robot. I’ll be documenting whatever I can here to share what I learn, and to start I’m looking at control systems. Since my day job is developing iOS applications, it was natural to look at ways of using my iPhone to control and monitor the robot and to do that I developed a library for communicating between iOS and ROS.

Robot Operating System (ROS) is an open source software package that works above the core operating system to provide communication and processing for the different components a robot might have. It has a very large user community and is used by a variety of robots in many different industries. It was also mentioned in the job description I was targeting.

ROS uses “nodes”, which are independent software blocks that connect to the ROS subsystem and communicate with each other. Many different nodes have been contributed by users in the community, from PID controllers to GPS signal analyzers, and one of those is ROSBridge. ROSBridge, like the name suggests, creates an interface to ROS using an industry-standard JSON format inside a websocket. This provides a very easy way for a variety of platforms to create robot controllers.

My library, called RBManager (the RB is for ROSBridge), is a wrapper for the SocketRocket websocket library in iOS. I’ve followed the standard publisher/subscriber/service call architecture to send packets compatible with the ROSBridge Protocol and make it easy to send packets and control your robot. The GitHub page provides a general overview of the structure, but I wanted to take this point to provide a more detailed example project.

To follow along, you’ll need to have a reasonable grasp of ROS concepts and know your way around Xcode and the iOS SDK. We’ll be using the standard turtlesim node. Some things I’ll skip through so it’s probably a good idea if you’ve built an iOS app before.


Download RBManager on GitHub


Open Xcode and create a new empty application, with a single view controller. We’ll keep it simple and contain everything into one view. Add the RBManager files to the project, along with the SocketRocket library and import RBManager.h to the header file of your view controller.

Set up header variables and methods

How the view is laid out is up to you, but below are some of the RBManager related objects and methods that should be added to the header file. UI objects are suggestions for outputting the subscriber data.

RBPublisher * twistPublisher;
RBSubscriber * turtleSubscriber;
UILabel * xLabel;
UILabel * yLabel;
UILabel * linearVelocityLabel;
UILabel * angularVelocityLabel;
RBServiceCall * clearTurtle;
RBServiceCall * resetTurtle;


The labels are largely self explanatory — they will be updated with the current position/velocity of the turtle simulator. The RBSubscriber and RBServiceCall objects are provided by the library and provide access to make those calls to ROSBridge.

Introduction to Messages

Messages are the core object that ROS returns from subscribers and RBManager has an RBMessage type that you override to be able to send and receive data in an object-oriented way. There are lots of messages included in ROS but you can also create your own. To see how to do that in RBManager, take a look at the header file VectorMessage.h

@interface VectorMessage : RBMessage {
    NSNumber * x;
    NSNumber * y;
    NSNumber * z;

@property (nonatomic, strong) NSNumber * x;
@property (nonatomic, strong) NSNumber * y;
@property (nonatomic, strong) NSNumber * z;


VectorMessage, which has the form std_msgs/Vector3 in ROS, is a basic object with properties for the keys that ROS expects. By doing it this way, it’s very easy to use Key-Value-Coding to populate a message object inside each subscriber. Some of the standard messages are included already but creating your own type is as easy as specifying the property type and name. You can even use nested messages like TwistMessage, which is what turtlesim uses and is shown below.

@interface TwistMessage : RBMessage {
    VectorMessage * linear;
    VectorMessage * angular;

@property (nonatomic, strong) VectorMessage * linear;
@property (nonatomic, strong) VectorMessage * angular;


By calling publish, you can get back the NSDictionary representation of the message object. This method is included in the top level RBMessage object and uses KVC to get the property list.

If your message object includes additional properties that are not in the ROS message type, you should override publish directly.

Connecting and Disconnecting

RBManager behaves as a singleton, by referencing [RBManager defaultManager]. This prevents multiple instances from being created. To connect to ROSBridge, it’s as easy as calling

[[RBManager defaultManager] connect:@"ws://robot.local:9090"];

where ws://robot.local:9090 is the IP of your robot. The default port of ROSBridge is 9090, but that can be changed. Disconnecting is just as simple, by calling

[[RBManager defaultManager] disconnect];

Adding Publishers and Subscribers

Handling the publishing process is RBPublisher. After this object is added to the manager, it is automatically advertised to ROS and you can push messages through. To create the object, in the case of turtlesim, use the following method

twistPublisher = [[RBManager defaultManager] addPublisher:@"/turtle1/cmd_vel" messageType:@"geometry_msgs/Twist"];
twistPublisher.label = @"Turtle controller";

In this case, the topic is /turtle1/cmd_vel and the message type is geometry_msgs/Twist, which are both expected by ROS. The label property is just a handy way of differentiating multiple publishers, if you have more than one created. Put this declaration inside the view controller init method and they will be automatically advertised when you connect the socket. If you want to manually un/advertise the publisher afterwards, you would use these methods

[twistPublisher advertise];
[twistPublisher unadvertise];

Subscribers behave in a similar fashion. They are added to the manager and subscribed automatically when the socket is opened. The primary difference is that subscribers also take a callback to receive messages that ROS publishes. In the case of turtlesim, that would look like this

turtleSubscriber = [[RBManager defaultManager] addSubscriber:self selector:@selector(turtlePoseUpdate:) name:@"/turtle1/pose" messageClass:[PoseMessage class]];
turtleSubscriber.throttleRate = 100;

-(void)turtlePoseUpdate:(PoseMessage*)message {
    // read the message and update the view here

Here turtlePoseUpdate: is the method in the view controller that will receive the message update, and it only has one parameter. The ROS topic of /turtle1/pose is generated by turtlesim and it provides a message of type PoseMessage. By providing the class type, RBManager can create and populate the correct message. As seen by the ROSBridge specification, the throttleRate is the interval at which ROS will send a message, in milliseconds. This is to prevent overloading the receiver.

Here is what a valid init and subscriber method would look like inside the view controller

- (id)init
    self = [super init];
    if (self) {
        // Custom initialization
        twistPublisher = [[RBManager defaultManager] addPublisher:@"/turtle1/cmd_vel" messageType:@"geometry_msgs/Twist"];
        twistPublisher.label = @"Turtle Controller";
        turtleSubscriber = [[RBManager defaultManager] addSubscriber:self selector:@selector(turtlePoseUpdate:) name:@"/turtle1/pose" messageClass:[PoseMessage class]];
        turtleSubscriber.throttleRate = 100;
    return self;

-(void)turtlePoseUpdate:(PoseMessage*)message {
    xLabel.text = [NSString stringWithFormat:@"%.5f", [message.x floatValue]];
    yLabel.text = [NSString stringWithFormat:@"%.5f", [message.y floatValue]];
    linearVelocityLabel.text = [NSString stringWithFormat:@"%.5f", [message.linear_velocity floatValue]];
    angularVelocityLabel.text = [NSString stringWithFormat:@"%.5f", [message.angular_velocity floatValue]];

Sending Messages

Using an iPhone with ROSBridge is advantageous because the iPhone has an abundance of sensors that are great for controlling robots. That means sending and receiving messages are a very important component. Doing that with RBManager is fairly straightforward. After connecting and advertising a publisher, create a new message object and submit it.

-(void)sendUpdate {
    CGFloat linearVelocity = xAngle * -4.0;
    CGFloat angularVelocity = zAngle * -4.0;
    TwistMessage * twist = [[TwistMessage alloc] init];
    twist.linear.x = [NSNumber numberWithFloat:linearVelocity];
    twist.angular.z = [NSNumber numberWithFloat:angularVelocity];
    [twistPublisher publish:twist];

In this case, xAngle and zAngle are calculated from the accelerometer. If everything is connected after this, you’ll start to see the turtle move.

Using Service Calls

Service calls are important components for monitoring and updating robot configurations. In the case of turtlesim, this includes changing the background, changing the colour of the pen and killing and spawning turtles. You can think of service calls like publishing a message without content, although some calls do return data. RBManager handles both cases, but doesn’t require adding the object to the queue.

// service call without parameters
resetTurtle = [[RBManager defaultManager] makeServiceCall:self selector:@selector(resetTurtleMessageResponse:) name:@"/reset"];
[resetTurtle send];

// service call with specific ROS message
SetPenMessage * penMessage = [[SetPenMessage alloc] init];
penMessage.r = [NSNumber numberWithFloat:red];
penMessage.g = [NSNumber numberWithFloat:green];
penMessage.b = [NSNumber numberWithFloat:blue];
penMessage.width = [NSNumber numberWithFloat:2]; = [NSNumber numberWithInteger:0];
changePenColour = [[RBManager defaultManager] makeServiceCall:self selector:@selector(changePenMessageResponse:) name:@"/turtle1/set_pen"];
[changePenColour setMessage:penMessage];
[changePenColour send];

The calls are not sent immediately because this allows you to assign additional parameters, like the id. The first example shows sending a call without any parameters. The selector is the callback when the response is returned. When there is no data expected back, the most useful thing to get from the response is a success true/false.

Related to service calls is the process for assigning parameters. These are essentially wrapped service calls that call directly to the ROS API. In turtlesim, this is used to change the background colour

// assigning specific parameters
RBServiceCall * backgroundService = [[RBManager defaultManager] setParam:@"background_r" value:[NSString stringWithFormat:@"%.0f", red]];
[backgroundService send];
backgroundService = [[RBManager defaultManager] setParam:@"background_g" value:[NSString stringWithFormat:@"%.0f", green]];
[backgroundService send];
backgroundService = [[RBManager defaultManager] setParam:@"background_b" value:[NSString stringWithFormat:@"%.0f", blue]];
[backgroundService send];

Although the actual service call uses arrays, it’s unfortunately not possible to include more than one parameter at a time so you have to make 3 separate calls.

That is a detailed, but still pretty open example about integrating RBManager into an iOS application. With the touchscreen and motion sensors, it’s pretty easy to now direct your robot to follow a path on the map or move in relation to the accelerometer position. Hopefully this library can make developing and building robots more efficient so please show me what you build with it! If you find an issue, create a ticket on GitHub or comment below and I’ll look into it. I’ll be continuing to develop it over time, particularly when my robot project actually makes use of it.

Tagged with: , , ,