PDA

View Full Version : serial communication time



Mugelpower
- 29th January 2008, 15:36
Hi Guys & Girls!

my serial data transfer between two pics 16F628A works for starters. BUT: in my program theres at high engine speeds only 0.4 ms or less to send the data from one pic to another.
The action my receiving PIC makes is triggered by an external interrupt that means after that theres hardly time to get the data. On the other hand it doesn´t matter if it misses the data for a few cycles because at high engine speeds the data update could wait . I think it is sufficient to transmit that data every 0.1 sec.

Yes: baud rate 9600, 4 Mhz crystal, data: one word. Input Frequency 3 Hz - 600 Hz

Does this work?

on Interrupt goto ISR

main:
serin2 blah blah

isr:
pulsout 7, 50, 1

something like that




I will show the program when i´m back home

AH: one BIG Problem too:
when using a 2-channel oscilloscope it shows a Delay between input signal and output signal
of about 0.5 ms more than expected. this makes the whole action too slow!!!
Maximum accepted delay between input trigger and output pulseout could be 0.1 ms.

is the only way to handle those timecritical events by assembler? please say no....

Mugel

skimask
- 29th January 2008, 18:17
only 0.4 ms or less to send the data from one pic

I think it is sufficient to transmit that data every 0.1 sec.

9600 baud = 9600 bits per second
1 second / 9600 = .1046 ms per bit
1 byte = 8 bits + start bit + stop bit = 10.5 bits
10.5 x .1046 = 1.0983ms per single data byte = 910.498 bytes per second MAX

The math doesn't work...

paul borgmeier
- 30th January 2008, 04:43
Mugel,

It is not clear to me what you are trying to do. If you use the Hardware USART, you can send and receive in the "background" and keep your programs doing what they need to do.

Further, are you using RS232? Why Pulsout shown in the ISR?

More details = more help

Mugelpower
- 30th January 2008, 20:43
oha,
1 ms for Data transfer is way too much. And recieving data (no sending!) in the background seems the only thing to do
'************************************************* *******************************************
' 16F628A 10 Mhz crystal 15pf capacitors
' damn program should blink an LED every time a pulse goes into RB.0
' later a value should be serial loaded and set a delay before the blink pulse
'************************************************* *******************************************

'
' DEFINITIONS


DEFINE OSC 10
CMCON=%00000111
inputData var word ' variable to receive data into
pulseWidthVar var word



' START OF MAIN PROGRAM
'
CMCON = 7 ' RA0-RA3 are digital I/O
TRISA = 0 ' PORT A is output
TRISB = 1 ' RB0 is Input others output


on interrupt goto ISr

INTCON.1 = 0 ; Clear External Interrupt Flag
INTCON.4 = 1 ; Enable External Interrupt



main:
Portb.7 = 0

serin2 portB.0,16468, [inputData] 'for the future to load a value
pulseWidthVar = inputData

goto main

disable

ISR:

portb.7 = 1 'blink LED 0.02 sec one time when RB.0 goes high
pauseus 500
portb.7 = 0
INTCON.1 = 0 ; Clear External Interrupt Flag
RESUME 'resume main program
Enable 'Enable interrupts

END ' End of program

In my picbasic pro book from Dogan Ibrahim it says " USART is very complicated"
and that did not encourage me.
Because I use only 16F628A , maybe with 10Mhz that should do.

How could I use the Usart . I think those 16F628A have one....

mister_e
- 30th January 2008, 21:15
Then throw that book away ;)

HSERIN is one, method. Reading the USART register is another one, using it's interrupt is a third one.

Now you have to determine which process is much important. If you really have a need for speed for your interrupt, you may need to switch to Darrel's Instant-Interrupt. Not enough? ... use ASM interrupts.

@10MHz, you could use a 57600 baud communication without too much problem.

Not sure of your whole requirement... but i would use USART interrupt for that... i'll read it again.. just to make sure i didn't miss the main idea.

Mugelpower
- 31st January 2008, 08:21
Hi Mister_E,

you helped me a lot last time I remember. OK. Principle is an Ignition that gets an input signal (raising edge on Portb.7) , starts an interrupt and after a "Delay" it sends a 0.5 ms High to an Output. After that it recieves serial the actual variable "Delay" which is a byte and is ready for the next interrupt.
This all in about 1.5 ms at maximum speed.
I have a second PIC that measures pulse width and calulates "Delay" so I save Time and code for the time critical Interrupt.

But the Delay caused by the PBP program including the serial communication is about 1ms thats way too much.

Mugelpower
- 31st January 2008, 08:55
I meant Portb.0 as input of course...

paul borgmeier
- 1st February 2008, 11:26
Mugel,

How is it coming?

I am still not clear what you are trying to do.

I also am not clear on what is causing your 1mS latency ... is it the actual send time of the serial data?

To me, it looks like you could use the USART on both the send program and the receive program and never really have to wait.

Here is MELABS example program on USARTS

http://www.melabs.com/resources/samples/pbp/usart.bas

Once the USART is configured then sending data is as easy as

TXREG = DATA1 ; where DATA1 is your Byte variable to send, your program continues on and the data is sent in the background

And receiving DATA is as easy as

DATA2 = RCREG ; where DATA2 is your Byte variable, your program can be doing other things while the data is coming in. Once the byte has been received in the background, your program can grab the data like this.

It looks like to me you could do what I think you want to do with the USART and without Interrupts.

Again, more details = more help

Mugelpower
- 1st February 2008, 20:26
Ok. To make it clear I want This:

http://www.sportdevices.com/ignition/ignition.htm

but want to do that myself AND by using Picbasic Pro (Full version 2.5). I don´t want to write Asm because I´m unable to do so.
Although I know this could be done with 1 simple PIC I´m willing to take 2 of them or 3 if necessary for Picbasic Pros sake.

Those smart Guys that programmed ignitions don´t even give you the ASM code, only Hex.

Further I need this circuit and software etc. modified for different engines . For that I bought the PBP software.

I know You Guys could programm something like I need in 5 minutes or less but I need something in simple structure so I can handle the software and necessary changes.

My actual problem is the fact that my serial pic to pic communication is far to slow AND the com routine seems to delay the interrupt action by about 1ms which is inacceptable.

Hope this made everything clear.

thanks for your interest.

skimask
- 1st February 2008, 21:59
In my mind...short and simple answers...

High speed PIC's could handle the work...it's all about the guy behind the keyboard
High speed anything don't work too well in the automotive environment...it's all about the guy designing the filters.
9600 baud...not so much...as stated before. You want data transmitted every .4ms . Not going to happen at 9600 baud, I don't care how you program it, unless you want to start dropping bits and sending 3 bits instead of 8. Must go with much higher speed as stated earlier.
You don't want to learn or write in assembly? Well, that's probably not going to happen either. PBP's built-in 'ON INTERRUPT' is designed in such a way that latency is practically unavoidable in a lot of situations. Using DT's Fast Interrupts isn't that hard, and yes, it does require you to learn a little bit about ASM, not much though.

In my mind, any serious ignition work is best suited for a different processor, maybe a dsPIC...not that a PIC couldn't handle it...with the right programmer behind the keyboard. Personally, I think you're playing with matches in a gas fume filled room. One ignition event just a bit early, there goes the intake manifold, a whole load of events a bit early, now you've got 8 pistons that could double as doughnuts and con-rods that could do double duty as horseshoes.

Mugelpower
- 4th February 2008, 17:47
Hi .
Ok maybe I´m not software-smart enough to get my data sending/recieving problem as fast as needed.
So I try to switch to parallel communication.
I like the instruction:

PortB = VAR (byte)

the only problem is the fact that I need Portb.0 for the external interrupt so I will take the PIC16F873 which has more pins. Still need the ZIF socket for my programming adapter.

I will tell how that works.

To Skimask:
yes you are right about your detonation assumptions.
Know a bit about engines myself : http://www.davidpower.de/fotos_mot.htm

skimask
- 4th February 2008, 18:03
So I try to switch to parallel communication.
I don't think it's so much serial vs. parallel as it is the fact that you've got to SPEED up the serial quite a bit, which is entirely doable, or switch over to a CAN based type network, which again, with the newer PICs, entirely doable.


yes you are right about your detonation assumptions.
Know a bit about engines myself : http://www.davidpower.de/fotos_mot.htm
Point taken. Looks like a bit of a fun place to work there! :D Wish I could read German(?)

Mugelpower
- 4th February 2008, 18:51
in a post i read something like this:

Define Debugin_Reg portc
Define Debugin_Bit7
Define Debugin_Mode 0
Define Debugin_Baud 115200

The baud rate seems to good to be true. is that possible with a 4 Mhz crystal , or maybe a 10 Mhz ? By the way I don´t get my Pic 16F628A-20 to work with max Speed regardless of capacitors. Tried several 20 Mhz crystals: No Go! tried several 10 Mhz crystals with different capacitors (27 pF-yes ,22pF-yes, 15pF-yes , 12 pF-no) and they worked.
What could be wrong?

Mugelpower
- 4th February 2008, 18:52
oh yes what does Portc mean in the upper post,
why not Portc.0 or something?

Archangel
- 4th February 2008, 20:17
in a post i read something like this:


By the way I don´t get my Pic 16F628A-20 to work with max Speed regardless of capacitors. Tried several 20 Mhz crystals: No Go! tried several 10 Mhz crystals with different capacitors (27 pF-yes ,22pF-yes, 15pF-yes , 12 pF-no) and they worked.
What could be wrong?
Remember every piece of wire at radio frequencies exhibits the properties of inductance and capacitence, and the reactance of both. Which means the wire acts as both a coil and a capacitor.

Might be you have too much wire attached to the Xtal lines, too many sharp bends in those wires, too low impeadance due to resistance path between pins somehow, If you forget to change the config fuse from XT to HS then insufficient power to OSC. Try using a resonator without additional caps and keep those wires as short and straight as possible.
JS

Mugelpower
- 8th February 2008, 09:00
Thanks for your Help so long Guys.

As you know I will do as You tell and try. So I bought everything I need to try parallel com between pics but at first I will give "Debug" a try because its so fast (I read about that)

Sending (with all the Defines at Baud rate 9600)

CNT Var Byte
....
....
Debug [cnt]


Recieving (same Definitions)

Debugin ; cnt

.....
LCDOUT $FE02 `something like that, worked before
LCDOUT $FE80 "CNT=" , CNT
...

I´m not absolute shure about the code BUT

The LCD Display recieves something but only one Element which changes when changing the Input frequency
It shows CNT=§ (its the german symbol for "Divide" I dont have it on my keyboard)
or CNT=A (but only half symbol height and square)

This shows the transmission works, its just like different languages.
When I use Serout/Serin everything works fine
then it shows "CNT=146" for example whith input freq 146Hz .

There must be more about Debug/Debugin
I tried changing the Var defines from byte to dec which changed the display from rubbish to rubbish .

I thought if i´m sending a Var frompic to pic then it doesn´t change. Obvious it does.
What I´mmissing?
I´m showing the precise program code today in the evenig when I´m back home.
I need just a simple example for sending a byte by debug from pic to pic.
Oh yes I dream of baud rate 120000 or something....

Mugelpower
- 8th February 2008, 17:25
This is for sending the variable "CNT"
' DEFINITIONS
Include "modedefs.bas"
CMCON=%00000111
DEFINE OSC 4
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 2
DEFINE DEBUG_MODE 0 '1 = Inverted, 0 = true
DEFINE DEBUG_BAUD 9600

Cnt VAR Word ' Cnt is a word variable
CMCON = 7 ' RA0-RA3 are digital I/O
TRISA = 0 ' PORT A is output
TRISB = %01111111 ' RB7 is Input others output
cnt = 0
main:

COUNT PORTA.2,100,cnt ' Count for 1 second
DEBUG cnt

goto main


END ' End of program

And this is for recieving

'
' DEFINITIONS
Include "modedefs.bas"
CMCON=%00000111
DEFINE OSC 4
DEFINE DEBUGIN_REG PORTB
DEFINE DEBUGIN_BIT 1
DEFINE DEBUGIN_MODE 0 '1 = Inverted, 0 = true
DEFINE DEBUGIN_BAUD 9600

Cnt VAR Word ' Cnt is a word variable
CMCON = 7 ' RA0-RA3 are digital I/O
TRISA = 0 ' PORT A is output
TRISB = %11111101 ' RB1 is Input others output
cnt = 0

main:


debugin [cnt]


LCDOUT $FE,2
LCDOUT "cnt=", cnt
goto main



goto main


END ' End of program
and it shows just rubbish as told in the post above.
Any Hint?`

skimask
- 8th February 2008, 19:14
LCDOUT $FE , 2 , "cnt=" , DEC cnt

Just like the good book says...
That rubbish you say was the ASCII representation of the value in cnt.

Mugelpower
- 10th February 2008, 10:03
Hi Skimask,

I did as You told but now my LCD shows

cnt=252 or cnt=253

thats the only change

Any hint?

Greetings from a desperate mechanical engineer

Mugelpower
- 10th February 2008, 10:16
Hi Skimask,

I changed my program into this:

'
' DEFINITIONS
Include "modedefs.bas"
CMCON=%00000111
DEFINE OSC 4
DEFINE DEBUGIN_REG PORTB
DEFINE DEBUGIN_BIT 1
DEFINE DEBUGIN_MODE 0 '1 = Inverted, 0 = true
DEFINE DEBUGIN_BAUD 2400

Cnt VAR Word ' Cnt is a word variable
CMCON = 7 ' RA0-RA3 are digital I/O
TRISA = 0 ' PORT A is output
TRISB = %11111101 ' RB1 is Input others output
cnt = 0

main:


debugin [cnt]


LCDOUT $FE,2 ' Home cursor
LCDOUT "CNT=", DEC3 Cnt

goto main



goto main


END ' End of program

Now it works but only with this Baud rate of 2400.

BUT I WANT a Baud rate of ONE ZILLION or so.

seems I´m still at the beginning.

Or is it possible to run the data transfer in the background using some asm code ?

Greetings from Mugel

skimask
- 10th February 2008, 10:32
Now it works but only with this Baud rate of 2400.
BUT I WANT a Baud rate of ONE ZILLION or so.
seems I´m still at the beginning.
Or is it possible to run the data transfer in the background using some asm code ?
Greetings from Mugel

I guess I still don't get what you're trying to accomplish in the end.

It probably works at 2400 baud because there's enough time in between transmitted characters to send the data out to the LCD. At higher speed, when PBP returns from displaying to the LCD, the next transmission/reception is already halfway done and it gets missed. Either that or your oscillator is out of tolerance.

As far as using high baud rates, no you don't really need asm code...just a good understanding of the PIC, it's registers, the USART module, and some interrupts.

And it seems I'm right back to saying what I said back on 1Feb...

Mugelpower
- 10th February 2008, 14:46
Hello famous Skimask,

my LCD is only for controlling the principal of transmission.

I got 3 Pics together:

1. : getting Input, storing freq in VAR "CNT" and sending out with Debug
2. : taking the VAR "CNT" with Debugin, calculating a Delay and sending out a 1ms Pulse
after RB0 gets High + Delay time.
3. : taking the VAR "CNT" and showing on LCD just for control purposes

Showing my extremes:

a)cranking a 4-cyl. engine makes about 180/min. with a fixed 50° before OT input signal we need a delay of 37 ms until Ignition which makes 10° before OT which is great for starting an engine.

b) 4cyl 8000/min: we need only 0.2ms Delay after fixed 50° Input signal to get 40° before OT Ignition which may be great for a racing engine.

The delay has to include the PICs intern calculation delay.
The calculation could be done in the first PIC which measures only 10 times a second
BUT the "Execution PIC" has only about 1.5 ms for receiving the Var and being ready for the next action.
And an 8cyl at 6000/min leaves only 0.8 ms.
thats why I need transmission speed

Archangel
- 10th February 2008, 21:22
Hello famous Skimask,

my LCD is only for controlling the principal of transmission.

I got 3 Pics together:

1. : getting Input, storing freq in VAR "CNT" and sending out with Debug
2. : taking the VAR "CNT" with Debugin, calculating a Delay and sending out a 1ms Pulse
after RB0 gets High + Delay time.
3. : taking the VAR "CNT" and showing on LCD just for control purposes

Showing my extremes:

a)cranking a 4-cyl. engine makes about 180/min. with a fixed 50° before OT input signal we need a delay of 37 ms until Ignition which makes 10° before OT which is great for starting an engine.

b) 4cyl 8000/min: we need only 0.2ms Delay after fixed 50° Input signal to get 40° before OT Ignition which may be great for a racing engine.

The delay has to include the PICs intern calculation delay.
The calculation could be done in the first PIC which measures only 10 times a second
BUT the "Execution PIC" has only about 1.5 ms for receiving the Var and being ready for the next action.
And an 8cyl at 6000/min leaves only 0.8 ms.
thats why I need transmission speed

Hi Mugelpower,
.8ms, interesting number, how did you get that? 8cyl eng @ 6000 rpm fires 4 times per rev so 6000 * 4 = 24000 per minute 24000 % 60 seconds = 400 pulses per second so 1000 ms % 400 = 2.5 ms No?

skimask
- 11th February 2008, 03:20
my LCD is only for controlling the principal of transmission.
Loses something in the translation here :)


1. : getting Input, storing freq in VAR "CNT" and sending out with Debug
What INPUT?


2. : taking the VAR "CNT" with Debugin, calculating a Delay and sending out a 1ms Pulse after RB0 gets High + Delay time.
What does CNT represent? What is the delay for? Where does RB0 get a high pulse from?


The delay has to include the PICs intern calculation delay.
Which at times can be a variable delay due to the way math is done with PBP.


thats why I need transmission speed
Transmission speed? RPM of the input shaft? output shaft? MPH? KPH? GPM?

Mugelpower
- 11th February 2008, 08:55
Hi Skimask,

I try to answer with a minimum of translation losses....(Reminds me of principal Skinner, hehe)

1. Input is a 50% Duty cylce with 1/2 frequency of the magnetic/Hall pickup from the distributor because the Duty cycle varies sometimes with the frequency. So I took a 4027 to cut it in Half and got a nice constant 50/50 square signal. Makes 6Hz up to 300Hz. Thats my 1/2 frequency range. Threfore I have to multiply my VAR CNT by 2 to get the real freq, If I want to.Now I can handle this Input(my Variable CNT) mathematically like i want or need.
The easy thing is: we need this Input Variable only changed every 0.1 sec. thats fast enough.When the engine runs with constant speed for example for 1 minute we dont even need to change the Input variable because theres no difference.Thats the task of my first pic including sendig (by DEBUG)this Variable or the calculatet Delay (variable name and task is the same here) to PIC #2.

2. PIC #2 reacts when the RB0 pin shows a change fromlow to high. thats the same Input signal from our Distributor but the original frequency . The signal has to be changed into a square signal by a comparator or Schmitt-trigger.But here we need the precise starting point. After that a delay (Stored in the Var DELAY and calculated before depending on the input VAR CNT ) is startet ("ON Interrupt "or an asminterrupt handler needed here )
to get the right time for the Ignition action. This could be in the simplest way 10° befor OT at low speeds and 40° at high engine speeds (rotations per minute, Input signal fromthe distributor stored in VAR CNT). As you can see, even if you want a constant ignition action say 20° before OT the time of the delay after the delay starting signal (50° before OT = constant) the delay is reciprocal to the engine speed and reciprocal to VAR CNT.

3. Ignition action is a simple Output signal from the pin we choose (here PORTB.7) of 1ms high. This is send to the ignition coil driver wich switches 10Amps and 12Volts.The End of the 1ms is The Ignition timing point.

4.Due to PICs internal and software delays we need a correction factor for the VAR DELAY depending on Engine speed. Once we got this I´m happy. maybe in a list with just 10 points from low engine speeds to high speeds. Cranking is another thing because theres no constant cranking speed so the VAR DELAY has to be calculated for every cranking speed.
From 1000/min up we need only 10 different pre-ignition values, maybe 1000-1500,1500-2000 and so on. BUT: VAR DELAY would be different for a constant ignition timing for 1000/min or 1500/min.

If I can make anything more clear I will do so.

Transmission speed: The calculated VAR DELAY has to be sent from PIC1 to PIC2 (The ignition action PIC) .
BUT I put in a PIC#3 thats just for control purposes to check the VAR DELAY thats sent.
At the time theres no calculation OF The VAR DELAY and I´m sending just the "rough data VAR CNT". Calulation code is implemented after the transmission works.

Now: How will I send a WORD Variable fromPIC to PIC at Engine speeds of 8000/min? just 0.2 ms left. Or its done in the background with the famous USART registers which I try to use with DEBUG .......

skimask
- 12th February 2008, 05:26
Hi Skimask,
1. ..........Now I can handle this Input(my Variable CNT) mathematically like i want or need.
Multiplying by two is the same as a LEFT SHIFT, which only takes a single clock cycle on a byte, about 3-4 cycles on a word


4.Due to PICs internal and software delays we need a correction factor for the VAR DELAY depending on Engine speed. Once we got this I´m happy. maybe in a list with just 10 points from low engine speeds to high speeds. Cranking is another thing because theres no constant cranking speed so the VAR DELAY has to be calculated for every cranking speed.
From 1000/min up we need only 10 different pre-ignition values, maybe 1000-1500,1500-2000 and so on. BUT: VAR DELAY would be different for a constant ignition timing for 1000/min or 1500/min.
Learn how to use the hardware timers and you won't have a problem with the PICs internal software delays. Let the timers run on their own and interrupt the main program to trigger whatever you need triggered.


Now: How will I send a WORD Variable fromPIC to PIC at Engine speeds of 8000/min? just 0.2 ms left. Or its done in the background with the famous USART registers which I try to use with DEBUG .......
DEBUG doesn't use the internal USART, it too is a software bit-banged command.
8000 RPM = 133.3 RPS...
A word = 16 bits, 2 bytes = 8 bits x 2 + start/stop bits = 20 bits for each word.
134 (133.3 rounded up) x 20 bits = 2,680 baud, use 9600 baud so it's a standard baud rate.
Each word takes 2.083 ms, 134 times per second, 278ms used by the serial port per second at maximum RPM, leaves you with 722 ms to play with total in between words, 5.38ms on average between each word sent.
But, cut each of those numbers by 1/4 for an 8 cyl engine, still leaves you with 1.34ms between each ignition event.

Completely software driven is NOT the way to go with this. You NEED to learn how to use the hardware timers/interrupts, etc. to get this done with blowing holes in pistons.

Mugelpower
- 12th February 2008, 07:30
Thanks Skimask,

thats exactly what I was afraid of. OK it took one year to get me this far maybe I can make the whole thing go in another 6 months.....

I know Darrel Taylor got some interesting asm routines for interrupts. That may be a starting point.

AAAARRRGGGGHHH!

skimask
- 12th February 2008, 17:07
Thanks Skimask,
thats exactly what I was afraid of. OK it took one year to get me this far maybe I can make the whole thing go in another 6 months.....
I know Darrel Taylor got some interesting asm routines for interrupts. That may be a starting point.
AAAARRRGGGGHHH!

Afraid of!!!???!!!???
Don't be afraid... As long as you don't have whatever it is connected to a fuel burning 'thing' of some sort, what's the worst that could possibly happen?

The learning curve is steep, but once you're over the intial hump, everything else falls into place...for the most part :)