Cosa: An Object-Oriented Platform for Arduino programming

The next step; a USI based TWI master for ATtiny and the ported LCD support. Below is the LCD benchmark running on a LCD with I2C IO expander and an ATtiny85 (internal clock 8 MHz, internal pull-up). The benchmark result is 39 operations per second (32 characters plus 2 set cursor per op). The result for the Cosa LCD driver with I2C IO on a standard Arduino (Uno, Nano, etc) is 53 fps.

The latest I2C optimizations include packaging larger I2C block (32 IO expander commands for 8 characters) on puts() and write().

Cheers!

Here are the numbers from the latest improvements of the Cosa LCD device driver. The table also contains the ratio compared to the New LiquidCrystal Library benchmark.
https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home#!performance-and-benchmakrs
Please note that the ATtiny84/85 benchmarking uses the internal 8Mhz clock.

Read more on "Arduino Forum :: Using Arduino :: Displays :: Cosa/Boosting LCD 1602 I2C performance beyond 130 fps" Cosa/Boosting LCD 1602 performance (7X SR4W, 6.5X 4-bit parallel, 1.7-2.3X I2C) - #27 by kowalski - Displays - Arduino Forum and the blog Cosa: Object-Oriented LCD management

Cheers!

Every time I see your pictures with your 8pin attiny it comes across my mind how difficult would be to port Cosa onto LPC810M (8pin DIP as well) :slight_smile:

pito:
Every time I see your pictures with your 8pin attiny it comes across my mind how difficult would be to port Cosa onto LPC810M (8pin DIP as well) :slight_smile:

LOL - Guess that would be in another forum!

Anyway after browsing through the LPC810M spec I actually think the ATtiny85 has the better cost/performance, though 1Kbyte SRAM is a small improvement, 4Kbyte PROGMEM is very limiting.

When the Arduino/AVR Cosa project starts to drops in velocity I will need to considering porting to other micro-controllers or starting a new project. ARM is the obvious next step even if it will not happen shortly as I still have tons to do.

Cheers!

If you ever think about porting it to LPCs (122x especially) let me know.


Rob

The Cosa CosaBenchmarkPins.ino has been successfully built within the new UECIDE with Cosa library located in libraries..
http://forum.arduino.cc/index.php?topic=176498.msg1319940#msg1319940
:slight_smile:

pito:
The Cosa CosaBenchmarkPins.ino has been successfully built within the new UECIDE with Cosa library located in libraries..
UECIDE: A New Fork of the IDE - #95 by pito - Libraries - Arduino Forum
:slight_smile:

@pito

Great job! Thanks for testing that. Appreciate any feedback from the port to UECIDE. Read some of the dialogue in the topic above. And there seems to be some alternative installation strategy i.e. Cosa as a core instead of within the Arduino core.

As Cosa has grown build speed is becoming vital. I see that this has been discussed and is being addressed. Hope that a solution will soon be available also for the Arduino IDE.

Cheers!

A new Cosa blog post is available. It is an introduction to the Cosa 1-Wire device driver support. The example sketch is a simple DS1990A iButton reader.

Cheers!

Graynomad:
If you ever think about porting it to LPCs (122x especially) let me know.

@Graynomad

What LPC122X development board/environment would you recommend? The hardware resources in the LPC122X have much in common with the ATmega so this might be of interest later on this fall.

The current Cosa project backlog top five are:

  • SR (74HC595) LCD IO driver
  • LCD menu system
  • Sensor driver framework and some additional sensors 9-10DOF, etc
  • Next increment on the Socket and NRF24L01+ driver
  • Socket/Ethernet driver

Cheers!

What LPC122X development board/environment would you recommend?

I can't compare them because I've only used one, that being the LPCXpresso board and IDE (Eclipse-based). I'm well happy with both, the boards cost 20 Euro and the IDE is free for C, not for C++ although I believe it's easy enough to use it for C++, just not as turnkey as one might like.

I reckon the LPC1227 is roughly equivalent to the Mega1284, both are "just right" in terms of features IMO.


Rob

BTW, LPC11xx, LPC11Uxx, LPC12xx, LPC13xx are similar, and there is almost no difference at c source level with drivers. I've been toying with lpcxpresso 1343 and 11U14. For the purpose of Cosa port you may consider all the same (maybe except USB and DMA stuff). All have got an uart bootloader in a rom, plus other drivers there (it depends on the model).

I already have a lot of Arduino-like code written for the 122x, pinMode, digitalWrite, Serial etc. It's all C but I plan move it to C++ before too long.

One of my next jobs is to separate the 122x-specific stuff into files to help get it running on the other models.


Rob

Graynomad:
I already have a lot of Arduino-like code written for the 122x, pinMode, digitalWrite, Serial etc. It's all C but I plan move it to C++ before too long.

One of my next jobs is to separate the 122x-specific stuff into files to help get it running on the other models.


Rob

Fancy building a core for UECIDE?

Fancy building a core for UECIDE?

Yeah, when I get back onto that project. Not that I understand the way it works, do you have separate "cores" for each target board/CPU? Maybe answer that back on your thread rather than high jacking this one. Maybe you already described that somewhere I missed or forgot after 13 pages :slight_smile:

I've been following your UECIDE thread but at 100M per download can't afford to grab every change, I'll have to wait for it to stabilise a bit.


Rob

Graynomad:

Fancy building a core for UECIDE?

Yeah, when I get back onto that project. Not that I understand the way it works, do you have separate "cores" for each target board/CPU? Maybe answer that back on your thread rather than high jacking this one. Maybe you already described that somewhere I missed or forgot after 13 pages :slight_smile:

I've been following your UECIDE thread but at 100M per download can't afford to grab every change, I'll have to wait for it to stabilise a bit.


Rob

I'm doing some work on the WIki for it - starting with how to write a core :wink:

There is a tiny (relatively) upgrade package generated along with the standard installations which just contains the java components and support files. This can be extracted over the top of an existing installation to upgrade it to the latest version. This won't upgrade any cores or boards, and doesn't include any of the platform specific executables.

One day this package will form the basis of the auto-update facility :wink:

Graynomad:

Fancy building a core for UECIDE?

Maybe answer that back on your thread rather than high jacking this one.

Would appreciate that :wink: though I think the work you @majenko are doing on UECIDE and @pito for porting Cosa into this new IDE project is great. Hope to get time to have a closer look soon.

Cheers!

The latest addition to Cosa is a LCD menu system. It ties into the Cosa LCD and Keypad device drivers.

The design is data-driven and uses program memory for all static data, e.g. menu items, lists, strings, etc. This gives a very compact design. The Menu support also allows simple access and change of program state such as enumeration, bitset and integer range variables. A supporting macro set hides all of the details of creating the data structures in program memory. Below are some snippets to give a feel for the declarative programming style.

First, creating a menu item with an action function. As most of the Cosa design this is object-oriented with a support class Menu::Action. The object can hold the state necessary for the implementation of the action.

#include "Cosa/LCD/Driver/HD44780.hh"
#include "Cosa/Menu.hh"

// Use the HD44780 LCD driver with 4-bit parallel port and keypad shield
HD44780::Port port;
HD44780 lcd(&port);

// Menu Action ---------------------------------------------------------------
// Menu item with binding to action function and state (object)
// 1. Create an action handler by sub-classing Menu::Action

class FileOpenAction : public Menu::Action {
public:
  virtual void run(Menu::item_P item) 
  {
    lcd.display_clear();
    lcd.puts_P(PSTR("opening file..."));
    SLEEP(2);
  }
};

// 2. Create an instance and bind to a menu item.
FileOpenAction do_open;
MENU_ACTION(open_action,"Open",do_open)

// 3. Add to a menu item list.
MENU_BEGIN(file_menu,"File")
MENU_ITEM(open_action)
MENU_END(file_menu)

Selecting "File" from the "Demo" root menu the first item, "Open", in the sub-menu is shown as the title.

Selecting this item will execute the action function.

Second snippet creates enumeration symbols and mapping from a menu item to program state. When the item is selected the up/down buttons will allow change of the associated value. The current value is shown as the enumeration item string. These configuration/control variables are collected in an "Options" sub-menu in "Edit". Please note that the menu system data structures handle the mapping between the binary and textual representation of the value.

// Menu Enumeration Variable -------------------------------------------------
// Menu item with enumeration to change program state
// 1. Define the symbols needed for the enumeration type
MENU_SYMB(on_symb,"On")
MENU_SYMB(off_symb,"Off")

// 2. Define the enumeration type
MENU_ENUM_BEGIN(onoff_enum_t)
  MENU_ENUM_ITEM(off_symb)
  MENU_ENUM_ITEM(on_symb)
MENU_ENUM_END(onoff_enum_t);

// 3. Create a menu item with reference to program state to control
uint16_t tracing = 1;
MENU_ENUM(onoff_enum_t,tracing_enum,"Tracing",tracing)

Selecting the "Edit" and "Options" will take us to the above settings.

Selecting the "Tracing" item will allow us to change the tracing state. In modify mode the menu item title is prefixed with an asterisks.

Third snippet shows mapping from a menu item to an integer range variable. When selected the up/down keys will allow the variable to be changed within the given range.

// Menu Integer Range Variable -----------------------------------------------
// Menu item with integer range(low..high) to change program state change
// 1. Create menu item with integer range and reference to variable
int16_t limit = 42;
MENU_RANGE(limit_range,"Limit",-10,100,limit)

// 2. Add menu item to menu item list
MENU_BEGIN(options_menu,"Options")
  MENU_ITEM(tracing_enum)
  MENU_ITEM(state_enum)
  MENU_ITEM(limit_range)
MENU_END(options_menu)

The integer range menu item will show the lower and upper value in modification mode. The up/down keys will handle decrement/increment of the variable.

The enumeration symbol lists may also be used for bitset, i.e. to create configuration variables with one-or-many selection.

Below is a snippet that allows setting of a number of debug attributes. Selecting the menu item will allow adding/removing attributes for the set.

// Menu Bitset Variable ------------------------------------------------------
// Menu item with bitset to change program state
// 1. Define the symbols needed for the enumeration type
MENU_SYMB(break_symb,"Break")
MENU_SYMB(mockup_symb,"Mockup")
MENU_SYMB(profile_symb,"Profile")
MENU_SYMB(trace_symb,"Trace")

// 2. Define the enumeration type. Symbol order is the value set (0.3).
MENU_ENUM_BEGIN(debug_enum_t)
  MENU_ENUM_ITEM(break_symb)
  MENU_ENUM_ITEM(mockup_symb)
  MENU_ENUM_ITEM(profile_symb)
  MENU_ENUM_ITEM(trace_symb)
MENU_ENUM_END(debug_enum_t);

// 3. Create a menu item with reference to program state to control
// The enumeration type values are bit positions. The initial value is
// Break | Mockup.
uint16_t debug = 3;
MENU_BITSET(debug_enum_t,debug_enum,"Debug",debug)

// The Edit sub-menu with Options and Debug settings
MENU_BEGIN(edit_menu,"Edit")
  MENU_ITEM(options_menu)
  MENU_ITEM(debug_enum)
MENU_END(edit_menu)

Selecting an item in the bitset with toggle the corresponding bit in the control variable.

A Menu::Walker class handles all of the details of stepping through the menu tree and decoding the key events. The walker keeps track of the path through the menu tree and handles the select/up/down/left/right keypad button events. Below is the setup/loop snippet. It is pure event driven.

// The walker will receive key events from the keypad
Menu::Walker walker(&lcd, &root_menu);

void setup()
{
   Watchdog::begin(16, SLEEP_MODE_IDLE, Watchdog::push_timeout_events);
   lcd.begin();
   lcd.puts_P(PSTR("CosaLCDmenu: started"));
   SLEEP(2);
   walker.begin();
}

void loop()
{
  Event event;
  Event::queue.await(&event);
  event.dispatch();
}

See the full example sketch on github (or in the Cosa/examples directory):
https://github.com/mikaelpatel/Cosa/blob/master/examples/Sandbox/CosaLCDmenu/CosaLCDmenu.ino

The LCD menu class documentation: http://dl.dropboxusercontent.com/u/993383/Cosa/doc/html/dc/db6/Menu_8hh.html

Cheers!

To try the above Cosa menu example (CosaLCDmenu.ino) with the new UECIDE you may:

  1. Place Cosa's library ("Cosa") and Cosa's examples ("Examples") folders into your Sketchbook directory - into "libraries\Cosa" folder, for example:
C:\MyCode\Arduino\libraries\Cosa\Cosa
C:\MyCode\Arduino\libraries\Cosa\Examples
  1. Place this #pragma at the beginning of the CosaLCDmenu.ino sketch, for example:
..
 * Baseline(Watchdog, LCD) 4006 bytes, +Menu::Walker 6430 bytes 
 * and +Demo menu code 6678 bytes.
 *
 * This file is part of the Arduino Che Cosa project.
 */

#pragma parameter extension=C:\MyCode\Arduino\libraries\Cosa 

#include "Cosa/Watchdog.hh"
#include "Cosa/LCD/Driver/HD44780.hh"
#include "Cosa/Menu.hh"
..
  1. As the result of the build process you may get (built for Mighty1284p)
Program Size:
  Flash: 6608 bytes
  RAM:   400 bytes

@pito
Nice job! Looking good :wink:

If it is possible to add an "-I." (allow include path expansion from current directory) to the IDE compiler option it should be possible to remove the need for the pragma and the modification of the example sketch code.

Thanks for your effort of getting Cosa up and running in this new IDE.

Cheers!

kowalski:
@pito
Nice job! Looking good :wink:

If it is possible to add an "-I." (allow include path expansion from current directory) to the IDE compiler option it should be possible to remove the need for the pragma and the modification of the example sketch code.

Thanks for your effort of getting Cosa up and running in this new IDE.

Cheers!

Adding the -I for include files is simple enough, but that won't include the source (.cpp) files. The #pragma tells the compiler to include those files into the compilation of the core.a library file.