Why can't I get Serout to work
I have my encoders working and now I want to get the counts to my "Propeller".· If I send 2400 Baud from my Stamp2 for instance·the propeller gets the data·perfectly, but when I send them from my SX/B program I can't get it to work.
I know it has something to do with the interrupts, but I'm not really versed on how to calculate the Clock cycles it consumes.
How would I calculate a baud rate that will actually send 2400?
Thanks,
Eric
I know it has something to do with the interrupts, but I'm not really versed on how to calculate the Clock cycles it consumes.
How would I calculate a baud rate that will actually send 2400?
DEVICE SX28, OSCHS2, TURBO, STACKX, OPTIONX, BOR42 FREQ 50_000_000 ID "ENCODER" EncPort VAR RA ' encoder port TRIS_Enc VAR TRIS_A MaxVal CON 255 'encCheck VAR Byte EncodersOld VAR byte EncodersNew VAR byte Encoder_A_Count VAR byte Encoder_B_Count VAR byte tmpB1 VAR byte tmpB2 VAR Byte tmpB3 VAR Byte ' ========================================================================= INTERRUPT ' ========================================================================= ' Runs every 64 uS @ 4 MHz (no prescaler) ISR_Start: EncodersNew = EncPort TmpB1 = EncodersOld XOR EncodersNew ' compare old with new ' to work out which channels have changed TmpB2 = TmpB1 << 1 ' make single bit that shows change on A or B phase TmpB1 = TmpB1 OR TmpB2 EncodersOld = EncodersOld << 1 ' make direction bits by comparing old A with new B EncodersOld = EncodersOld XOR EncodersNew ' xor old A with new B IF TmpB1.3 = 1 THEN IF EncodersOld.3 = 1 THEN INC Encoder_A_Count ELSE DEC Encoder_A_Count Encoder_A_Count Min 0 ENDIF ENDIF ' ========================================================================= IF tmpB1.1 = 1 THEN IF EncodersOld.1 = 1 THEN INC Encoder_B_Count ELSE DEC Encoder_B_Count Encoder_B_Count Min 0 ENDIF ENDIF EncodersOld=EncodersNew 'ISR_Exit: RETURNINT ' ========================================================================= PROGRAM Start NOSTARTUP ' ========================================================================= Start: EncodersNew = EncPort EncodersOld = EncodersNew Encoder_A_Count = 0 Encoder_B_Count = 0 OPTION = $88 ' interrupt, no prescaler Main: Do Serout RC.7,T2400,Encoder_A_Count LOOP
Thanks,
Eric
Comments
It seems that what you are trying to attempt may be rather tricky. If your ISR was designed such that each and every time it was called it took exactly the same number of clock cycles to complete, then the solution might be as easy as adjusting the effective frequency passed to the compiler. The compiler would then make adjustments to the serout routine so that the internal timing would work out correctly. Unfortunately, your ISR seems to be capable of taking variable length paths based upon encoder information and that can not be completely predicted and taken into account.
Some Considerations
1) Given that 2400 baud is such a slow baud rate, have you confirmed that it is indeed the ISR that is causing your problem? If you disable interrupts, is data transmitted correctly?
2) Have you considered using a synchronous serial transfer like the one provided by the 'shiftout' command? Granted, it will require the use of one or two additional pins, but the advantage of a synchronous transfer is that the clock rate can vary a great deal without affecting the data being sent.
Those are just some thoughts I had.
An easy "cheat", is to just increase the baud rate until it starts working, then keep increasing it until it stops working again. Then use the average of those two values.
For instance if it starts working at T2800 then stop working again at T3200, just use T3000 for the baud rate.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
Don't mistake experience for intelligence. And vis-vera.
·
One thing I can't do is find what Baud I need to send to the SX28, I tried 7200 but It does not work... this trial and Error is not going well.
Let's say I am sending from the SX28 N9600... Under normal conditions how do I calculate the Pulse width of each bit in microsecs. I figure once I know that·I can measure and compare it on my USB Scope.
I need to figure out a fool proof method of being able to send a serial command to the SX28 and it respond correctly every time. I'm going to use one for My Encoders and a couple of other Tasks.
·
Since the interrupt is making the SX send bits SLOWER, you need specify a higher baud rate.
To send on the SX try using 12800 baud (or there-abouts) that should send at about 9600 baud.
The pulse width is simple 1/baud seconds. So 9600 baud would be 1/9600 = 104.16uSec per bit.
At 50MHz your interrupt is occuring every 5.12uSec, so there will be about 20 interrupts per bit (that is a GOOD thing). The more interrupts per bit, the more consistance they will be with the "fudge-factor".
What is going to hurt your timing is that your interrupt does NOT take the same·number of cycles each time.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
Don't mistake experience for intelligence. And vis-vera.
Post Edited (Bean (Hitt Consulting)) : 10/9/2006 12:57:21 PM GMT
If you were to write this encoder and UART code in assembler, then it is relatively easy to have multiple timed tasks not interfering with each other. Using a simple task scheduler, the encoder and communication routines can be written to be totally indendent of each other.
The downside is that it is quite a bit more work as compared to using SX/B, but the upside is that it works without fail, and is easier to debug with the SX-Key.
Eventhough it is more work, I don't want to suggest that it is a daunting task.... just more work than SX/B.
If you think this might be an eventual approach for you, I'd be happy to give you some pointers and help you through it.
Cheers,
Peter (pjv)
It's funny... I can write programs to make a 3D Lunar Lander (Remake) but I can't make a microcontroller to a simple serial transfer.
I guess I should have learned ASM!!!
Anyhow... Bean... If I put delays in my code above for instance...
Will this help even out the timing issues??
Peter (pjv)
I would appreciate any help you can offer.· (THANKS!!! )
Best Regards,
Eric
I found working with interrupts within SX/B to be a major headache. You may want to goto the help file and re-read all the commands that will be affected by using·an interrupt. I believe that serin/out is one that gets affected by·using an interrupt. Now, somewhere in my reading it states that you can overcome this by turning the interrupt on and off, boy doesn't that sound like easy coding.
If you really are serious with your project, I would take up the offer that Peter (pjv) just made you. But keep in mind that his tutaledge will be in asm, and not in SX/B.
Ray
SX/B compiles to assembler (this is very useful for understanding and debugging), so I took your code and compiled and analyzed it.
The following numbers have some approximations due to rounding.
The encoder code in the interrupt routine consumes 72, 76 or 80 clock cycles, depending on what branches it follows.
At 2400 baud, the serial routine should output a bit every 416.6 uSec. Considering the interrupt is triggered every 256 clocks, which is 5.12 uSec, therefore the interrupt routine is executed 416.6 / 5.12 = 81.4 (use 81) times per transmitted bit. This means the interrupt activity eats up 81 times 72, 76 or 80 clocks, and that is works out to 5832, 6156 or 6480 clocks, which translates to 117, 123 or 130 uSec.
That implies the effective time for serial comms bits must be adjusted by those amounts to become 417 minus (117, 123 or 130) resulting in 300, 294 or 287 uSec. And these times would translate to (baud=1/time) 3333 baud, 3401 baud or 3484 baud, again depending on the path taken through the interrupt routine.
The extremes represent a variance of about 2 percent from the middle, and that should be well within the acceptance band of the serial receiver. So I suggest you try perhaps the middle one of those numbers and tell us what happens.
Cheers,
Peter (pjv)
Would adding NOP statements like I listed above help even out the Interupt time?
Now if I am Recieving a serial Stream from my propeller that is 2400 Baud would I still used the same Baud rate of (3401) on the SX28?
Can I use the same logic on 9600 Baud? I came up with an effective rate of 13557.
Thanks for staying with me. [noparse]:)[/noparse]
You have several questions here, so let me try:
1. Simply draw a little flow chart of the assembly equivalent of the SX/B ISR code, and count the respective number of machine cycles for each native (NOT compound) instructions. Also allow 3 each for getting into and out of the interrupt. There are actually 6 possible paths through your ISR routine, but several of them happen to have the same count.
2. I did not analyze your no-op approach, so I can't really comment. It would depend what paths they ended up in. It might be that it's not (easily) possible.
3. I have not analyzed the assembler equivalent of the SX/B serial receive code, so again it's hard for me to say for sure, but I have a suspicion that it may be so.
4. I believe so. You might be better to use the average of the two extremes which I calculated to be 13,333 and 13889, so I would use 13,611. Try it and see if it works.
Glad to be able to help.
You know, it would be great if SX/B could run in a non-blocking mode and let more than one thread run at a time; I wonder.......
Cheers,
Peter (pjv)
OK next question.
Are there any problems with the Serin Command?
I·added some code..
The above is just a snipet...
What I do is send a Character from my "Propeller"
If the SX recieves that character it outputs the Encoder count.
What is happening is the SERin is Timing out and the SX outputs the Command variable which happens to be what I am sending to it. My question is ... how can Serin time out and the Command Variable contain serial data from the host??
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com
Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
Don't mistake experience for intelligence. And vis-vera.
·