Recent changes RSS feed

 

Bitlash API

Your Arduino C program can interact with Bitlash using the functions documented here. Of course, in the tiny and open world of Arduino most everything is visible globally. So feel free to dive in and call what you need. The entry points documented here are intended to be reasonably well hardened for third party use.


initBitlash(baudrate);

You must call this first, normally from setup(), to initialize Bitlash and set the serial port baud rate.


runBitlash();

You must call runBitlash() from your loop() function to make Bitlash go. The more frequently you call runBitlash(), the more smoothly foreground and background activity will run. If you don't call runBitlash(), nothing will happen.


Example: Simple Integration

This is the minimum possible integration, and in fact it is the bones of the code that you will see at the bottom of bitlashdemo.pde:

simple.pde
void setup(void) {
	initBitlash(57600);
}
 
void loop(void) {
	runBitlash();
	// YourOtherCodeHere();
}

doCommand(char *command);

A simple way to control Bitlash is to use the doCommand() function to execute commands from your code. Your code can call doCommand() to make Bitlash “do stuff” – anything you can type, actually, up to the buffer size limit. Here's a dumb example that leads up to our next big case study: this code spends a lot of energy looking for the precise millisecond to beep at the top of the hour:

void setup(void) {
	initBitlash(57600);
}

void loop(void) {
	runBitlash();
	// beep at the top of the elapsed hour
	if (millis() % (60*60*1000) == 0) doCommand("beep(11,440,1000)")
}

Lots of ways to do this better (read on for one example), but the takeaway point is that your C code can drive Bitlash.


Manipulating Bitlash Variables from C

Bitlash has 26 variables named a through z. These are 32-bit signed integer values. Your code can read and write these values using a few simple functions. This allows your C code to control code running in Bitlash, and vice versa.

You refer to a variable using an integer index in the range [0..25] corresponding to ['a'..'z']. For example, here is how your code could use the getValue command to read out the value of the bitlash variable 't' and put it into the signed long C variable named 'temperature':

void loop(void) {
	...
	long temperature = getValue('t'-'a');	
	...

Here are the three API functions for Bitlash variable manipulation. Examples of their use are shown below in the clock application.

assignVar(char var, long value);

Assigns the (signed long 32-bit integer) value to the indicated Bitlash variable.

assignVar(0,42);		// a=42
// note this stylish notation to calculate the var index:
assignVar('i'-'a', 33);	// i=33

long x = getValue(char var);

Returns the value of the given Bitlash variable.

long temperature = getValue('t'-'a');	

incVar(var);

Increments the designated Bitlash variable.

incVar('i'-'a');		// i++

Example: Macro Tastic Clock

You can open and play with this example code from the Arduino IDE via File / Examples / bitlash / bitlashclock.

Here is an example with some meat on it to show a reasonably complex Bitlash-C integration. The application is a clock, of sorts: the time is stored in Bitlash variables (h for hour, m for minute, and so on) and updated by a C routine based on the passage of millis().

The C routine, called runClock(), also triggers Bitlash macros named onsecond, onminute, onhour, and onday as the appropriate time intervals roll over.

Upload this to your Arduino and you have an easily configurable clock that can Do Bitlash Stuff at appointed times… just add macros.

bitlashclock.pde
 
	time.cpp -- Bitlash API Integration :: Wall Clock Example
 
	Copyright 2008 by Bill Roy.
 
	This is a sample Bitlash API integration.  
 
	It implements clock based on the Arduino millis() timer.
 
	INSTALL
 
	Paste bitlash.cpp and this file time.cpp into an Arduino sketch window.
	Modify loop() to look like this:
 
		void loop(void) {
			runClock();			// <-- add this line
			runBitlash();
		}
 
	Upload and play.
 
 
	CLOCK REGISTERS
 
	The time of the clock is automagically maintained in Bitlash variables:
		h:	the hour
		m:	the minute
		s:	the second
		d:	the day
		e:	the epoch (the value of millis() when d:h:m:s was the time)
 
	Think of these as your time registers.
 
	To set the time, set the variables at the Bitlash prompt:
 
		> h=12;m=30;s=12
 
	A note on 'd': the days variable simply counts the number of days since
	startup.  Implementing better day rollover including end-of-month
	handling with correction for leap years is left as an exercise for the
	reader.  Same with leap seconds.  And time zones.  And daylight savings
	time.
 
	CLOCK UPDATE
 
	The automagic time update happens in the runClock() function, which
	the sketch calls runClock() in loop(), along with runBitlash().  
 
	The runClock() function updates the Bitlash clock variables so that 
	your Bitlash script can use them at any time:
 
		> print "Time: ", h,":",m,":",s
 
 
	CLOCK MACROS: 
 
	The script also demonstrates running commands through the API by automatically
	looking for and running these Bitlash macros, if they are present, on the specified
	time events:
 
		onsecond	runs each second
		onminute	runs each minute at seconds rollover
		onhour		runs each hour at minutes rollover
		onday		runs each day at hour rollover
 
	For example, this will chime the hour on a piezo buzzer at pin 11:
 
		> checknoon := "if i==0: i=12"
		> onhour := "i=h; checknoon; while i--: beep 11,440,200; delay(1000)"
 
	Additional event types like onalarm and onleapsecond are left to the reader. ;)
 
	LICENSE
 
	Bitlash lives at: http://bitlash.net
	The author can be reached at: bill@bitlash.net
 
	Copyright (C) 2008 Bill Roy
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
*****/
 
// variable indexes for epoch, hour, minute, second, and day
#define v_epoch ('e'-'a')
#define v_hour ('h'-'a')
#define v_minute ('m'-'a')
#define v_second ('s'-'a')
#define v_day ('d'-'a')
 
 
//	runClock -- update the clock variables
//
//	call this frequently in loop()
//
void runClock() {
unsigned long now = millis();
unsigned long dt = now - getVar(v_epoch);
 
	if (dt < 1000) return;		// nothing to see
 
	while (dt >= 1000) {		// tally the full seconds
		dt -= 1000;
		incVar(v_second);
		if (getValue("onsecond") >= 0) doCommand("onsecond");
		while (getVar(v_second) >= 60) {
			assignVar(v_second, getVar(v_second) - 60);
			incVar(v_minute);
			if (getValue("onminute") >= 0) doCommand("onminute");
			while (getVar(v_minute) >= 60) {
				assignVar(v_minute, getVar(v_minute) - 60);
				incVar(v_hour);
				if (getValue("onhour") >= 0) doCommand("onhour");
				while (getVar(v_hour) >= 24) {
					incVar(v_day);
					if (getValue("onday") >= 0) doCommand("onday");
					assignVar(v_hour, getVar(v_hour) - 24);
				}
			}
		}
	}
	assignVar(v_epoch, now - dt);	// put back remainder
}
 
api.txt · Last modified: 2010/01/12 10:08 by wikiops