Hi,
I have a setup with arduino (code formatted for lilypad) running on a atmega168 using the internal oscillator of 8mhz, and running at 3.3volts.
it is sending serial commands to a xbee, which works fine. I would also like to monitor the atmega chip using AFsoftserial, but are having problems gettting anything but garble.
I have tried different pins, different cables etc, and I am pretty sure the hardware and electronics works fine.
I have run the exact same code on a arduino diecimila, and AFsoftserial works fine.
So, first of all, does AFsoftserial work with 8mhz setup? I believe I have seen posts where people are using lilypad and AFsoftserial so I would assume it would work?
Any obvious things I could be missing?
best,
hc
AFsoftserial on a stripped down arduino
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
-
- Posts: 1645
- Joined: Sat Nov 10, 2007 12:59 am
i took a look at the soft serial library and noticed this bit of code, which i'd guess is a timing delay. there is no similar conditional for f_cpu = 8MHz, so this may be your problem.
first of all, if this code compiles at all for you your board is not defined as a lilypad to the arduino environment, so i don't understand why your serial comms to the xbee is working.
second, i am not an avr assembler programmer, mostly because i'm too dim to figure out how the inline assembly embedding works in gcc.
but i'll take a crack at interpreting the snippet above.
changing the subtrahend, (wow, never thought i'd use that word again), of the sbiw instruction to 0x02 should make this work at 8MHz but, alas, only if delay is odd. i'll have to do a little research into how the avr processor flags work before i can give you an actually useful answer.
Code: Select all
#if (F_CPU == 16000000)
void whackDelay(uint16_t delay) {
uint8_t tmp=0;
asm volatile("sbiw %0, 0x01 \n\t"
"ldi %1, 0xFF \n\t"
"cpi %A0, 0xFF \n\t"
"cpc %B0, %1 \n\t"
"brne .-10 \n\t"
: "+r" (delay), "+a" (tmp)
: "0" (delay)
);
}
#endif
second, i am not an avr assembler programmer, mostly because i'm too dim to figure out how the inline assembly embedding works in gcc.
but i'll take a crack at interpreting the snippet above.
Code: Select all
sbiw %0, 0x01 - subtracts 1 from delay
ldi %1, 0xFF - loads -1 to temp
cpi %A0, 0xFF - compare low order byte of delay to -1
cpc %B0, %1 - compare high order byte of dela to temp, (with carry)
brne .-10 - repeat if not equal
: "+r" (delay), "+a" (temp) - this tells us the first param is delay and the second is temp
: "0" (delay) - this tells us that delay will not survive
- hcgilje
- Posts: 75
- Joined: Fri Aug 15, 2008 8:51 am
hi,
thanks for taking the time to look into it!
I am no assembly programmer myself, so not sure if I will be able to resolve this on my own if it is a programming issue in the AFsoftserial code.
maybe I was a bit unclear in my post, I am using the hardware serial for communicating with the xbee, not the AFsoftserial.
I verify my arduino sketches as lilypad, and then upload without a bootloader from terminal with the aspusb programmer I have, this works fine.
hc
thanks for taking the time to look into it!
I am no assembly programmer myself, so not sure if I will be able to resolve this on my own if it is a programming issue in the AFsoftserial code.
maybe I was a bit unclear in my post, I am using the hardware serial for communicating with the xbee, not the AFsoftserial.
I verify my arduino sketches as lilypad, and then upload without a bootloader from terminal with the aspusb programmer I have, this works fine.
hc
-
- Posts: 1645
- Joined: Sat Nov 10, 2007 12:59 am
no, that was clear. what i meant was that the AFsoftserial code should fail to compile if the arduino environment knows that you're using a lilypad, because the symbol F_CPU would then be set to 8000000 causing the conditional to evaluate false and keeping the whackdelay function from compiling. maybe i didn't look at enough of the code.hcgilje wrote: maybe I was a bit unclear in my post, I am using the hardware serial for communicating with the xbee, not the AFsoftserial
this looks like a fun problem, (i.e. i don't have to get anything to compile or run), so i'll be happy to waste a little more time on it.
- hcgilje
- Posts: 75
- Joined: Fri Aug 15, 2008 8:51 am
much appreciated!mtbf0 wrote:this looks like a fun problem, (i.e. i don't have to get anything to compile or run), so i'll be happy to waste a little more time on it.
I just hope its not something really simple not related to code, but I am 97% sure I haven´t done anything really stupid.
btw, the arduino circuit will be the brain of my wind-up birds, a network of mechanical woodpeckers, some photos here:
http://flickr.com/photos/hcgilje/sets/7 ... 588267198/
hc
-
- Posts: 1645
- Joined: Sat Nov 10, 2007 12:59 am
this is a pretty stupid idea, but since the afsoftserial stuff is hardcoded for a 16MHz clock and you're running at 8MHz so everything takes twice as long, you might get away with selecting a baud rate twice what you are really aiming for. so if you want 9600 baud, try
i don't really understand why there isn't a linear relationship between baud rate and _bitdelay
Code: Select all
mysoftserial.begin(19200);
-
- Posts: 1645
- Joined: Sat Nov 10, 2007 12:59 am
cool. stupid rules!hcgilje wrote:
your stupid idea works!
i now understand why the relationship between baud rate and _bitdelay is non linear.
ideally, _bitdelay = (F_CPU + (BAUD / 2)) / BAUD
the (BAUD / 2) term takes care of rounding, so _bitdelay is the number of clock cycles per second divided by the number of bits transmitted per second. unfortunately, there is a rather large chunk of code involved in processing the bits as they pass through. one must also account for the number of clock cycles used in each pass through the wait loop. in the case of AFSoftserial this looks to be either 5 or 6. 6, i think.
so the real world _bitdelay will be the (ideal_bitdelay - some_number_of_cycles_to_process_each_bit) / wait_loop_length.
so it should be possible to work backwards from AFSoftserial to calculate the constant that is subtracted from the ideal _bitdelay and recalculate the whole mess for an 8MHz clock.
maybe when i get home.
what i still don't understand is how you got the hardware serial port to work and the AFSoftserial to compile at the same time. for the hardware serial to work you would have had to have F_CPU defined as 8000000 which would have caused the conditional compilation of whackDelay to not take place, which in turn should have caused all kind of nastiness when it came time to link.
oh, well.
- jsc
- Posts: 13
- Joined: Wed Nov 05, 2008 1:58 pm
Re: AFsoftserial on a stripped down arduino
I've been trying to make sense of the assembly delay loop. From my reading of the data sheet, it should take up delay * 7 + 6 clock cycles:
sbiw takes 2; ldi, cpi, and cpc take 1, brne takes 2 when the branch is taken and 1 when not.
The loop runs delay+1 times through, since it counts down from delay to -1.
This confuses me, because then the calculations of the bit delays for various baud rates don't come out exactly right. For example, at 9600 baud, the bit delay is given as 113:
1 / ((113 * 7 + 6) / 16000000 * 2) = 10038 baud, slightly faster than it should be.
How were these numbers calculated? And is my calculation correct?
sbiw takes 2; ldi, cpi, and cpc take 1, brne takes 2 when the branch is taken and 1 when not.
The loop runs delay+1 times through, since it counts down from delay to -1.
This confuses me, because then the calculations of the bit delays for various baud rates don't come out exactly right. For example, at 9600 baud, the bit delay is given as 113:
1 / ((113 * 7 + 6) / 16000000 * 2) = 10038 baud, slightly faster than it should be.
How were these numbers calculated? And is my calculation correct?
- manu12
- Posts: 9
- Joined: Tue Apr 16, 2013 8:52 am
Re:
Thank you for this explanation! I was stuck asking myself if is AFsoftserial/newsoftserial is using one of the 3 timers of the ATmega328. In the end, it seems it doesn't.mtbf0 wrote:i took a look at the soft serial library and noticed this bit of code, which i'd guess is a timing delay. there is no similar conditional for f_cpu = 8MHz, so this may be your problem.
...
but i'll take a crack at interpreting the snippet above.
Code: Select all
sbiw %0, 0x01 - subtracts 1 from delay ldi %1, 0xFF - loads -1 to temp cpi %A0, 0xFF - compare low order byte of delay to -1 cpc %B0, %1 - compare high order byte of dela to temp, (with carry) brne .-10 - repeat if not equal : "+r" (delay), "+a" (temp) - this tells us the first param is delay and the second is temp : "0" (delay) - this tells us that delay will not survive
- johnoh
- Posts: 2
- Joined: Mon Sep 17, 2012 4:30 am
Re: AFsoftserial on a stripped down arduino
Hi manu12,
Did you get any values together for 8MHz operation? The technique of using 19k2 for a 9k6 on a 8MHz works a treat but I would like to tidy it up somewhat.
Did you get any values together for 8MHz operation? The technique of using 19k2 for a 9k6 on a 8MHz works a treat but I would like to tidy it up somewhat.
- manu12
- Posts: 9
- Joined: Tue Apr 16, 2013 8:52 am
Re: AFsoftserial on a stripped down arduino
Hello,JohnOH wrote:Hi manu12,
Did you get any values together for 8MHz operation? The technique of using 19k2 for a 9k6 on a 8MHz works a treat but I would like to tidy it up somewhat.
I didn't try this by myself.
Maybe it could do the trick if you select an 8MHz board in the Arduino IDE (Arduino Pro or Pro Mini (3.3V, 8MHz) w/ ATmega328)?
- johnoh
- Posts: 2
- Joined: Mon Sep 17, 2012 4:30 am
Re: AFsoftserial on a stripped down arduino
Thanks, I have it working fine. I would however like to have it set up correctly to avoid confusion in the code.
Please be positive and constructive with your questions and comments.