Cosa: An Object-Oriented Platform for Arduino programming

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.

majenko:
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.

@majenko

Great work with the UECIDE! I have followed some of its progress. And the work by @pito with getting Cosa to build.

I am aware of the problem with compiling the source. The focus with the include was the sub-directory structuring of header files in Cosa. I see the pragma solution as only temporary and do not see that as a long term solution for the Cosa source code.

I was hoping to delay the transition to a core for Cosa but it seems like this would be the natural next step to make build of the library easier. I wanted to allow Cosa and the Arduino core to coexist so that porting of code to Cosa could be done in increments. Going to a core would allow me to remove all of the Arduino core code and create my own main() and init(). This would remove some ISR conflicts and reduce the footprint with a few hundred bytes.

What would be the optimum structuring of Cosa for the UECIDE build process? Would it be possible to install Cosa as a library and header files? This is what I would like to do later on in the project to achieve more traditional software delivery/install.

BW if would be great if UECIDE link/upload to include the EEMEM section. The Arduino IDE just skips this part and EEMEM variables are not initiated correctly (i.e. the eeprom section is not generated and uploaded).

Cheers!

The core format (what little there is of it) is detailed at http://uecide.org/wiki/index.php/Writing_Cores. The actual format is pretty flexible and you can put what you like where you like, within reason. Any file locations are pointed to by entries in the core.txt file. There's only really 2 or 3 bits to worry about - the "core" or "api" folder, which is where the main Cosa software would be, the "libraries" folder, which would be any importable libraries in the format that the Arduino uses (libname/libname.cpp & libname/libname.h + extra files), and the examples folder (which is actually a hard-coded name at the moment) where your example sketches can go. You can also add a "plugins" directory (again hard coded at this moment in time) where you can put java plugins to be included with the core. The compiler and any tools you need for uploading, like avrdude, can go in a folder in the core too - I usually use a "compiler" and a "tools" folder. These don't have to be included with the core if the user is able to use a compiler or tools installed in the OS somewhere, or you could reference the compiler and tools located in another core (say the avr105 core), as long as that core is installed.

During compilation the .eeprom section of the compiled elf file is stripped out into a separate file (named "${build.folder}/${filename}.eep"), which you can do what you want with. You can craft the upload command to use that .eep file should you wish.

@majenko

Thanks for the link and info. I was considering starting off with a Arduino core and then adapt to UECIDE. Guess the formats/structure are more or less the same.

What I really would like is support for frameworks and binary libraries with header files as a delivery. If I understand the intension of the cores, they came about to allow new custom boards to use Arduino software without updating the "core".

The eeprom stuff I am doing when I need to but it would have been great if the IDE had done this from the start.

Thanks again for your help!

kowalski:
What I really would like is support for frameworks and binary libraries with header files as a delivery.

I have been thinking about this too, but from the PoV of caching core and library pre-compiled code to speed up compilations. The first time you compile a sketch for a board and it compiles the libraries and the core it could put the libraries into .a files (say ~/.uecide/cache/uno/libSPI.a) and store them, along with the core.a file, somewhere it can get at later. Then it just links against the libraries it needs to (-L~/.uecide/cache/uno -lSPI).

I guess it could look for .a files inside the library too if the code is generic enough to do it as one library for all boards - MyLib/libMyLib.a and MyLib/libMyLib.h - if it finds the .a then it links against it instead of compiling .cpp files.

The latest update to Cosa includes a new installation procedure. Cosa is now packaged as an Arduino core and supports Standard Arduino (ATmega328), Mighty (ATmega1248), Mega (ATmega2560) and Tiny (ATtinyX4/X5) out-of-the-box.

To install Cosa download from github and unzip in the Arduino Sketchbook hardware directory.

https://github.com/mikaelpatel/Cosa/archive/master.zip

Restart the Arduino IDE and the Cosa example sketches and board support will be available in the File>Sketchbook> and Tools>Boards> menus.

Advanced users should git clone to allow faster update.

Use the issue handling at github for trouble reports and improvement suggestions. Do not forget "Watch/Star" the repo in github.

http://dl.dropboxusercontent.com/u/993383/Cosa/doc/html/index.html

Cheers!

Here are some details on the new Cosa installation package and core. The Cosa Arduino core contains its own main.cpp and Arduino.h file. The main() function looks like this:

extern void setup(void);
int main(void) __attribute__((weak));
int main(void)
{
  init();
  setup();
  while (1) loop();
  return (0);
}

The function attribute "weak" allows sketches to replace the main() function. The setup() and loop() are the Arduino major sketch functions. For Cosa there is a default loop() function. This is possible as Cosa is an object-oriented event driven framework.

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

The Arduino.h file is required for the Arduino build pre-processing. The Cosa version of this file is more or less empty as all Cosa symbols are handled by the Cosa/Types.h, Cosa/Board.hh and other header files.

The Cosa/Board.hh and sub-directory Board with implementations of the class Board is how variants are handled in Cosa. It replaces the core variants directory with the pins_arduino.h file.

The Board class contains the low-level special function register access functions and pin symbols. This method of implementation allows compiler error detection when building a sketch and high performance. The Cosa object-oriented pin functions are 2-10X faster than Arduino/Wiring. And as the pins are symbols defined in enum's in the Board class the compiler can help detect illegal usage of pins.

The Cosa Arduino core is truly stand-alone. It is easy to include the Arduino core baseline functions if needed. In that case copy them from the Arduino core.

Cheers!

Received a bunch of 74HC595's today (ebay: $2 for 10 pcs) so now I could add and benchmark a shift register based port version for the Cosa LCD support. It uses basically the same method as suggested by @Nadir with three pins for data, clock and latch. And where the latch signal is also used for the LCD enable. Below is the 3-wire schematics from the codegoogle arduinoshiftreglcd project page http://code.google.com/p/arduinoshiftreglcd/.

The shift register port is used a bit different to allow further optimizations later on. Below are the updated LCD benchmark with the initial result for the SR3W support added.

This SR3W implementation uses the Cosa OutputPin serialization function and is "high-level" (i.e. not PORT direct) as the 4-bit parallel version optimization. SPI could be used to boost performance further.

void 
HD44780::SR3W::write4b(uint8_t data)
{
  m_port.data = data;
  m_sda.write(m_port.as_uint8, m_scl);
  m_en.toggle();
  m_en.toggle();
}

Using the different LCD port adapters is easy. The LCD driver is a single source for all versions. It is only the port adapter that needs implementing. This is one of the great OOP design pattern; delegation. Below is a snippet from the LCD benchmark.

// Select the LCD device for the benchmark
#include "Cosa/LCD/Driver/HD44780.hh"
// HD44780::Port port;
HD44780::SR3W port;
// HD44780::MJKDZ port;
// HD44780::DFRobot port;
HD44780 lcd(&port);

The HD44780 LCD device driver implements the abstract class LCD and can be replaced by any other Cosa LCD device driver implementations in the benchmark source code. Again by changing only a few lines. Below is yet another snippet:

// #include "Cosa/LCD/Driver/PCD8544.hh"
// PCD8544 lcd;
// #include "Cosa/LCD/Driver/ST7565.hh"
// ST7565 lcd;
// #include "Cosa/VLCD.hh"
// VLCD lcd;

These are all implementations of the LCD interface and are all benchmarked with the same code. Basically be commenting in/out the LCD to test. Below is a link to the benchmark sketch.

After benchmarking the different LCD port alternatives we can conclude that the Shift Register method has the best cost/performance and can match parallel access methods with a much lower pin count. It would be interesting to see this as part of future Arduino boards/shields.

Cheers!

Here are the latest results after some additional performance tuning and the ATtiny port of SR3W (Shift Register, 3 output pins) and SR3W SPI (USI on ATtiny). The upper table are the new numbers for the Cosa LCD port adapters. The lower table are the numbers from the NewLiquidCrystal library wiki. Measurements are in micro-seconds (total time and per byte written).

The benchmark code is Cosa/CosaLCDbench.ino at master · mikaelpatel/Cosa · GitHub
and is a port of the NewLiquidCrystal library benchmark to Cosa.

The following optimizations where introduced for the SR3W (3 digital output pins, SDA, SCL and EN):

  1. Only six bits are shifted into the register (QA..QF = D0..D3, RS, BT). The two MSB bits are omitted (not used). The back-light control (BT) could be omitted if always on.
  2. The function calls in write8b are manually in-lined (two level call with one virtual member function call) and the shift loop is unrolled for the six bit words, e.g. write of a byte to the LCD.
void 
HD44780::SR3W::write8b(uint8_t data)
{
  m_port.data = data >> 4;
  uint8_t value = m_port.as_uint8;
  for (uint8_t i = 0; i < 2; i++) {
    m_sda.write(value & 0x20);
    m_scl.toggle();
    m_scl.toggle();
    m_sda.write(value & 0x10);
    m_scl.toggle();
    m_scl.toggle();
    m_sda.write(value & 0x08);
    m_scl.toggle();
    m_scl.toggle();
    m_sda.write(value & 0x04);
    m_scl.toggle();
    m_scl.toggle();
    m_sda.write(value & 0x02);
    m_scl.toggle();
    m_scl.toggle();
    m_sda.write(value & 0x01);
    m_scl.toggle();
    m_scl.toggle();
    m_en.toggle();
    m_en.toggle();
    m_port.data = data;
    value = m_port.as_uint8;
  }
#if (I_CPU >= 16)
  DELAY(SHORT_EXEC_TIME);
#endif
}

The SR port access is defined as a bit-field to make access easy. Below is the definition:

  * HD44780 (LCD-II) Dot Matix Liquid Crystal Display Controller/Driver
   * Shift Register 3-Wire Port (SR3W), 74HC595 (SR[pin]), with digital 
   * output pins.
   *
   * @section Circuit
   *   SDA (Arduino:D7/Tiny:D1) => SR:SER[14]
   *   SCL (Arduino:D6/Tiny:D2) => SR:SRCLK[11]
   *   EN (Arduino:D5/Tiny:D3) => SR:RCLK[12]
   *   VCC => /SR:SRCLR[10]
   *   GND => /SR:OE[13]
   *   SR:QA..QD[15,1..3] => LCD:D4..D7
   *   EN (Arduino:D5/Tiny:D3) => LCD:EN
   *   SR:QE[4] => LCD:RS
   *   SR:QF[5] => LCD:BT (Backlight)
   */
  class SR3W : public IO {
  private:
    static const uint16_t SHORT_EXEC_TIME = (6 * I_CPU) / 16;
    union {
      uint8_t as_uint8;
      struct {
	uint8_t data:4;		/**< Data port (P0..P3) */
	uint8_t rs:1;		/**< Command/Data select (P4) */
	uint8_t bt:1;		/**< Back-light control (P5) */
	uint8_t app2:1;		/**< Application bit#2 (P6) */
	uint8_t app1:1;		/**< Application bit#1 (P7) */
      };
    } m_port;
    OutputPin m_sda;		/**< Serial data output */
    OutputPin m_scl;		/**< Serial clock */
    OutputPin m_en;		/**< Starts data read/write */
    ...
  };

The optimized SR3W adapter code is https://github.com/mikaelpatel/Cosa/blob/master/cores/cosa/Cosa/LCD/Driver/HD44780_IO_SR3W.cpp

Please note that the SR3W SPI version is now on par with the 4-bit parallel. The 74HC595 shift register/SPI solution is a simple, fast, cheap and moderate pin count (3 pin) LCD adapter which even works on an ATtiny85.

Cheers!

The latest update of the Cosa LCD Menu System contains some improvement that might be of interest.

  1. The menu controller has been separated from the menu walker class. This is more in line with the Model-View-Control design pattern, Model–view–controller - Wikipedia, and allows multiple and replaceable controllers.

  2. The keypad handler is now a controller.

  3. A controller for rotary encoder with push button has been added.

Below is Arduino Nano running the CosaLCDmenu example sketch with a 16X2 LCD and a rotary encoder. The sketch uses a total of 6 pins; D2..D4 for the rotary encoder (input clock, data and push button), D5..D7 for the LCD SR3W adapter (output clock, data and enable).

The menu declaration is as before. Below is the new setup() with both the LCD port adapter for SR3W and the rotary encoder menu controller.

...
HD44780::SR3W port;
HD44780 lcd(&port);
...
// The menu handler ----------------------------------------------------------
Menu::Walker walker(&lcd, &root_menu);
Menu::RotaryController rotary(&walker);

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

Turning the rotary encoder will step through the menu items or values as expected. The push button is used to select and deselect items and values.

The LCD menu system is part of the Cosa Arduino programming framework. See github for the download and installation instructions. GitHub - mikaelpatel/Cosa: An Object-Oriented Platform for Arduino/AVR

Cheers!

not set in 1.5.2 there is no folder your-arduino-install-directory/hardware/arduino/cores/arduino. therefore copied to the /avr/cores/arduino/.
CosaNRFsensors

C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:30: error: 'DEFAULT' undeclared here (not in a function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c: In function 'analogWrite':
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:107: error: 'OUTPUT' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:107: error: (Each undeclared identifier is reported only once
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:107: error: for each function it appears in.)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:110: error: 'LOW' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:114: error: 'HIGH' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:130: error: 'TIMER0A' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:138: error: 'TIMER0B' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:146: error: 'TIMER1A' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:154: error: 'TIMER1B' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:170: error: 'TIMER2A' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:178: error: 'TIMER2B' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:186: error: 'TIMER3A' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:194: error: 'TIMER3B' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:202: error: 'TIMER3C' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:210: error: 'TIMER4A' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:221: error: 'TIMER4B' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:229: error: 'TIMER4C' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:249: error: 'TIMER5A' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:257: error: 'TIMER5B' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:265: error: 'TIMER5C' undeclared (first use in this function)
C:\Users\masha\Desktop\??????\arduino-1.5.2-cosa\hardware\arduino\avr\cores\arduino\wiring_analog.c:272: error: 'NOT_ON_TIMER' undeclared (first use in this function)

Tell me please on the forum did not find an example of working with viznet 5100.
And as I understand it is not fully completed yet work with the nRF24L01?

@arturmon

Arduino IDE 1.5.2 is not supported right now. Sorry about that.

Try 1.0.5 instead.

The Socket implementation for Ethernet is not yet available. There is not very much interest right now.
The NRF24L01+ Socket implementation works but it is restricted functionality.

Please check the list of supported hardware.

Cheers!

Cosa is now "officially" supported on the latest version of UECIDE - which sports the ability to select between multiple cores for different groups of boards.

Great job! Looking good! Feel like I should be providing you with some feedback but I see that @pito is doing an excellent job. Right now I am focused on yet-another LCD port driver :wink: and adding a few ultra fast ciphers.

Have you tried compiling an empty sketch in UECIDE with the Cosa core?

Below is the Cosa default main(), setup() and loop(). Actually I fixed the local static instance and pure virtual problem in AVR. There where a few functions missing.

#include <avr/io.h>
#include <avr/interrupt.h>

#include "Cosa/Event.hh"
#include "Cosa/Watchdog.hh"
#include "Cosa/LED.hh"

/**
 * The init function; minimum setup of hardware after the bootloader.
 * This function may be overridden.
 */
void init() __attribute__((weak));
void init()
{
   ...
}

/**
 * The default setup function; initiate the watchdog. This function may be
 * overridden.
 */
void setup() __attribute__((weak));
void setup()
{
  // Start the watchdog ticks and push time events
  Watchdog::begin(16, SLEEP_MODE_IDLE, Watchdog::push_timeout_events);

  // Start the built-in LED in alert mode
  static LED builtin;
  builtin.alert_mode();
}

/**
 * The default loop function; event dispatcher. This function may be
 * overridden.
 */
void loop() __attribute__((weak));
void loop()
{
  Event event;
  Event::queue.await(&event);
  event.dispatch();
}

/**
 * The main function. This function may be overridden.
 */
int main(void) __attribute__((weak));
int main(void)
{
  init();
  setup();
  while (1) loop();
  return (0);
}

Yepp, the default, empty sketch will give you the classical blink program but in an event driven style.

Cheers! And keep up the great work.

BW: The Cosa Arduino.h file is great fun. Cosa/Arduino.h at master · mikaelpatel/Cosa · GitHub

Some news on the latest improvements and updates to Cosa.

  1. Two more HD44780 LCD port adapters have been added.
    a. Support for the ERM1602-5 serial interface (3-wire+backlight control).
    b. Support for SR4W, 3-wire+backlight control/8-bit parallel shift register (74HC595) based port. The fastest port adapter yet with an average byte transfer time of 44 us (using Cosa Pin functions and not SPI (yet)). This is over 7X faster that the original LiquidCrystal library with a 74HC595 for $0.20. Below is the wiring. The tricks are i) reusing SCL for the RS signal when pulsing EN, ii) using EN for both the SR latch and LCD enable signal.
    *                         74HC595    (VCC)
   *                       +----U----+    |
   * (LCD D1)------------1-|Q1    VCC|-16-+
   * (LCD D2)------------2-|Q2     Q0|-15-----------(LCD D0)
   * (LCD D3)------------3-|Q3    /OE|-13-----------(GND)  
   * (LCD D4)------------4-|Q4    SER|-14-----------(SDA)
   * (LCD D5)------------5-|Q5   RCLK|-12-----------(EN)
   * (LCD D6)------------6-|Q6   SCLK|-11-----------(SCL)
   * (LCD D7)------------7-|Q7    /MR|-10-----------(VCC)
   *                   +-8-|GND   Q6'|-9
   *                   |   +---------+
   *                   |      0.1uF
   *                 (GND)-----||----(VCC)
   * (LCD RS)---------------------------------------(SDA)
   * (LCD EN)---------------------------------------(EN)
   * (LCD BT)---------------------------------------(BT)
   * (LCD RW)---------------------------------------(GND)

The byte write operation for this LCD port adapter is simply:

void 
HD44780::SR4W::write8b(uint8_t data)
{
  m_sda.write(data, m_scl);
  m_sda.write(m_rs);
  m_en.toggle();
  m_en.toggle();
  DELAY(SHORT_EXEC_TIME);
}
  1. Cryptographer support. See example/test sketches.
    a. Vigenere autokey cipher (1 us per byte). The inner core of the algorithm is the following inline function:
  char encrypt(char c) 
  {
    char res = c + m_key[m_nr++];
    if (m_max != N) m_key[m_max++] = c;
    if (m_nr == N) m_nr = 0;
    return (res);
  }

The line with "if (m_max != N)..." gives the autokey behavior, i.e., the password/phrase and the beginning of the message form the key. Vigenere autokey method requires key size plus 3 bytes.
https://github.com/mikaelpatel/Cosa/blob/master/examples/Cipher/CosaVigenere/CosaVigenere.ino
b. RC4 (2,2 us per byte). The inner core of this method is:

  char encrypt(char c) 
  {
    m_y = m_y + m_state[++m_x];
    uint8_t tmp = m_state[m_x];
    m_state[m_x] = m_state[m_y];
    m_state[m_y] = tmp;
    uint8_t ix = m_state[m_x] + m_state[m_y];
    return (c ^ m_state[ix]);
  }

https://github.com/mikaelpatel/Cosa/blob/master/examples/Cipher/CosaRC4/CosaRC4.ino
RC4 requires more memory; 256 byte state table plus 2 bytes (index m_x/y).

  1. I2C/TWI bus scanner. A Cosa version is available. See examples/TWI/CosaTWIscanner. And this is what is looks like.
#include "Cosa/TWI.hh"
#include "Cosa/IOStream.hh"
#include "Cosa/IOStream/Driver/UART.hh"

IOStream cout(&uart);

void setup()
{
  uart.begin(9600);
  for (uint8_t addr = 3; addr < 128; addr++) {
    twi.begin();
    uint8_t data;
    int count = twi.read(addr, &data, sizeof(data));
    twi.end();
    if (count == sizeof(data)) {
      cout << PSTR("device = ") << hex << addr 
	   << PSTR(":group = ") << (addr >> 3) << '.' << (addr & 0x07)
	   << endl;
    }
  }
}

void loop() {}

Typical output:

device = 0x1e:group = 3.6
device = 0x27:group = 4.7
device = 0x48:group = 9.0
device = 0x50:group = 10.0
device = 0x53:group = 10.3
device = 0x68:group = 13.0

Links:

  1. Documentation http://dl.dropboxusercontent.com/u/993383/Cosa/doc/html/index.html
  2. Download/Install GitHub - mikaelpatel/Cosa: An Object-Oriented Platform for Arduino/AVR
  3. Blog http://cosa-arduino.blogspot.se/

Cheers!

kowalski:
Great job! Looking good! Feel like I should be providing you with some feedback but I see that @pito is doing an excellent job. Right now I am focused on yet-another LCD port driver :wink: and adding a few ultra fast ciphers.

Have you tried compiling an empty sketch in UECIDE with the Cosa core?

Below is the Cosa default main(), setup() and loop(). Actually I fixed the local static instance and pure virtual problem in AVR. There where a few functions missing.

#include <avr/io.h>

#include <avr/interrupt.h>

#include "Cosa/Event.hh"
#include "Cosa/Watchdog.hh"
#include "Cosa/LED.hh"

/**

  • The init function; minimum setup of hardware after the bootloader.
  • This function may be overridden.
    */
    void init() attribute((weak));
    void init()
    {
      ...
    }

/**

  • The default setup function; initiate the watchdog. This function may be
  • overridden.
    */
    void setup() attribute((weak));
    void setup()
    {
     // Start the watchdog ticks and push time events
     Watchdog::begin(16, SLEEP_MODE_IDLE, Watchdog::push_timeout_events);

// Start the built-in LED in alert mode
 static LED builtin;
 builtin.alert_mode();
}

/**

  • The default loop function; event dispatcher. This function may be
  • overridden.
    */
    void loop() attribute((weak));
    void loop()
    {
     Event event;
     Event::queue.await(&event);
     event.dispatch();
    }

/**

  • The main function. This function may be overridden.
    */
    int main(void) attribute((weak));
    int main(void)
    {
     init();
     setup();
     while (1) loop();
     return (0);
    }



Yepp, the default, empty sketch will give you the classical blink program but in an event driven style. 

Cheers! And keep up the great work.

Just tried it - that's really nice :slight_smile:

BW: The Cosa Arduino.h file is great fun. Cosa/Arduino.h at master · mikaelpatel/Cosa · GitHub

Love it :slight_smile:

There's no way to avoid an include at the moment, but it doesn't have to be Arduino.h - the filename is specified in the core config file. Maybe I should have it so if nothing is specified nothing gets included ... Hmmm...

Some news on the latest improvements and additions to the Cosa Arduino framework.

  1. Major rewrite of the DHT11/DHT22 device driver. Update to an event/interrupt driven version which is fully integrated with the Cosa event framework. The traditional procedural variant looks like this (CosaDHT).
DHT11 outdoors(Board::EXT0);
#if !defined(__ARDUINO_TINY__)
DHT22 indoors(Board::EXT1);
#endif

void setup()
{
  // Start trace output stream on the serial port
  uart.begin(9600);
  trace.begin(&uart, PSTR("CosaDHT: started"));

  // Check amount of free memory and size of instance
  TRACE(free_memory());
  TRACE(sizeof(DHT));

  // Start the watchdog for low power sleep
  Watchdog::begin();
  RTC::begin();
}

void loop()
{
  // Sample every 2 seconds
  SLEEP(2);

  // Read and print humidity and temperature
#if !defined(__ARDUINO_TINY__)
  indoors.sample();
  trace << PSTR("indoors: ") << indoors << endl;
#endif
  outdoors.sample();
  trace << PSTR("outdoors: ") << outdoors << endl;
}

The output operator<< for DHT11/22 will write the sampled humidity and temperature to the output stream (LCD, Serial, etc). The active object/event driven variant uses the Cosa default loop() function (CosaDHTevent).

// Example of DHT22 sub-class and periodic member function;
// on_sample_completed() prints current value to the trace stream.
class DHTevent : public DHT22 {
public:
  DHTevent(Board::ExternalInterruptPin pin) : DHT22(pin) {}
  virtual void on_sample_completed() { trace << *this << endl; }
};

// The DHT event object
DHTevent dht(Board::EXT1);

void setup()
{
  // The trace output stream on serial output
  uart.begin(9600);
  trace.begin(&uart, PSTR("CosaDHTevent: started"));

  // Watchdog will issue timeout events
  Watchdog::begin(16, SLEEP_MODE_IDLE, Watchdog::push_timeout_events);
  RTC::begin();

  // The DHT event object is started with default 2 second period
  dht.begin();
}

A program is viewed as a set of active objects communicating by events. The above example the DHT object will sample the sensor every 2 seconds and call the on_sample_completed() virtual member function (callback), which in this example does the trace.

Cheers!

Hi!

Just found Cosa when searching for a good Nexa library for Arduino but I ran into some problems. I downloaded the zip, put the Cosa folder in my sketches/library folder and the Cosa/cores/cosa/Cosa folder in the Arduino/hardware/arduino/cores/arduino folder as you suggested in this post:

1. Download Cosa as a zip file.
2. Unzip in your libraries folder in your sketches folder.
3. Move the Cosa (source/header) folder to the Arduino source/header folder. For 1.0.5 that is the folder "arduino-1.0.5/hardware/arduino/cores/arduino".
Cosa: An Object-Oriented Platform for Arduino programming - #133 by kowalski - Libraries - Arduino Forum

But I get the following (and more) errors:

In file included from C:\Program Files\Arduino\hardware\arduino\cores\arduino/Cosa/Board.hh:37,
                 from C:\Program Files\Arduino\hardware\arduino\cores\arduino/Cosa/Types.h:45,
                 from C:\Program Files\Arduino\hardware\arduino\cores\arduino/Cosa/Pins.hh:29,
                 from MyWirelessProgramming_node.ino:31:
C:\Program Files\Arduino\hardware\arduino\cores\arduino/Cosa/Board/Standard.hh:115: error: expected identifier before numeric constant
C:\Program Files\Arduino\hardware\arduino\cores\arduino/Cosa/Board/Standard.hh:115: error: expected `}' before numeric constant
C:\Program Files\Arduino\hardware\arduino\cores\arduino/Cosa/Board/Standard.hh:115: error: expected unqualified-id before numeric constant
C:\Program Files\Arduino\hardware\arduino\cores\arduino/Cosa/Board/Standard.hh:122: error: 'A0' redeclared as different kind of symbol
C:\Program Files\Arduino\hardware\arduino\variants\standard/pins_arduino.h:49: error: previous declaration of 'const uint8_t A0'

I'm using a bunch of other libraries to I would really love to be able to use the Nexa part of Cosa as a library to, would this be possible? If yes, how?

Awesome work with Cosa btw, seems like the ultimate Arduino library collection!

Hi @englund.

Unfortunately that was an old installation guide (I haven't updated all posts on the forum, just too much work :-(. Cosa is now packaged as an Arduino core and much easier to install. The procedure is in the first post on this topic and in the blog. And below (why wait ;-).

  1. Download the Cosa zip from github.
  2. Unzip the file in your sketchbook/hardware directory. If you do not have a folder named "hardware" in your sketchbook directory please create one before unzipping. If you want rename "Cosa-master" the default git download to "Cosa". In Windows simply drag the Cosa-master directory from the zip file into the sketchbook/hardware directory.
  3. Restart/start Arduino IDE and Cosa will show up as a set of examples and boards.

First test.

  1. Connect an Arduino board.
  2. Select the Cosa board setting and serial port in the tools menu.
  3. Compile the empty sketch.
  4. And see the default setup and loop in action - an event driven blink sketch. Here is the code for the empty sketch (all defaults). Cosa/main.cpp at master · mikaelpatel/Cosa · GitHub

I will have to get back to you with a guide on how to mix Arduino code with Cosa. This was possible "out of the box" before the packaging as a core. Now there is a bit more moving into directories and there might be some extra stuff. I will be back with the details.

BW: The compiler errors that you are getting are from the mixing of Cosa with Arduino/Wiring in the same sketch. You will need to compile Arduino or Cosa in separate files (classes). The conflicting symbols in your sketch are LED and A0. These are defined in Cosa board (as enum values) and they are define/variable in Arduino pins_arduino.h. Cosa is not really yet another Arduino library. It is more an OOP framework for small scale embedded systems. Cosa offers a clear structure, "architecture", for adding device drivers, etc. It does not use malloc/new, free/delete and is very conservative on SRAM usage. Also the whole framework, all classes, compiles from Tiny to Mighty and Mega. That includes all TWI and SPI drivers, LCD, etc.

What other libraries are you using?

Cheers!

PS: The alternative installation, if you interested in following the project more in detail and know a bit about how git works, is:

  1. Create the hardware folder in your sketchbook
  2. git clone from github in that directory
  3. Frequently do a git pull to keep up to date with the development. Cosa is still moving with new libraries, drivers, etc. More or less weekly additions. Todays update is a Touch sensor. Don't forget to "Watch/Star" on github.
    DS.

Not using Cosa here, but I just have to say this:
This freamework looks great! Well thought out and beautifully written & documented.

My hat is off to you!