the Arduino language?

I

Ivan Shmakov

[Cross-posting to news:comp.lang.c.]
"mbed" [ http://www.mbed.org ] Would be another option...
* No need for dedicated toolchains but standard C (or even C++)
programming.

Indeed, I've just discovered that they use a specific "Arduino"
(e. g., [1]) language for the "sketches."

The question is: how this language is different from C (it
surely looks "C-like" enough), and is there any reason to prefer
it over the latter, even if only for 8-bit AVR programming?

TIA.

[1] https://github.com/languages/Arduino

[...]
 
B

BartC

Ivan Shmakov said:
[Cross-posting to news:comp.lang.c.]
"mbed" [ http://www.mbed.org ] Would be another option...
* No need for dedicated toolchains but standard C (or even C++)
programming.

Indeed, I've just discovered that they use a specific "Arduino"
(e. g., [1]) language for the "sketches."

The question is: how this language is different from C (it
surely looks "C-like" enough), and is there any reason to prefer
it over the latter, even if only for 8-bit AVR programming?

I looked at this recently (http://arduino.cc/en/Reference/HomePage). Any
resemblance to C is purely superficial (there don't seem to be any user
functions for example). And in the implementation I saw, it just got
converted to C behind the scenes (where I believe gcc was then used to
compile to machine instructions).

If you know C then just use that instead, if you can figure out how to use
the tools.
 
I

Ivan Shmakov

BartC said:
[...]
* No need for dedicated toolchains but standard C (or even C++)
programming.
Indeed, I've just discovered that they use a specific "Arduino"
(e. g., [1]) language for the "sketches."
The question is: how this language is different from C (it surely
looks "C-like" enough), and is there any reason to prefer it over
the latter, even if only for 8-bit AVR programming?
I looked at this recently (http://arduino.cc/en/Reference/HomePage).
Any resemblance to C is purely superficial (there don't seem to be
any user functions for example). And in the implementation I saw, it
just got converted to C behind the scenes (where I believe gcc was
then used to compile to machine instructions).

Well, as I was able to figure out, it /is/ indeed converted to
C++. The conversion is (as per Arduino.mk from [2], which is
itself derived from [3]):

# the ino -> cpp -> o file
$(OBJDIR)/%.cpp: %.ino
$(ECHO) '#include <Arduino.h>' > $@
$(CAT) $< >> $@

Naturally, Arduino.mk also makes sure that a number of include
directories are added to the search path, and that a number of
libraries are compiled and linked into the resulting binary.

[2] http://packages.debian.org/wheezy/arduino-mk
[3] http://mjo.tc/atelier/2009/02/arduino-cli.html
If you know C then just use that instead, if you can figure out how
to use the tools.

... When last year I've ordered my Arduino Uno board (which I
haven't found much use to this day), it made me wonder, who'd
need that 32 KiB program memory ATmega328P MCU? Now, I've tried
to build this simply-looking 540-line code [4] (with -Os and
-mmcu=atmega8, = 8 KiB) and got the following from the linker:

/usr/lib/gcc/avr/4.7.0/../../../avr/bin/ld: ArduinoISP section `.text' will not fit in region `text'
/usr/lib/gcc/avr/4.7.0/../../../avr/bin/ld: region `text' overflowed by 7112 bytes
collect2: error: ld returned 1 exit status
make: *** [ArduinoISP] Error 1

I understand that there may be certain advantage in using the
libraries they supply. But somehow, I feel that I should try
rewriting this particular piece of code in C, with AVR Libc as
the only library used...

[4] https://github.com/rsbohn/ArduinoISP/blob/master/ArduinoISP/ArduinoISP.ino
 
M

Mel Wilson

Ivan Shmakov w
Indeed, I've just discovered that they use a specific "Arduino"
(e. g., [1]) language for the "sketches."

The question is: how this language is different from C (it
surely looks "C-like" enough), and is there any reason to prefer
it over the latter, even if only for 8-bit AVR programming?

It's C with a small injection of C++ for the libraries. Some "hidden
headers" supply types like "byte" and "word" where a mainstream programmer
would use "uint8_t" and "uint16_t"; and instead of writing a "main"
function, the programmer writes "setup" and "loop" functions which get
wrapped into the actual program as

void main (void) {
setup();
for (;;)
loop ();
}

A real beginner would prefer it because it's wrapped into a complete Arduino
IDE along with peripheral libraries and a bootloader. This provides
everything needed to create a simple project with sensors, actuators and
what not.

A sophisticated user is liable to find that the Arduino packaging has
expropriated some resources and tied the designer's hands. That's when it's
time to either replace the Arduino firmware totally with one's own, or get
down and design ones own board.

I've put a sketch of my own at <http://www.melwilsonsoftware.ca/wiz5100/>
for an illustration of what can be done. Another Arduino-based project is
at <http://codeshield.diyode.com/>

Mel.
 
T

Theo Markettos

In comp.arch.embedded Ivan Shmakov said:
I understand that there may be certain advantage in using the
libraries they supply. But somehow, I feel that I should try
rewriting this particular piece of code in C, with AVR Libc as
the only library used...

I've been using an Arduino Due (Cortex M0) for prototyping purposes:

1. The board is cheap enough for a 1-off compared with the time of messing
about with the toolchain. Untar toolchain, run ./arduino, select example
code, press download button, board is programmed. It's that
straightforward.

2. The documentation often says things like 'Arduino ...' when it actually
means 'AVR Arduino ...'. The documentation for Due is very patchy. I've
had to do rather more googling and making random guesses than I would like.


While I /can/ go bare metal on it, it's not worth the extra time involved.
I'm shipping exactly one unit of this thing, so time is the major factor
here. I've done some fairly complex things (multiplexed LEDs hung off timer
interrupts) in a few lines of code.

Theo
 
I

Ivan Shmakov

(I've used the "plain C" AVRUSB500 firmware instead.)
I've been using an Arduino Due (Cortex M0) for prototyping purposes:

First of all, ARM-based boards seem like a different league. To
drive, say, an ATmega8, in PDIP, placed on a breadboard, one'd
need only a resistor and a button (for the /Reset line; and even
these are optional.) It isn't that simple for ARM's.
1. The board is cheap enough for a 1-off compared with the time of
messing about with the toolchain. Untar toolchain,

But then, doesn't every other contemporary OS include some kind
of package management software? Thus making downloading and
installing GCC (whether AVR, ARM, "native," or some other
variety) essentially a "single-click" operation. (The same
applies to the Arduino IDE, though.)
run ./arduino, select example code, press download button, board is
programmed. It's that straightforward.
2. The documentation often says things like 'Arduino ...' when it
actually means 'AVR Arduino ...'. The documentation for Due is very
patchy. I've had to do rather more googling and making random
guesses than I would like.

My understanding is that the Arduino project relies heavily on
the community for the documentation, etc. It may thus be
beneficial to edit their Wiki pages as you go.
While I /can/ go bare metal on it, it's not worth the extra time
involved.

I tend to agree, as long as the ARM variety is considered.
I'm shipping exactly one unit of this thing, so time is the major
factor here. I've done some fairly complex things (multiplexed LEDs
hung off timer interrupts) in a few lines of code.

Well, the point of my question was: could someone please share
such "complex things in a few lines of Arduino code" examples?

TIA.
 
T

Theo Markettos

In comp.arch.embedded Ivan Shmakov said:
But then, doesn't every other contemporary OS include some kind
of package management software? Thus making downloading and
installing GCC (whether AVR, ARM, "native," or some other
variety) essentially a "single-click" operation. (The same
applies to the Arduino IDE, though.)

It's not the installing that matters, it's writing your first program and
making it do something on your board. The Arduino environment targets
particular boards, and there's a repository of example programs supplied so
you run them and they just work. No hunting for the right header files or
the right compile options, or reading random blogs looking for examples.
My understanding is that the Arduino project relies heavily on
the community for the documentation, etc. It may thus be
beneficial to edit their Wiki pages as you go.

I'm not really confident enough about that - I've got things working, but
am not knowledgeable of the details to write a manual about them.

I've run into a few painful things too. For example, the IDE isn't really
designed to cope with more than one source file. Ditching the IDE turns out
to be nontrivial - I found a Makefile on the web, and eventually got it to
compile (library issues). But the binary I have is different from the one
output from the IDE, and my binary sits there doing nothing. Even for a
trivial LED blink program.
Well, the point of my question was: could someone please share
such "complex things in a few lines of Arduino code" examples?

OK, here's my fading LED mux example. Complicated by the fact that I'm
using HSV rather than RGB to set the colour so I have to convert between the
two. I have a string of 7 tri-colour LEDs with each LED with individual
colour control. There are three common cathodes for each colour and one
anode per LED, as I needed to minimise the wiring (10 pins). I'm using the
Arduino PWM to set the dimming of the cathodes, and then muxing the anodes
using a routine driven by an interrupt. I'm using a third-party timer
library to get timer interrupts on the Due (not sure the standard library
does this yet) and a third-party PWM library because the default PWM
frequency is 1KHz which beats with my interrupt rate and makes the LEDs
flicker. In the standard library you set the PWM duty cycle of a pin with
something like
analogWrite(pin, duty=0 to 255)

I've substantially refactored the code since and merged with a bigger
project, this is my previous version. The motivation is that the LED fading
now happens entirely under interrupts - the foreground task is oblivious
they're happening. This was about three more lines of code.

So you know where to start, setup() and loop() are the two entry points in
an Arduino sketch.

Theo



#include <ARMtimer.h> // third party timer library
#include "pwm01.h"

volatile void ledSwitch();

#define LEDS 7
// run system PWM at 20KHz
#define PWMFREQ1 20000

typedef struct {
int r;
int g;
int b;
} Colour;

Colour ledColour[LEDS];

// pin numbering
int anode[LEDS] = {12, 5, 4, 3, 2, 10, 11};
int blueCathode = 7;
int greenCathode = 9;
int redCathode = 8;

int currentLED=0;

// the setup routine runs once when you press reset:
void setup() {
// set up LEDs - all off
for (int i=0; i<LEDS; i++)
{
pinMode(anode, OUTPUT);
digitalWrite(anode, LOW);
ledColour.r = 0;
ledColour.g = 0;
ledColour.b = 0;
}
pinMode(redCathode, OUTPUT);
pinMode(greenCathode, OUTPUT);
pinMode(blueCathode, OUTPUT);
digitalWrite(redCathode, LOW);
digitalWrite(greenCathode, LOW);
digitalWrite(blueCathode, LOW);

pwm_set_resolution(8); // 8 bits of PWM resolution
pwm_setup( 7, PWMFREQ1, 1); // Pin 7 freq set to "pwm_freq1" on clock B
pwm_setup( 8, PWMFREQ1, 1); // Pin 8 freq set to "pwm_freq1" on clock B
pwm_setup( 9, PWMFREQ1, 1); // Pin 9 freq set to "pwm_freq1" on clock B

// register for our timer interrupt
startTimer(TC1, 0, TC3_IRQn, 2000, selectLED); // run at 2KHz
}

//Convert a given HSV (Hue Saturation Value) to RGB(Red Green Blue) and set
//the led to the color
// h is hue value, integer between 0 and 360
// s is saturation value, double between 0 and 1
// v is value, double between 0 and 1
//http://splinter.com.au/blog/?p=29
void setLedColorHSV(int h, double s, double v, int led) {
//this is the algorithm to convert from RGB to HSV
double r=0;
double g=0;
double b=0;

double hf=h/60.0;

int i=(int)floor(h/60.0);
double f = h/60.0 - i;
double pv = v * (1 - s);
double qv = v * (1 - s*f);
double tv = v * (1 - s * (1 - f));

switch (i)
{
case 0: //rojo dominante
r = v;
g = tv;
b = pv;
break;
case 1: //verde
r = qv;
g = v;
b = pv;
break;
case 2:
r = pv;
g = v;
b = tv;
break;
case 3: //azul
r = pv;
g = qv;
b = v;
break;
case 4:
r = tv;
g = pv;
b = v;
break;
case 5: //rojo
r = v;
g = pv;
b = qv;
break;
}

//set each component to a integer value between 0 and 255
int red=constrain((int)255*r,0,255);
int green=constrain((int)255*g,0,255);
int blue=constrain((int)255*b,0,255);

setColour(red,green,blue,led);
}

/* multiplex LEDs as a background process run from a timer so
* the foreground process can get on with something else
*
* the LEDs themselves use PWM to set the intensity
* so care is required so it doesn't beat with the PWM frequency
*/

volatile void selectLED()
{
// deactivate the previous LED
digitalWrite(anode[currentLED],LOW);
currentLED++;// advance
if (currentLED>=LEDS) currentLED=0;// % LEDS;
// set the colours on the cathodes (low=on, so invert them)
pwm_write_duty(redCathode, 255-ledColour[currentLED].r);
pwm_write_duty(greenCathode, 255-ledColour[currentLED].g);
pwm_write_duty(blueCathode, 255-ledColour[currentLED].b);
// activate the current LED
digitalWrite(anode[currentLED],HIGH);
}


void setColour(int r, int g, int b, int led)
{
ledColour[led].r = r;
ledColour[led].g = g;
ledColour[led].b = b;
}

// the loop routine runs over and over again forever:
void loop() {

for(int hue=0;hue<360;hue++)
{
for (int led=0; led<LEDS; led++)
setLedColorHSV((hue+25*led)%360,1,1,led);
// each LED has a different hue, so we colour sweep
//We are using Saturation and Value constant at 1
delay(5); //each color will be shown for 5 milliseconds
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top