NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Microcontroller Programming » RS232 Bit Banging producing unexpected results.
August 16, 2012 by Finis |
I'm working on a project for dmx lighting. I intend on bit banging both for receiver and transmitter. However, my initial test, bit banging a single char, repetitively. With rs232 protocol, start bit - 8 data bits - 2 stopbits. Transmitted to putty. Is not producing the character i'm expecting. I've tried switching the byte order, inverting the binary, and other things with no avail.
|
---|---|
August 17, 2012 by pcbolt |
Finis - What kind of results are you getting out of PuTTy? Just curious because you have 'byte' set to 'a' first then 0b01000110 later on which seems to be 'b' (little endian version). Do you have an oscilloscope? It would be interesting to see what the output from the MCU looks like. I'm sure you checked this, but just in case, did you set parity to none in PuTTy? I would try a relatively long delay between frames (100 ms maybe). This is tricky the way your code is set up since everything is happening inside the timer interrupt. First you'd have to start with a count variable (16-bit) and add in a flag variable (both global and volatile)...
Then inside the interrupt you can count the number of times it cycles through and only when enough cycles occur do you allow it to send your character. Something like this...
After reading through this a little more, maybe you can just make "bitno" a 16-bit number, add a default case that resets "bitno" to 0 only after it reaches 1000 (instead of inside "case 10"). |
August 17, 2012 by Finis |
Thx for the reply PcBolt, I'm getting "þþþþþþ..." when I assign 'b' to byte. I've tried :
after my switch in the interrupt, still no luck... I did try a few different delay times too... No, I don't have a an oscilloscope. |
August 18, 2012 by pcbolt |
Finis - I had a little break from the project I was working on so I was able to try out your code and test it with an O-scope. The output was as expected showing the bit pattern of '0b01000110' very clearly. However when I measured the time between pulses I got the following:
I used a 100 mSec pause between Tx's (using your cli(); sei(); in case 10). Hyperterminal was showing "B" 0x42 which is odd since I was trying to send 'b' so it was one bit off. I think when it runs through the case statements it is stretching out the timing enough to throw things off. I didn't have time to test it, but I was thinking of pre-loading the next bit value to send and once the interrupt fires, send the bit then spend the rest of the time figuring out the next bit to send and pre-load that one. Should at least be consistent. I'll let you know how it turns out. |
August 18, 2012 by Finis |
Very interesting. I'm surprised there is so much deviation in timing. This may the sort of thing that would benefit from using assembly (might be a good time to learn). esp. since I intend to eventually to bang at 250k baud (4 usec bits). |
August 18, 2012 by Finis |
I've change the structure a bit. tried @ 9600 baud, and I get one character only "ÿ" tried @ 115200 baud, and I get two character only "b0"
|
August 18, 2012 by pcbolt |
Finis - Looks like I've over-thought the matter too much. The trouble is in this statement...
Since the timer takes a full (pre-scaler) clock cycle (17.3 uSec) to go from 6 back to 0, your actually counting 7 ticks (121.1 uSec) instead of 6 (104 uSec). I changed it to...
Everything worked fine. You do have to send LSB first and I did have remnants of my "pre-loader" code installed but it worked like a champ. |
August 19, 2012 by Finis |
PcBolt, Thank you, I've tried this both at 9600 and 115200 baud. It's working now as expected. so to find the desired baud rate: [d / ( 1 / [ clk / p ] ) ] - 1 = r working code:
|
August 20, 2012 by Ralphxyz |
Finis, so now you have working code what exactly is your dmx lighting project? Your code looks interesting how are you going to use it? Ralph |
August 20, 2012 by Finis |
Hi Ralph, Well, I,m interested in building intelligent lighting fixtures for theater and stage. As well as, building controllers. I would like to be able to control my fixtures with a lighting console, etc.. The DMX protocol is interesting. Physically it's RS485. DMX transmit up to 512 channels (slots) of data. where each fixture (light, fog, etc) is set to a channel (or multiple channels). it runs at 250k baud and is based on frames that start with a break. transmission starts with a break - low for 88us then a mark - high for 8us then a 11bit packet is sent all low (1 start bit(low), 8 data bits, 2 stop bits(high)) then another 11bit packet is sent, the byte in this will be data for ch 1 then another 11bit packet is sent, the byte in this will be data for ch 2 then the frame starts over with the break. I've seen AVR code on the net that uses the built in UART. They detect the break by looking for frame errors. I dont like that method as a frame error could be an error and not a break. Seems like a guess, even if it's correct, mostly. Not to mention, not having control over the ch count. As timing can be crucial. I've been reading up on assembly I may try to write this in asm. It's seems easy enough (lol, after a curve) and I could calculate the exact number of clock cycles each operation takes. Pretty neat. Any route from here should be fun... |
Please log in to post a reply.
Did you know that you need to think about wires differently when you're transmitting signals more than a few inches? Learn more...
|