Show Posts
Pages: [1] 2 3 4
1  Using Arduino / Project Guidance / Re: Arduino MEGA Pinout Diagram on: July 14, 2013, 03:54:13 am
Fantastic work, thank you!
2  Community / Bar Sport / Re: Ask your nix questions here instead? on: June 25, 2013, 06:26:52 pm
http://jonathonhill.net/2009-04-23/auto-start-a-shell-script-on-ubuntu-server/

The problem is the startup system can differ from a linux distro to another. And this method may be old already... I'm not in sync with Ubuntu...

And the opposite:
http://www.tainguyen.com/2011/06/12/disable-ubuntu-services-autostart/
3  Community / Bar Sport / Re: Slotted, non-blocking delays against millis() on: June 25, 2013, 10:07:30 am
...
Both ways have applications where they fit better so IMO it's good to know both.

The slotted method is an array-adapted version of single-timer ISR timer solutions I have seen here already so if I don't act like it's big news then please forgive me.


Perfectly agree with you. I didn't presented like a big news, just the joy of a personal accomplishment and, somehow is a "gypsy wagon" thing: you carry with you your own tools and knowledge to the new territories. Thanks for the discussion, code snippet and technical details! 
4  Community / Bar Sport / Re: Slotted, non-blocking delays against millis() on: June 24, 2013, 09:10:32 pm
...
And there is a small savings in cycles using the slotted method that has the down side of requiring an interrupt that may run longer than I would like and can be delayed by serial print.

Yeah, it may be practical for a small number of delays...

Consider that in addition to decrementing slot counters there needs to be a zero check first as you don't want a counter to roll back, do you?
Not needed, look at the type of array and at the logic.
5  Community / Bar Sport / Re: Slotted, non-blocking delays against millis() on: June 23, 2013, 04:48:04 pm
I don't see a real advantage of the slotted delays over what is done with Arduino now.

I don't see slotted delays replacing millis() in Wiring language. I don't even know how to implement it in Wiring as a library, as it needs the array size specified by the user in a header of a library. But in a C language has his advantages over millis(). For every millis() timer (delay), you need a 32bit variable... if, lets say, we use 10 non-blocking delays (well, I don't see how that is needed in a real application but lets pretend that we need them), millis() is using even more Flash and RAM than slotted delays. Even more, at every check, you need to do a subtraction operation. In Wiring language it does not matter too much - at least, not for me, as I use it only for rapid prototyping. But in the industrial and commercial world it matters (but only if you need to move forward).

6  Community / Bar Sport / Re: Slotted, non-blocking delays against millis() on: June 22, 2013, 10:08:52 pm
I know, the read_write_time sketch example it comes with the Arduino Dallas library if I correctly recall... it suppose the configuration string was correctly introduced. I made my example after that, trying to reproduce it.

BTW, interesting forum software!
7  Community / Bar Sport / Re: Slotted, non-blocking delays against millis() on: June 22, 2013, 09:53:20 am
Excepting classes, printf function is another culprit in increasing the code size - alot. Some time ago I did another test between Arduino, Wiring and ATmegaCLib C library, and I avoided to use printf function, compiling an application with PCF8583.

In the following image, we have Arduino on the left, Wiring on the right, and Eclipse in background. For both Arduino and Eclipse I used gcc 4.7 and Wiring came with 4.3.5 version. You can see the resulted code size on each window.

This kind of analysis helps you chose the right tools, libraries, methods when you shrinkify your Arduino projects or go commercial.

comparison-wiring-language-and-c by funlw65, on Flickr

https://code.google.com/p/atmega-clib/source/browse/trunk/ATmega_PCF8583_Serial/main.c

8  Development / Other Software Development / Re: Does a C/C++ PC (not arduino) serial port library exist on Linux? on: June 21, 2013, 05:34:41 pm
See this one
http://qt-project.org/wiki/QtSerialPort
9  Community / Bar Sport / Re: Slotted, non-blocking delays against millis() on: June 21, 2013, 08:35:08 am
Code:
int main ()  { }
Program size (compiled for Uno):
Code:
Binary sketch size: 176 bytes (of a 32,256 byte maximum)
138 bytes if the IDE is using avr-gcc 4.7.3 as is on Linux Fedora19 (I told you, I am maniac)  smiley-grin

Quote
In any case it's only a waste if you need the program space for something else.
True.
10  Community / Bar Sport / Re: Ban Fritzing on: June 21, 2013, 07:48:11 am
Mine is prettier! Anyway, the author was talking about the schematic part, which is horrible compared with any free EDA package.

sheet_breadboard-FreeJALduino by funlw65, on Flickr
11  Community / Bar Sport / Re: EverythingDuino on: June 21, 2013, 07:19:40 am
A Polish guy did a DIY board, named Multiblue EvB!


http://www.blue17.elektroda.eu/projekty/1477

For everything there, you have an Arduino library available, you just need to search for them on Internet.
You can insert there a Sanguino microcontroller (ATmega644P/1284P), or you can modify the design for an ATmega328P micro, or even an Arduino UNO footprint and add your own components. You can do anything you imagine (including laser diodes and stepper drivers for a 3D printer).

The board is nothing else than a DIY enhanced replica to a commercial board, EvB4.3 made by a Polish company (And-Tech) who targeted the Polish Universities.

http://and-tech.pl/produk-testowy/
12  Community / Bar Sport / Re: Slotted, non-blocking delays against millis() on: June 20, 2013, 10:01:41 pm
Well, there are solutions regarding to portability. I mean, you can use a C library designed to support many more microcontrollers, as is ASF from Atmel. I forked libarduino project of Mike and I can use same code (not the one I presented, which is made for Sanguino, without portability in mind) on many ATmega devices and some Arduino boards: http://atmega-clib.googlecode.com. Is possible and Arduino team should consider preparing the people to advance on the next step (the users are evolving anyway). libarduino is a good example. Unfortunately, no updates from a long time.

But again, nothing against Wiring language and what Arduino means.

P.S. No problem for me to make the presented code portable... just inserting some #if 's . millis() is already written by the Arduino team with portability in mind, and slotted, non-blocking delays is based on millis() code - already portable. The non-portable part of the code was the "pinout" - there comes the conditional compiling...
13  Community / Bar Sport / Re: Slotted, non-blocking delays against millis() on: June 20, 2013, 08:56:20 pm
Using slotted, non-blocking delays:
Code:
#ifndef F_CPU
#define F_CPU 16000000U // required by Atmel Studio 6
#endif

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

#define sbi(PORT, BIT) (_SFR_BYTE(PORT) |= _BV(BIT)) // set bit
#define tbi(PORT, BIT) (_SFR_BYTE(PORT) ^= _BV(BIT)) // toggle bit

#define FALSE 0
#define TRUE  1

#define DELAY_SLOTS  3 // the number of non-blocking delays we need
int16_t isr_countdowns[DELAY_SLOTS]; // the array where the "delays" are stored

#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
// the overflow handler is called every 256 ticks.
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))

// the whole number of milliseconds per timer0 overflow
//#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)

// the fractional number of milliseconds per timer0 overflow. we shift right
// by three to fit these numbers into a byte. (for the clock speeds we care
// about - 8 and 16 MHz - this doesn't lose precision.)
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
#define FRACT_MAX (1000 >> 3)

volatile uint32_t timer0_overflow_count = 0;
//volatile uint32_t timer0_millis = 0;
static uint8_t timer0_fract = 0;

#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ISR(TIM0_OVF_vect)
#else
ISR(TIMER0_OVF_vect)
#endif
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
//uint32_t m = timer0_millis;
uint8_t f = timer0_fract, i, j;
i = 1;
//m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
//m += 1;
i = 2;
}

timer0_fract = f;
//timer0_millis = m;
timer0_overflow_count++;
for (j=0; j<DELAY_SLOTS;j++){
if(isr_countdowns[j] > 0){
//
isr_countdowns[j] = isr_countdowns[j] - i;
}
}
}

void timer0_isr_init(void) {
#if defined(TCCR0A) && defined(WGM01)
sbi(TCCR0A, WGM01);
sbi(TCCR0A, WGM00);
#endif
// set timer 0 prescale factor to 64
#if defined(__AVR_ATmega128__)
// CPU specific: different values for the ATmega128
sbi(TCCR0, CS02);
#elif defined(TCCR0) && defined(CS01) && defined(CS00)
// this combination is for the standard atmega8
sbi(TCCR0, CS01);
sbi(TCCR0, CS00);
#elif defined(TCCR0B) && defined(CS01) && defined(CS00)
// this combination is for the standard 168/328/1280/2560
sbi(TCCR0B, CS01);
sbi(TCCR0B, CS00);
#elif defined(TCCR0A) && defined(CS01) && defined(CS00)
// this combination is for the __AVR_ATmega645__ series
sbi(TCCR0A, CS01);
sbi(TCCR0A, CS00);
#else
#error Timer 0 prescale factor 64 not set correctly
#endif
// enable timer 0 overflow interrupt
#if defined(TIMSK) && defined(TOIE0)
sbi(TIMSK, TOIE0);
#elif defined(TIMSK0) && defined(TOIE0)
sbi(TIMSK0, TOIE0);
#else
#error Timer 0 overflow interrupt not set correctly
#endif
}

// check if the time in a specific slot expired
uint8_t check_delay(uint8_t slot)
{
if (slot >= DELAY_SLOTS) return TRUE; //protection against user input error
uint8_t oldSREG = SREG;
cli();
if (isr_countdowns[slot]<=0){
SREG = oldSREG;
return TRUE;
}
SREG = oldSREG;
return FALSE;
}

//set the duration of a delay (in milliseconds) in a specific slot
void set_delay(uint8_t slot, uint16_t ms_time){
if(slot >= DELAY_SLOTS) return; //protection against user input error
uint8_t oldSREG = SREG;

cli();
isr_countdowns[slot] = ms_time;
SREG = oldSREG;
}

void main(void) __attribute__((noreturn));
void main(void) {
// setting (LED) pins as outputs
sbi(DDRD, 5);
sbi(DDRC, 6);
sbi(DDRC, 7);
// init the non_blocking delays
timer0_isr_init();
sei();
// set delays in milliseconds for every LED
set_delay(0, 250);
set_delay(1, 500);
set_delay(2, 750);
while(1){
if(check_delay(0)){
tbi(PORTD, 5);
set_delay(0, 250);
}
if(check_delay(1)){
tbi(PORTC, 6);
set_delay(1, 500);
}
if(check_delay(2)){
tbi(PORTC, 7);
set_delay(2, 750);
}
}
}



Both programs do the same. The code-size results, using the latest ATMEL toolchain, are as follows (I think that the majority of JAL users are maniacs regarding their code size, me included):

Using millis():
Code:
Device: atmega644p

Program:     606 bytes (0.9% Full)
(.text + .data + .bootloader)

Data:         25 bytes (0.6% Full)
(.data + .bss + .noinit)

Using slotted, non-blocking delays:
Code:
Device: atmega644p

Program:     516 bytes (0.8% Full)
(.text + .data + .bootloader)

Data:         11 bytes (0.3% Full)
(.data + .bss + .noinit)
14  Community / Bar Sport / Slotted, non-blocking delays against millis() on: June 20, 2013, 08:55:58 pm
Hi, i will try to make a "short" introduction first and I will try to explain what is all about (my native language is Romanian).

My journey in the microcontroller world started with PICAXE08M microcontroller, thanks to an australian friend and, obviously, I migrated later to true Microchip microcontrollers, where I learned to program them using the JAL language. We have there, inside jallib library collection, a library named timer0_isr_interval where you can define your own non-blocking delays.

Some how, is working like millis() function but in a different way. First, you must set the size of an array corresponding to the number of total non-blocking delays you need in your application. Then, in every cell of that array, you put a number representing the required delay in milliseconds. An interrupt will trigger at every millisecond and instead of a variable increment as in millis, it will decrement the values of every cell until those will equal zero. Periodically, in your program, you will check if your delay has become zero and that means that that delay has just expired and you do the task assigned to that delay. Then, you set the delay again at the initial value.

It is useful in simulating multitasking.

After a while, I decided that is the time to see what are those AVRs, what are they doing, and if their parents knows that! Obviously, as a good PIC programmer, I bricked my first ATmega32 and returned for awhile back to PICs. But I don't like to lose battles so I tried again with an ATmega644P (util I will make an AVR Doctor, my ATmega32 remains bricked). This time I was careful and I succeeded in transforming it into a Sanguino microcontroller. I started exploring Wiring language and I can recognize the educational value and the project completion speed it offers. But i don't like how it waste the microcontroller resources. Because of this, I moved to avr-gcc toolchain and a big help was the project of Mike, libarduino, hosted on googlecode.com.

I don't know yet too much about the interrupts and timers of AVRs but I succeeded in porting the slotted, non-blocking delays from JAL to avr-gcc looking at the millis() example. I decided to compare them and for that I took a project theme where you must simultaneously blink 3 LEDs at different speeds: 250, 500 and 750 milliseconds. So here are the two avr-gcc C examples:

Using millis():
Code:
#ifndef F_CPU
#define F_CPU 16000000U // required by Atmel Studio 6
#endif

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

#define sbi(PORT, BIT) (_SFR_BYTE(PORT) |= _BV(BIT)) // set bit
#define tbi(PORT, BIT) (_SFR_BYTE(PORT) ^= _BV(BIT)) // toggle bit

#define FALSE 0
#define TRUE  1

#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
// the prescaler is set so that timer0 ticks every 64 clock cycles, and the
// the overflow handler is called every 256 ticks.
#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256))

// the whole number of milliseconds per timer0 overflow
#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000)

// the fractional number of milliseconds per timer0 overflow. we shift right
// by three to fit these numbers into a byte. (for the clock speeds we care
// about - 8 and 16 MHz - this doesn't lose precision.)
#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3)
#define FRACT_MAX (1000 >> 3)

volatile uint32_t timer0_overflow_count = 0;
volatile uint32_t timer0_millis = 0;
static uint8_t timer0_fract = 0;

//#if defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
//ISR(TIM0_OVF_vect)
//#else
ISR(TIMER0_OVF_vect)
//#endif
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
uint32_t m = timer0_millis;
uint8_t f = timer0_fract;

m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}

timer0_fract = f;
timer0_millis = m;
timer0_overflow_count++;
}

void millis_init(void) {
#if defined(TCCR0A) && defined(WGM01)
sbi(TCCR0A, WGM01);
sbi(TCCR0A, WGM00);
#endif
// set timer 0 prescale factor to 64
#if defined(__AVR_ATmega128__)
// CPU specific: different values for the ATmega128
sbi(TCCR0, CS02);
#elif defined(TCCR0) && defined(CS01) && defined(CS00)
// this combination is for the standard atmega8
sbi(TCCR0, CS01);
sbi(TCCR0, CS00);
#elif defined(TCCR0B) && defined(CS01) && defined(CS00)
// this combination is for the standard 168/328/1280/2560
sbi(TCCR0B, CS01);
sbi(TCCR0B, CS00);
#elif defined(TCCR0A) && defined(CS01) && defined(CS00)
// this combination is for the __AVR_ATmega645__ series
sbi(TCCR0A, CS01);
sbi(TCCR0A, CS00);
#else
#error Timer 0 prescale factor 64 not set correctly
#endif
// enable timer 0 overflow interrupt
#if defined(TIMSK) && defined(TOIE0)
sbi(TIMSK, TOIE0);
#elif defined(TIMSK0) && defined(TOIE0)
sbi(TIMSK0, TOIE0);
#else
#error Timer 0 overflow interrupt not set correctly
#endif
}

uint32_t millis()
{
uint32_t m;
uint8_t oldSREG = SREG;

// disable interrupts while we read timer0_millis or we might get an
// inconsistent value (e.g. in the middle of a write to timer0_millis)
cli();
m = timer0_millis;
SREG = oldSREG;
return m;
}

uint32_t currentMillis, pLED1Millis = 0, pLED2Millis = 0, pLED3Millis = 0;

void main(void) __attribute__((noreturn));
void main(void) {
sbi(DDRD, 5);
sbi(DDRC, 6);
sbi(DDRC, 7);
millis_init();
sei();
while (1) {
//
currentMillis = millis();
if (currentMillis - pLED1Millis > 250) {
pLED1Millis = currentMillis;
tbi(PORTD, 5);
}
if (currentMillis - pLED2Millis > 500) {
pLED2Millis = currentMillis;
tbi(PORTC, 6);
}
if (currentMillis - pLED3Millis > 750) {
pLED3Millis = currentMillis;
tbi(PORTC, 7);
}
}
}

15  Community / Bar Sport / Re: Ban Fritzing on: June 20, 2013, 05:00:27 pm
Tongue in check comment -

How much support do you think I might get if I start a campaign on the forum to ban all Fritzing circuit images? I think that they belong on the kindergarten wall.

 smiley-cool

If you offer the same amount of support to fritzing team to make that part of Fritzing prettier, then it may be a good idea  smiley-razz Let the "children" to have their fun! Anyway, you must admit that a great effort is required to make a nice schematic using it.

BTW, I find KiCAD electronic schematics much prettier, especially for documentations.
Pages: [1] 2 3 4