Society of Robots - Robot Forum
Software => Software => Topic started by: madsci1016 on December 04, 2010, 07:55:22 PM
-
Before I go writing my own, does anyone know of a AVR compatible Software Serial library that uses no hardware resources, other then flipping the pin (obviously). I only need TX, so I don't care about RX.
Thanks, my google-fu is failing me.
On second thought, writing my own should be easy since it's TX only.
-
You could probably grab the Arduino SoftwareSerial (polled) and NewSoftSerial (interrupt driven) code and adapt one of them.
since it's TX only.
Yep, roll you're own.
______
Rob
-
AVR compatible Software Serial library that uses no hardware resources, other then flipping the pin (obviously).
You could probably grab the Arduino SoftwareSerial (polled)
I looked at it, but it still relies on a timer to drive the delay functions, so it's no good for me. Thanks though.
I wrote my own, but haven't tested it.
-
WebbotLib lets you only have Tx but if you don't want to use a resource (Timer etc) then it means adding delays into the foreground task so everything else will grind to a halt (which is why WebbotLib doesn't do it that way).
Maybe the ATmel site has some examples.
-
WebbotLib lets you only have Tx
I would have loved to use Webbotlib, but figured if I'd ask you to port it for an ATtiny, I might hear the screams from across the Ocean. ;)
No worries, I whipped one out that works ok. Been a little refreshing coding from scratch.
-
No worries, I whipped one out that works ok. Been a little refreshing coding from scratch.
Did you post the code anywhere? Can you? I'd just like to see what it looks like.
-
Sure, but it may not be the most elegant solution to the experts out there.
#define baud 4800
#define bit_delay 1000000/baud
//write out a byte as software emulated Uart
void serialWrite(byte bite){
digitalWrite(TXPIN, LOW); //signal start bit
_delay_us(bit_delay);
for (byte mask = 0x01; mask; mask <<= 1) {
if (bite & mask){ // choose bit
digitalWrite(TXPIN,HIGH); // send 1
}
else{
digitalWrite(TXPIN,LOW); // send 0
}
_delay_us(bit_delay);
}
digitalWrite(TXPIN, HIGH); //signal end bit
_delay_us(bit_delay);
}
Then, when I want to print something...
string_len = sprintf(string, "Volts: %u.%u Freq %lu.%lu Amps1: %u.%u ", max_volts/10, max_volts%10, (10000000/freq)/10, (10000000/freq)%10, max_amps1/10, max_amps1%10);
for(int i = 0; i< string_len; i++)
serialWrite(string[i]);
-
Looks good to me for a simple bit bang type function. I have written a few on some different platforms and they start out looking very much like that.
On some of those platforms, I wanted higher speeds like 38400 or 115200 and on some I had problems with interrupt processing screwing up the timing. To handle that I have changed from doing the equivalent of calling _delay_us(), to using my system clock for timing, with something like:'
while (delta Clock < bit delay)
;This helped in most cases, except when the interrupt code took too long anyway...
Probably ignore: :)
Obviously one problem with all of these bitbang functions is they eat up a lot of time, especialy at lower speeds like 4800 baud. On a 16mhz processor you eat up something like: 3333 clocks per bit. If your program has nothing else to do, than this is not an issue. I have in the past written a version (H8 assembly language), that used a timer interrupt to drive the bits and have some simple queue code that the main Print function calls. But this can get somewhat tricky and depending on how much time overhead processing takes (H8 you need to save/restore all registers you use, and a save or restore of a 32bit register took 10 cycles. so I you save 5 of these, you just ate up 100 clocks, than add on 10 for rte and 15+ for the processing of the interrupt) you have a bit of overhead... Again at 4800 baud (3333) clocks per bit, this is very doable. But for 115200 (138 clocks per bit), this was a little more tricky...
So again unless you run into issues, I would keep with your KISS version of the code.
Kurt