OpenXSensor SPORT Interface

Development & General Chat for the superb openxvario project.

Moderator: rainer

Post Reply
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

Thanks, I'll get the code committed.

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!

RightRudder
Posts: 241
Joined: Tue Jan 15, 2013 9:41 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by RightRudder »

Bruneaux wrote:Kilrah,

Yes, that is I am looking at:

http://store.atmel.com/PartDetail.aspx? ... escription

But I still worry why my boards failed. 4 of them. Bad batch?

Bruneaux
You can save a lot of money on that AVRISP and just get one of these.
http://www.ebay.com/itm/1PCS-USBasp-USB ... 1021924011
That is what I use for burning the bootloader.
Bruneaux
Posts: 119
Joined: Mon Oct 14, 2013 7:13 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by Bruneaux »

Mike,

Quick question. Can that buffer be enlarged without messing things up?

I have more data than will fit ( GPS coords and other values in one transmission ).

If so I'll just extend it.

Bruneuax
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

The SPort data packet is ALWAYS exactly 8 bytes long. First byte 0x10, next 2 bytes are application ID, next 4 bytes are data, last byte is checksum.

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
Bruneaux
Posts: 119
Joined: Mon Oct 14, 2013 7:13 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by Bruneaux »

Mike,

Ok, thanks. I guess I'll make a little state machine to manage the data.

Bruneaux

mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by mstrens »

Mike,
I said in a previous post that I noticed wrong values returned with the function micros() (from arduino library).
I made some additionnal test with my own version of openxsensor I am working on (in order to transmit voltage op top of altitude and climbrate using SPORT).

I can confirm that there is really an issue with micros() when you disable interrupts on timer0.
The reason is probably that if overflow of timer0 occurs when interrupt is disabled, the timer0 interrupt will not callled when you enable interrupt again. Therefore a arduino variable that contains the milliseconds is not incremented.

Here is an extract of the Arduino library I found in a file "arduino/hardware/arduino/cores/arduino/wiring.c
ISR(TIM0_OVF_vect)
#else
ISR(TIMER0_OVF_vect)
#endif
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = timer0_millis;
unsigned char f = timer0_fract;

m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}

timer0_fract = f;
timer0_millis = m;
timer0_overflow_count++;
}

The function micro() uses this code:
unsigned long micros() {
unsigned long m;
uint8_t oldSREG = SREG, t;

cli();
m = timer0_overflow_count;
#if defined(TCNT0)
t = TCNT0;
#elif defined(TCNT0L)
t = TCNT0L;
#else
#error TIMER 0 not defined
#endif


#ifdef TIFR0
if ((TIFR0 & _BV(TOV0)) && (t < 255))
m++;
#else
if ((TIFR & _BV(TOV0)) && (t < 255))
m++;
#endif

SREG = oldSREG;

return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}

void delay(unsigned long ms)
{
uint16_t start = (uint16_t)micros();

while (ms > 0) {
if (((uint16_t)micros() - start) >= 1000) {
ms--;
start += 1000;
}
}
}

The function micro() uses the milliseconds handled by the interrupt and take care of a pending overflow flag but after some delay does take care anymore of the fact an overflow interrupt has not been called.

Wrong values of micros() generates erratic handling in the program (e.g. when program wait for a A/D conversion.

Here some result I got in DEBUG when I put this code in OXS_MS5611.cpp - function readSensor()
static unsigned long micros0 = micros() ;
static unsigned long micros1 = micros() ;
static unsigned long micros2 = micros() ;
static unsigned long lastmicros2 = micros() ;

if (SensorState==0) {// ========================== Request Pressure
SendCommand(0x48);
//cli();
lastmicros=micros();
lastmicros2=micros() ;
//sei();
SensorState+=1;
}
else if (SensorState==1) { // ========================== get Pressure value
micros0 = micros() ;
if (micros()-lastmicros>=9000){

micros1 = micros() ;
printer->print("p= "); printer->print ( lastmicros );
printer->print(" ,p2= "); printer->print ( lastmicros2 );
printer->print(" ,m0= "); printer->print ( micros0 );
micros2 = micros() ;
printer->print(" ,m1= "); printer->print ( micros1 );
printer->print(" ,m2= "); printer->println ( micros2 );

Here one extract of the data on the PC terminal where m0 is smaller than p2 - but the milli are still the same (7683):
p= 7683600 ,p2= 7683604 ,m0= 7683372 ,m1= 7683380 ,m2= 7684064

or even here where the millisecond from m0 (13764) is smaller than those from p or p2 (13765)
p= 13765140 ,p2= 13765144 ,m0= 13764908 ,m1= 13764916 ,m2= 13765556

I suggest to find a solution for this.

NB : if I change the code in order to avoid disabling Timer0 then, I do not get this error anymore.
I think I read in one old post that you disabled the timer0 to avoid that the program block totally after 20 min.
I do not know why.

I hope this can help finding a solution.
Michel

PS : If you prefer that I send this kind of information by direct mail instead via this post, just say it.
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

I will look closer at this, when time allows.
What is most confusing is you have:

if (micros()-lastmicros>=9000){

but neither micros0 nor micros1, read either side of this, are 9000 more than lastmicros, yet the above statement appears true or you would not get the printout.

Are all the other printouts OK with m0 and m1 at least 9000 more than p?

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by mstrens »

Mike,
all other printouts are ok. I get about one wrong printout every 100 printout (but is not regular).

micro() and lastmicros are defined as UNSIGNED long.
I presume that (micros()-lastmicros>=9000) return true when micros() is smaller than lastmicros (because there are unsigned).
Then the program try to read the barometric sensor and get wrong results because the barometric sensor had no enough time to achieve the AD conversions.
This creates erratic altitude calculations. That the reason why I discover this issue.

One work around here could be to skip calculation of pressure when micros() is smaller than lastmicros but this would not be enough. It would be required to increase 9000 up to 10000 or 11000.
This would solve the issue for reading the pressure but micros() is also use on several other place (e.g for the temperature, the climrate calculation).
Currently this is what I have done in my version of the program.

Please note that this issue occurs perhaps more often in my program than in yours because I tried to read as fast as possible all sensor even if send to RX only values when polling occurs. It means that I do not send all sensor readings I have done but only the last one (of the type I want to send : altitude, climb rate, analog voltage, current, ...). I think that this principe is good because the more readings there are, the more accurate is the altitude (thanks the Kalman filter).

Up to know I did not understood why disabling the Timer0 interrupt is required. If possible avoiding the suspension of this interrupt would be the easiest solution.

I will try to run a test with my version of the program and avoiding the suspension of the Timer0 interrupt and removing the work around I had put in place.
I keep you inform if the program run more than 20 min.
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

According to my calculations, the timer 0 interrupt takes over 5.5uS to run. For the SPort output, we need to send bits every 17uS. Half a bit time (maximum allowed jitter) is only 8.5uS. The timer interrupt takes most of this. In addition other interrupts may occur and some code (e.g. micros()) disable interrupts for a significant time. Taken together, it is possible for the SPort bit time to be delayed long enough to cause the data to misread at the receive end.

I only disable the timer 0 interrupt for around 170uS, and as soon as I enable it it should occur immediately.

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

The TWI interrupt, used when accessing the altitude sensor, also takes some time to execute.
I've analysed the micros() values you posted. It might be interesting to see a couple more.

value O'flow TCNT
7683600 0x1D4F 0x84
7683604 0x1D4F 0x85
7683372 0x1D4F 0x4B
7683380 0x1D4F 0x4D
7684064 0x1D4F 0xF8

13765140 0x3482 0x85
13765144 0x3482 0x86
13764908 0x3482 0x4B
13764916 0x3482 0x4D
13765556 0x3482 0xED

Clearly, the TCNT value is VERY similar in both cases.

I can't (yet) see what is causing the problem.

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by mstrens »

Mike,

I run a test with my version of the program where I put the instructions DISABLE_TIMER0_INT() and ENABLE_TIMER0_INT() as comment.
The test run more than 2 hours and nor the openxsensor nor the taranis display blocked.
You are right that some data could be misread at the receive end. I could not check if it really occurs or not.

If the timer0 interrupt should occurs as soon as the timer1 interrupt is handled even if the Timer0 mask bit is set after that overflow of timer0 occurs, I do not understand why micros() return wrong value. The only one I see, would be that sometime timer1 interrupt would take more than 1024 usec but this is not the case with the code you had.
Sorry but I do not understand yet.

Here is a longer extract from the PC display.
You can see that in most case there is more than 9000usec between m0 and p (what ok is) but when m0 is lower than p then it gives wrong results when the pressure is read.
nb : you can discard the lines like "NA=1907 ,OA=1910 ,NMic=29185524 ,PMic=28983868NCB=-14 , oldCR= -25": it was added to test another of calculating the climb rate.


p= 28937372 ,p2= 28937376 ,m0= 28946644 ,m1= 28946652 ,m2= 28948200
p= 28953096 ,p2= 28953100 ,m0= 28952868 ,m1= 28952876 ,m2= 28954848
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 28967544 ,p2= 28967544 ,m0= 28976876 ,m1= 28976884 ,m2= 28978444
NA=1910 ,OA=1915 ,NMic=28983868 ,PMic=28789552NCB=-25 , oldCR= -15
p= 28987712 ,p2= 28987716 ,m0= 28997016 ,m1= 28997028 ,m2= 28999044
p= 29006004 ,p2= 29006008 ,m0= 29015300 ,m1= 29015308 ,m2= 29016856
p= 29024364 ,p2= 29024364 ,m0= 29033668 ,m1= 29033676 ,m2= 29035224
p= 29042204 ,p2= 29042208 ,m0= 29051660 ,m1= 29051668 ,m2= 29053220
p= 29060244 ,p2= 29060248 ,m0= 29069584 ,m1= 29069596 ,m2= 29071444
p= 29079444 ,p2= 29079448 ,m0= 29088732 ,m1= 29088740 ,m2= 29090296
p= 29097356 ,p2= 29097360 ,m0= 29106668 ,m1= 29106676 ,m2= 29108236
p= 29115236 ,p2= 29115236 ,m0= 29124684 ,m1= 29124692 ,m2= 29126240
p= 29133240 ,p2= 29133244 ,m0= 29142580 ,m1= 29142588 ,m2= 29144140
p= 29151156 ,p2= 29151160 ,m0= 29160444 ,m1= 29160460 ,m2= 29162008
p= 29169252 ,p2= 29169256 ,m0= 29178532 ,m1= 29178540 ,m2= 29180096
NA=1907 ,OA=1910 ,NMic=29185524 ,PMic=28983868NCB=-14 , oldCR= -25
p= 29189264 ,p2= 29189264 ,m0= 29198468 ,m1= 29198476 ,m2= 29200024
p= 29206996 ,p2= 29207000 ,m0= 29216396 ,m1= 29216404 ,m2= 29217956
p= 29224928 ,p2= 29224932 ,m0= 29234216 ,m1= 29234228 ,m2= 29236264
p= 29243260 ,p2= 29243264 ,m0= 29252548 ,m1= 29252556 ,m2= 29254112
p= 29261620 ,p2= 29261624 ,m0= 29270916 ,m1= 29270924 ,m2= 29272480
p= 29279464 ,p2= 29279468 ,m0= 29288836 ,m1= 29288844 ,m2= 29290396
p= 29297492 ,p2= 29297496 ,m0= 29306832 ,m1= 29306840 ,m2= 29308684
p= 29315692 ,p2= 29315696 ,m0= 29324964 ,m1= 29324972 ,m2= 29326528
p= 29331980 ,p2= 29331984 ,m0= 29331756 ,m1= 29331764 ,m2= 29332724
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 29345344 ,p2= 29345348 ,m0= 29354876 ,m1= 29354884 ,m2= 29356444
p= 29363436 ,p2= 29363440 ,m0= 29372708 ,m1= 29372716 ,m2= 29374264
NA=1904 ,OA=1907 ,NMic=29379964 ,PMic=29185524NCB=-15 , oldCR= -14
p= 29383708 ,p2= 29383712 ,m0= 29393004 ,m1= 29393012 ,m2= 29394564
p= 29402084 ,p2= 29402084 ,m0= 29411388 ,m1= 29411396 ,m2= 29412944
p= 29419932 ,p2= 29419932 ,m0= 29429292 ,m1= 29429300 ,m2= 29430860
p= 29437900 ,p2= 29437904 ,m0= 29447188 ,m1= 29447196 ,m2= 29449272
p= 29456272 ,p2= 29456276 ,m0= 29465580 ,m1= 29465588 ,m2= 29467144
p= 29474660 ,p2= 29474664 ,m0= 29483948 ,m1= 29483956 ,m2= 29485512
p= 29492508 ,p2= 29492512 ,m0= 29501892 ,m1= 29501900 ,m2= 29503444
p= 29510476 ,p2= 29510476 ,m0= 29519808 ,m1= 29519820 ,m2= 29521740
p= 29528740 ,p2= 29528744 ,m0= 29538020 ,m1= 29538028 ,m2= 29539580
p= 29547100 ,p2= 29547104 ,m0= 29556420 ,m1= 29556428 ,m2= 29557984
p= 29564980 ,p2= 29564984 ,m0= 29574372 ,m1= 29574380 ,m2= 29575928
NA=1901 ,OA=1904 ,NMic=29581388 ,PMic=29379964NCB=-14 , oldCR= -15
p= 29585128 ,p2= 29585132 ,m0= 29594500 ,m1= 29594508 ,m2= 29596064
p= 29603056 ,p2= 29603060 ,m0= 29612324 ,m1= 29612332 ,m2= 29613880
p= 29620988 ,p2= 29620992 ,m0= 29630260 ,m1= 29630268 ,m2= 29631828
p= 29638812 ,p2= 29638816 ,m0= 29648220 ,m1= 29648228 ,m2= 29649776
p= 29656800 ,p2= 29656800 ,m0= 29666228 ,m1= 29666236 ,m2= 29667788
p= 29674772 ,p2= 29674776 ,m0= 29684060 ,m1= 29684068 ,m2= 29685616
p= 29692676 ,p2= 29692680 ,m0= 29701956 ,m1= 29701964 ,m2= 29703524
p= 29710488 ,p2= 29710492 ,m0= 29719836 ,m1= 29719844 ,m2= 29721392
p= 29728412 ,p2= 29728416 ,m0= 29737772 ,m1= 29737780 ,m2= 29739332
p= 29746332 ,p2= 29746332 ,m0= 29755588 ,m1= 29755596 ,m2= 29757148
p= 29762068 ,p2= 29762072 ,m0= 29761860 ,m1= 29761872 ,m2= 29763540
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
NA=1895 ,OA=1901 ,NMic=29775040 ,PMic=29581388NCB=-30 , oldCR= -14
p= 29778752 ,p2= 29778756 ,m0= 29788188 ,m1= 29788196 ,m2= 29789740
p= 29796724 ,p2= 29796728 ,m0= 29806064 ,m1= 29806072 ,m2= 29807672
p= 29814684 ,p2= 29814684 ,m0= 29823956 ,m1= 29823964 ,m2= 29825520
p= 29832796 ,p2= 29832800 ,m0= 29842076 ,m1= 29842084 ,m2= 29843636
p= 29850612 ,p2= 29850616 ,m0= 29859996 ,m1= 29860004 ,m2= 29861552
p= 29868564 ,p2= 29868568 ,m0= 29877916 ,m1= 29877924 ,m2= 29879600
p= 29886604 ,p2= 29886604 ,m0= 29895876 ,m1= 29895884 ,m2= 29897436
p= 29904760 ,p2= 29904764 ,m0= 29914044 ,m1= 29914052 ,m2= 29915604
p= 29922596 ,p2= 29922600 ,m0= 29931988 ,m1= 29931996 ,m2= 29933544
p= 29940564 ,p2= 29940568 ,m0= 29949936 ,m1= 29949948 ,m2= 29951652
p= 29958660 ,p2= 29958664 ,m0= 29968020 ,m1= 29968028 ,m2= 29969580
NA=1888 ,OA=1895 ,NMic=29975328 ,PMic=29775040NCB=-34 , oldCR= -30
p= 29979068 ,p2= 29979072 ,m0= 29988404 ,m1= 29988412 ,m2= 29989968
p= 29996996 ,p2= 29997000 ,m0= 30006356 ,m1= 30006364 ,m2= 30007916
p= 30015004 ,p2= 30015008 ,m0= 30024436 ,m1= 30024444 ,m2= 30026004
p= 30032992 ,p2= 30032992 ,m0= 30042236 ,m1= 30042244 ,m2= 30043796
p= 30051480 ,p2= 30051484 ,m0= 30060748 ,m1= 30060756 ,m2= 30062308
p= 30067216 ,p2= 30067220 ,m0= 30066988 ,m1= 30066996 ,m2= 30068972
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 30081644 ,p2= 30081648 ,m0= 30090988 ,m1= 30090996 ,m2= 30092556
p= 30099560 ,p2= 30099564 ,m0= 30108836 ,m1= 30108844 ,m2= 30110448
p= 30117868 ,p2= 30117872 ,m0= 30127156 ,m1= 30127164 ,m2= 30128716
p= 30135756 ,p2= 30135764 ,m0= 30145108 ,m1= 30145116 ,m2= 30146784
p= 30153772 ,p2= 30153776 ,m0= 30163132 ,m1= 30163140 ,m2= 30164696
NA=1888 ,OA=1888 ,NMic=30170128 ,PMic=29975328NCB=0 , oldCR= -34
p= 30173880 ,p2= 30173884 ,m0= 30183204 ,m1= 30183212 ,m2= 30185240
p= 30192228 ,p2= 30192232 ,m0= 30201540 ,m1= 30201548 ,m2= 30203108
p= 30210620 ,p2= 30210624 ,m0= 30219940 ,m1= 30219948 ,m2= 30221504
p= 30228504 ,p2= 30228508 ,m0= 30237876 ,m1= 30237884 ,m2= 30239432
p= 30246476 ,p2= 30246480 ,m0= 30255792 ,m1= 30255800 ,m2= 30257644
p= 30264636 ,p2= 30264640 ,m0= 30274012 ,m1= 30274020 ,m2= 30275568
p= 30280208 ,p2= 30280212 ,m0= 30279980 ,m1= 30279988 ,m2= 30281956
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 30294584 ,p2= 30294588 ,m0= 30303980 ,m1= 30303988 ,m2= 30305552
p= 30312540 ,p2= 30312544 ,m0= 30321804 ,m1= 30321812 ,m2= 30323360
p= 30331024 ,p2= 30331028 ,m0= 30340300 ,m1= 30340308 ,m2= 30341860
p= 30349144 ,p2= 30349148 ,m0= 30358428 ,m1= 30358436 ,m2= 30359992
NA=1884 ,OA=1888 ,NMic=30365424 ,PMic=30170128NCB=-20 , oldCR= 0
p= 30369092 ,p2= 30369096 ,m0= 30378484 ,m1= 30378492 ,m2= 30380048
p= 30387140 ,p2= 30387144 ,m0= 30396500 ,m1= 30396508 ,m2= 30398064
p= 30405144 ,p2= 30405148 ,m0= 30414428 ,m1= 30414436 ,m2= 30415988
p= 30423268 ,p2= 30423268 ,m0= 30432572 ,m1= 30432580 ,m2= 30434128
p= 30441140 ,p2= 30441144 ,m0= 30450428 ,m1= 30450436 ,m2= 30451992
p= 30458964 ,p2= 30458968 ,m0= 30468380 ,m1= 30468388 ,m2= 30469940
p= 30476948 ,p2= 30476952 ,m0= 30486236 ,m1= 30486244 ,m2= 30488312
p= 30495308 ,p2= 30495312 ,m0= 30504612 ,m1= 30504620 ,m2= 30506176
p= 30513688 ,p2= 30513692 ,m0= 30522988 ,m1= 30522996 ,m2= 30524552
p= 30531552 ,p2= 30531556 ,m0= 30540916 ,m1= 30540924 ,m2= 30542476
p= 30549496 ,p2= 30549496 ,m0= 30558808 ,m1= 30558816 ,m2= 30560724
NA=1883 ,OA=1884 ,NMic=30566160 ,PMic=30365424NCB=-4 , oldCR= -20
Michel
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

In that list I can see 5 times when the problem occurs. The TCNT values are all very similar:
0x82 0x49
0x83 0x4B
0x85 0x51
0x84 0x4B
0x57 0x4B

At the moment, the only way I can see this happening is that TWO timer 0 interrupts occur while it is disabled.

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

What may be worth considering is to use a new method for the timing. Something like:

Code: Select all

uint16_t halfMicros()
{
	uint8_t oldSREG = SREG ;
	uint16_t value ;
	cli() ;
	value = TCNT1 ;
	SREG = oldSREG ;

	return value ;
}
IGNORE, TIMER IS AT WRONG SPEED FOR THIS.
This provides a 16 bit unsigned integer value counted up in hardware only at a 0.5 uS rate. As such, it may be used to time up to 32767 uS.
Use as:

Code: Select all

    lastmicros=halfMicros() ;

    if (halfMicros()-lastmicros>=18000){
It is much faster to execute and does not rely on interrupts to provide the timing. TIMER 1 is always set running at this rate in the serial code, whether SPort or Hub mode.

Mike.
Edit: Try these files:
Files removed as they didn't work.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by mstrens »

Mike,
it is for sure possible to replace the arduino micros() function by another one.

Still I think that using only a running 16 bits counter at 0.5usec will totally solve the issues because the timer will quite quickly fall back to 0 and so the next value returned by halfmicros() will be lower than the one previously returned.
This can be solved if each test time we calculate the difference between 2 reading of halfmicros we first recognise (and handle) the case where the new value is lower that the previous one (and if we do not use the logic for a too long delay).

On the other side, are you sure that the timer count each 0,5 usec. Is it not at the CPU clock (=1/16 usec) when the prescaler is set on 1 (TCCR1B = 0xC1) event if noise reduction is activitated. If so, then I don't how to avoid using interrupt.

NB : I tested your program (inserting you new codes inside my version) but it does not work.
I get much more errors on pressure mesurement.
Here a new extract from the PC; I added the previous and the new value of Timer1. It looks like the frequency of the counter would be 1/16 from a usec and not 0.5.

p= 1305818728 ,p2= 1305818736 ,m0= 1305820060 ,m1= 1305820068 ,m2= 1305822000 ,lastTmr= 58884 ,Tmr1= 14727
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 1305837740 ,p2= 1305837744 ,m0= 1305839068 ,m1= 1305839076 ,m2= 1305841012 ,lastTmr= 35343 ,Tmr1= 56707
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 1305856744 ,p2= 1305856752 ,m0= 1305858084 ,m1= 1305858088 ,m2= 1305859964 ,lastTmr= 11747 ,Tmr1= 33257
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 1305875848 ,p2= 1305875860 ,m0= 1305877180 ,m1= 1305877188 ,m2= 1305879072 ,lastTmr= 55360 ,Tmr1= 11143
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 1305894860 ,p2= 1305894864 ,m0= 1305896196 ,m1= 1305896204 ,m2= 1305898088 ,lastTmr= 31774 ,Tmr1= 53254
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 1305913876 ,p2= 1305913880 ,m0= 1305915212 ,m1= 1305915220 ,m2= 1305917104 ,lastTmr= 8348 ,Tmr1= 29830
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 1305932808 ,p2= 1305932812 ,m0= 1305934140 ,m1= 1305934148 ,m2= 1305936028 ,lastTmr= 49102 ,Tmr1= 4995
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 1305951720 ,p2= 1305951728 ,m0= 1305953052 ,m1= 1305953060 ,m2= 1305954948 ,lastTmr= 24047 ,Tmr1= 45446
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 1305970736 ,p2= 1305970744 ,m0= 1305972068 ,m1= 1305972076 ,m2= 1305973960 ,lastTmr= 640 ,Tmr1= 22019
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 1305989560 ,p2= 1305989568 ,m0= 1305990892 ,m1= 1305990900 ,m2= 1305992784 ,lastTmr= 39674 ,Tmr1= 61063
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0
p= 1306008584 ,p2= 1306008592 ,m0= 1306009916 ,m1= 1306009924 ,m2= 1306011808 ,lastTmr= 16417 ,Tmr1= 37766
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++Error: pressure not available, Wrire = 0

Michel
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by mstrens »

Mike,

wat do you think about following proposal ?

Interrupt should not be allowed when sending one byte on the Sport because this process is time critical (one bit every 17 usec).
This would be solved automatically if you do not exit at all from the interrupt while sending the 8 bits.
This requires "just" to have a 8 X loop inside the CASE when state = TRANSMIT.

Michel
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

Sorry, I'm not giving this my full attention. You are right timer 1 is clocked atr 16MHz so wraps round in 4.096 mS. Using unsigned subtractions is OK, even when a counter/timer wraps back to 0. In unsigned, fixed length arithmetic, 0x0000 - 0xFFFF = 0x001, which the correct difference so something like:
if (halfMicros()-lastmicros>=18000){
does actually work correctly.

We could disable all interrupts while sending a byte, I thought just stopping timer 0 would be sufficient.

I'll give this some more thought.

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

Let's take the simple solution!
It seems that occasionally timer 0 interrupt doesn't get to increment the counter, so causes the problem. For now, ignore that, and change the code to do:
if (micros()>lastmicros+9000){
( there's another similar line using 2000 in the same file)

This will catch the problem of micros() being less than lastmicros. If a timer 0 interrupt is missed, then we might wait 10mS instead of 9mS.

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by mstrens »

Mike,
I tested your proposal.
This fix the issue getting wrong pressure measurements.

I see still one less bigger issue when micros() miss some millisecond overflow.
The enlapsed time between 2 micros() is used too in order to calculate the climb rate (in cm/sec).
An under estimation of the enlapsed time results in a (small) over estimated climb rate.
I expect that the error should small because the climb rate is calculated only once every 500 msec and probably that there will not be many missed Timer 0 overflow.
I can try to check this by comparing a long enlapsed time calculated by the sensor with one provided by my own clock.

I will try to further understand why there would be missed overflow. Up to know I don't understand.

Thanks for the already provided solution.

Michel
RightRudder
Posts: 241
Joined: Tue Jan 15, 2013 9:41 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by RightRudder »

Guys I don't know if you saw my point in an earlier message. If the timer0 interrupt is delayed by a higher priority interrupt service, since the timer is still running during that time period, the timer registers contain the exact number of cycles by which the interrupt is delayed. The timer can be read on the fly and the value used to correct the time period value used in any calculation. Say the timer module is setup to cause an interrupt every 2msec but since a higher priority interrupt service routine is running at the time the timer rolls over say the interrupt is delayed by 512 clock cycles. The timer has now underflowed to 0xFE00 (assuming no prescaler). Read the timer take it's 2'c complement and add that amount of time to 2msec and you have the accurate time period for the measurement. You might have to take into account prescale bits to get the right number of miliseconds but you see the point, the timer is always running so use it. I have used this technique to monitor an engine crankshaft while doing a lot of other stuff in the background and had very accurate timing without jitter.

Joe
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

That is valid if only 1 interrupt is missed. I have concluded that, for whatever reason, 2 interrupts are missed, so the timer has wrapped round twice and this method no longer works.
What might be possible is to also monitor timer 1 count. This wraps round only every 4mS, instead of 1 mS for the 8-bit timer 0.
The other problem is the code that is really in trouble is the Arduino library code that is (always?) included. It is not so easy to change this for all users.

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
RightRudder
Posts: 241
Joined: Tue Jan 15, 2013 9:41 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by RightRudder »

oh now I see. I guess I'm a bit spoiled. Working always in assembler I tend to assume the programmer has complete control over the hardware. Is it essential to keep the arduino code?
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by mstrens »

FYI, I made 2 tests each of them running 600 sec:
- in the first one, the openxsensor is connected to the receiver X8R and send the data; so the timer0 is suspended during each byte transmission.
- in the second one, the openxsensor is not connected to the receiver and so, timer0 is never suspended due to a byte transmission

Comparing the values returned by micros() after 600 sec (enlapsed time at my clock), I see that:
- in the first test, micros() reported only 593 seconds
- in the second test, micros() reported exactly 600 second.
So there are about 1% error. This is an average because on a much smaller enlapsed time, 1 msec missing could lead to a much bigger % of error in the climb rate.

Michel
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by mstrens »

I tried to change the code of CASE (TRANSMIT) with the following in order to avoid an exit of the interrupt as long as the 8 bits are not yet transmitted.

while ( SwUartTXBitCount < 8) {
if( SwUartTXData & 0x01 )
{ // If the LSB of the TX buffer is 1:
CLEAR_TX_PIN() ; // Send a logic 1 on the TX_PIN.
}
else
{ // Otherwise:
SET_TX_PIN() ; // Send a logic 0 on the TX_PIN.
}
SwUartTXData = SwUartTXData >> 1 ; // Bitshift the TX buffer and
SwUartTXBitCount += 1 ; // increment TX bit counter.
OCR1A += TICKS2WAITONE ; // Count one period into the future.
//digitalWrite(PIN_LED, HIGH );
do { }
while ( !(TIFR1 & (1 << OCF1A) ) ) ;
CLEAR_TIMER_INTERRUPT( ) ;
//digitalWrite(PIN_LED, LOW );


} // end while 8 bits have been sent

CLEAR_TX_PIN(); // Output a logic 1.
state = TRANSMIT_STOP_BIT;
ENABLE_TIMER0_INT() ; // Allow this in now.
OCR1A += TICKS2WAITONE ; // Count one period into the future.
CLEAR_TIMER_INTERRUPT( ) ;

#if DEBUG
PORTC &= ~1 ;
#endif
break ;


It seems OK. I get the data on the display of the Taranis and if I run the test during 600 sec I get no difference anymore between between my clock and the value returned by micros().

I think this can be a good solution.

Michel
NeilRogers
Posts: 87
Joined: Sat Jun 22, 2013 2:12 pm
Country: United Kingdom
Location: Wiltshire

Re: OpenXSensor SPORT Interface

Post by NeilRogers »

hi guys,

I made MikeB suggested code change on the 9000 and 2000 (in my code 1000) lines, I thought you would be interested in some live data from a quick slope session this afternoon.

I changed the recording period to 200ms and added calculated VSpd into a spreadsheet I've smoothed out the high peaks in calc vspd.

You'll see the recorded value although a little low follows the actual vspd quite nicely especially as the recorded value is filtered and only updated every 500ms.

Happy new year
Attachments
PIKE-2013-12-31.xls
(309.5 KiB) Downloaded 129 times
User avatar
MikeB
9x Developer
Posts: 17990
Joined: Tue Dec 27, 2011 1:24 pm
Country: -
Location: Poole, Dorset, UK

Re: OpenXSensor SPORT Interface

Post by MikeB »

mstrens: I would guess that as this is also holding off the TWI interrupt, when you exit this interrupt, timer0 has a higher priority than the TWI so gets in first.
May well be the required solution, unless we block the TWI interrupt as well as timer 0.

Mike.
erskyTx/er9x developer
The difficult we do immediately,
The impossible takes a little longer!
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by mstrens »

NeilRogers,
I had a look at your recorded values from yesterday.
It is very strange :
If you analyse the values about the altitude, you can see that there are several enlapsed times where the altitude do not change and still during those enlapsed time the values for the vertical speed are changing.
The only explanation I have is that the altitude is not received by the Taranis while the vertical speed well.
Still if the vertical speed is received, it means that the transmission between Rx and Tx is working.
I do not understand.

NB : It is normal that the vertical speed do not change after each altitude because the vertical speed is recalculated only after 20 altitude calculations (and only a few from the 20 altitudes should be transmitted).

On the other side, I see that when altitude and vertical speed seems to be transmitted accordingly then the transmitted vertical speed seems lower that the calculated one.

NB : if you want I can provide you my version of the program to see if it provides better results.
I can't test it live myself for the time being.

Michel
NeilRogers
Posts: 87
Joined: Sat Jun 22, 2013 2:12 pm
Country: United Kingdom
Location: Wiltshire

Re: OpenXSensor SPORT Interface

Post by NeilRogers »

Hi Michel,

Weather permitting I should be out on the slope tomorrow.

No problem doing a live test with your software either post the mods or email to [email protected] and I'll run it live asap.

Cheers neil
mstrens
Posts: 1435
Joined: Fri Dec 27, 2013 7:49 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by mstrens »

Neil,

Here a zip file with all files for my version of the openxsensor.
I made several changes compared to the latest released version on the web site.
- this version works only using the SPORT (so with an X8R receiver).
- it transmits not only the altitude and the vertical speed. I added the voltage from the receiver (should be equal to A1 when set up calibration is done) in the parameter Vfas and also an external voltage in the parameter T1. I did not yet added other telemetry data but it should be quite easy in this version.
- I calculate the vertical speed in another way (see previous posts in the forum)
- I calculate the vertical speed based on 10 presure measurements (instead of 20); it should be updated more often.

Please note that the folder where you put the unzip files should have the same name as the file with the "ino" extension.

You can test this version if you find time (and get good weather).
Hope it works fine.

Michel
Attachments
openxsensor_Sport.zip
(30.21 KiB) Downloaded 171 times
NeilRogers
Posts: 87
Joined: Sat Jun 22, 2013 2:12 pm
Country: United Kingdom
Location: Wiltshire

Re: OpenXSensor SPORT Interface

Post by NeilRogers »

Hi Michel

Downloaded your version all looks ok running on the sensor.


I'll you know how it goes and post live data tomorrow evening hopefully

Neil
Bruneaux
Posts: 119
Joined: Mon Oct 14, 2013 7:13 pm
Country: -

Re: OpenXSensor SPORT Interface

Post by Bruneaux »

Mike,

When you refering to 'TWI' interrupts, is that the 'wire.h' library (I2C)?

If so, I'd say just try turning it off while you have too and see if it has any bad side effects. In my mind the slight delay to read the sensor is fine.

Bruneaux

Post Reply

Return to “OpenXVario - an open source vario supported by the open source firmwares!!”