uNav INS

I haven't had time to start yet - if there is a version _V5 ready to minimize DIFFS I see first I'll use that - otherwise I'll take the P# 272 changes as my start. Need to get wood for the woodstove and see what else is on my plate for the day.

With the Master connected to USB for debug the Master can use Serial for input and output at any time. Just needs a parser set up for the commands. Another nice thing about SPI_MST!

Chris O posted the CPUspecs() I wrote during K66 - I found that in about 8 Beta sketches - I had that as a parsed command to spit it out so I could ask for it at any time. I never wrote a GOOD parser - just a bunch of case statements to handle what I was doing at the time with single char commands.

This and other could be put into D_Debug.ino to keep clutter out of the core code? I'll start the Timing in T_Timing.ino perhaps?

Here is one example - when I was hitting the Serial# ports - in case it inspires a way to use it cleanly - even has help/'?' for the commands. It can call any function or change or show any Global variable? This was written when I thought serialEvent() was cool - but "void yield()" bypasses this - so explicit call to serialEvent() would need to be added to loop().

This one doesn't use '+' and '-' which could be used to adjust a variable - and what variable is adjusted could be changed with a command.

Code:
void serialEvent() {
  while (Serial.available() ) {
    char inChar = (char)Serial.read();
    switch ( inChar ) {
      case 't':
        if ( doDelay > 50 )
          doDelay = 50;
        else
          doDelay = 2 + doDelay / 2;
        Serial.print("\nTURBO ms==");
        Serial.println(doDelay);
        break;
      case 'f':
        doDelay = 700;
        Serial.println("\nfast 700ms");
        break;
      case 's':
        doDelay = 2000;
        Serial.println("\nslow 2000ms");
        break;
      case 'o':
        pinMode(5, OUTPUT);
        digitalWrite(5, 0);//Disable Amplified.
        Serial.println("\nAMP OFF");
        break;
      case 'O':
        pinMode(5, OUTPUT);
        digitalWrite(5, 1);//Enable Amplified.
        Serial.println("\nAMP ON");
        break;
      case 'c':
        CPUspecs(0);
        break;
      case 'w':
        widepad += 10;
        if (widepad > 240) widepad = 0;
        Serial.print("\nWidePrint==");
        Serial.println(widepad);
        break;
      case '?':
        Serial.println("ENTER:: 's' slow blink, 'f' fast blink, 't' TURBO blink, 'c' CPU Specs, 'w' pad '~'");
        break;
      case '\n':
      case '\r':
        Serial.println("_");
        break;
      default:
        Serial.print(inChar);
        break;
    }
  }
}
 
I'm inserting the hooks to the other 8 residuals now, will do a uNavINS_CB_Ver3 soon...

Tim - Will take a look at your code in #276 after I post release. Looks like a great start! To adjust the Q matrix, looks like we'll need to modify the diagonals in the Rw matrix. So we could change the variables used to initialize the Rw matrix, or just change a particular diagonal of Rw directly. Then once we change the Rw element, Q would re-build itself in the Propagation stage.

Don
 
delay your loop a tiny bit for bigger packets, 5/10ms, well not the loop, but the transfer16’s themselves
 
tonton81,

Each loop right now is an even 200ms. I'm only sending the data for these plots at the 5Hz GPS update rate.

Don
 
the only limit on packet length is the buffer in the H file of MST, but thats set at 200, 44 should be okay
 
Mike,

Is there anything in the Slave file that might be capping the number of parms? I'm not seeing anything...
Don
 
double MST_PrintVals[packetLength]; //was36
int ii = 0;

i do believe doubles (since your declaring) on teensy 3.x series are 64bit, while floats are 32bit
try assigning the dataset to uint16_t and cast to double precision like the TVmaster/slave demo does
(correct me if im wrong)
you might be overflowing that 200 dword buffer OR worse, which is probably whats happening, the CRC is going bad because of the shaved buffer

keep in mind the buffer entries are 16bits, and declaring 32/64bits for the fields wont do any good
i mean, probably if i did add later on 32 and 64 bit transfers transfer32, transfer64, then possibly it may work :)
 
in Tim’s demo he does this:

Code:
    uint16_t *buf;
    double MST_PrintVals[12];
      teensy_gpio.transfer16((uint16_t *)MST_PrintVals, sizeof(MST_PrintVals) / 2, 55, 1);

he knows more about it than i do

btw Tim,

Code:
sizeof(MST_PrintVals) / 2

this isnt correct is it? your sizing the double while casting a uint16_t, shouldnt you /4 or /8?

Both values are expressed in the same units. You have a 32-bit system, so the size of an address is 32 bits, or 4 bytes. The size of double on your system is 8 bytes. The result of an integer division 4/8 is zero.

i would try changing that /2 to /8

OR, Don, since you know the packetLength, you can replace the sizeof check with just the variable (without the division as well)

could this have been the problem with MST crashes all along??? :)
 
Last edited:
Don, if my logic is correct:

( 44 data) * (8 byte double) / 2 == 176 data instead of 44 you want!
so why wont 50 work?...
50*8/2 == 200 DWORDS, guess what? buffer in library is set to 200 exactly, add the 4 byte overhead in transfer (204 total) and BOOM, overflow!

this also means we were all sending more than 4 times the data than was necessary since the very beginning of SPI_MST creation lol!!!!! :eek:

Sorry im ranting from an iphone, im almost at work :)
 
Original code was this : data[data_pos] = sizeof(data) / 2;

<edit> Opps - busy eating - TVmaster had :: sizeof(MST_PrintVals) / 2

sizeof(data) is # of bytes used by 'data' - cut down to # of 16 bit words.

Not sure what was done when the last revision was done - didn't look at that.

As long as the size is not too large for xfer buffers - values put in on Master side can be pulled out on Slave side.
 
Last edited:
Hi All,
Just got back on line for a little while. Yeah tonton81 is probably right as a guess. The max packetlength for the version I posted was 36, you are now just about doubling that. When Tim and I was discussing the size of the buffer it was figured based sending 36 doubles plus some headroom. If you want to send that much data across the line we are going to have to open up the buffer size in SPI_MSTransfer.

Haven't looked at the code yet - probably later today - but there may need to be some adjustments to both the Master and Slave packet sizes to make it work.

Are you really sure you need to send that much data to look at.
 
yes thats the internal buffer, its not the USER buffer, the internal creates a valid 16bit buffer which is smaller than what your feeding it , your asking for 176 sending, no problem, 180 is created and overflows internally

the internal buffer gets size of itself, not your size, so with the padding it overflows the 200, the issue is the SKETCH, a division of 8 would fix this and save 4x the traffic, go and put a static 50 instead of sizeof()/2 in the transfer16, find out :)

keeping sizeof()/2 in transfer16 user code you might as well put a static 200 and it will still bug out..., you need to divide doubles floats /4/8, never 2, or cast as uint16_t type sizeof
 
With :: double MST_PrintVals[12];

Taking :: sizeof(MST_PrintVals) / 2

where :: sizeof(MST_PrintVals) gives 12 * 8 bytes
 
im just saying, the internal buffer is a different buffer that appends your sletch buffer to it, so the internal sizeof is the correct method, and has no relation to the user buffer size
 
Don,
Back to your point of not seeing anything. I loaded up your sketches and am seeing data on my slave device. Although it was a little strange that the master kept running even though nothing was on the slave. Yes I didn't see anything at first. I had to unplug and replug the slave in to get it to work. You can give that a try.

Yes there is a cap. If you send too much it will overflow the circular buffer like tonton81 was mentioning. But 44 should not. I thought it was 64 at first .. not sure why.
 
Mike, its the transfer16 buffer MST (200)
ill verify it myself when i get home
and i will also work this week on a transfer 32 and transfer64 for you Tim/Don
 
oh and just fyi though, the 8 bit version doesnt divide by 2, because it expects 8 bits
ill try to test out doubles later
 
Mike,
44 parms worked fine. When I added the next group of 6, the data stopped appearing on my Slave. After reading tonton81's comments, maybe I can just switch the print data to float instead of double. So I won't mess with the EKF internal doubles, just the data being sent to serial. Does that make sense? I'll give it a try in the morning...
Don
 
Don:
If Float is good enough for TViewer display then that can be converted before transmission at half the transmit size - I think Mike pondered that when jumping up from the old [12] values.

That will reduce the display load on the Slave so it won't get behind.
 
OK guys, I hate to break it to you but it bothered me hearing that the problem is with the library and not the user code. I'm here to proove that this issue is most likely the original problem with SPI_MST, and it hasn't shown itself due to the excess bytes being calculated after everything

Code:
    Serial.println();
    double test1[44];
    float test2[44];

    Serial.print("MST_PrintVals: ");
    Serial.print(sizeof(MST_PrintVals) / 2);
    Serial.print(" --> ");
    Serial.println(sizeof(MST_PrintVals) / sizeof(MST_PrintVals[0]));

    Serial.print("double: ");
    Serial.print(sizeof(test1) / 2);
    Serial.print(" --> ");
    Serial.println(sizeof(test1) / sizeof(test1[0]));

    Serial.print("float: ");
    Serial.print(sizeof(test2) / 2);
    Serial.print(" --> ");
    Serial.println(sizeof(test2) / sizeof(test2[0]));
Code:
MST_PrintVals: [COLOR="#FF0000"]48[/COLOR] --> 12
double: 176 --> 44
float: 88 --> 44

All these demos, tests, everything, MST_printvals was set to 12 but using WRONG divisor, your casting the buffer but calculating a 64bit SIZE
SPI_MST only COPED with it BECAUSE the concatenated arrays for the transfer passed CRC on a 48 DWORD PAYLOAD.

The solution is this:
Code:
sizeof(ARRAY) / sizeof(ARRAY[0])

this calculates the array size BASED ON THE SIZE OF THE TYPE

so PLEASE dont blame MST, the 16bit transfer function does the PROPER calculation on what it was designed for, 16 BITS
 
Take these 2 for loops after the transfer16's

Code:
    Serial.println();
    for ( uint16_t i = 0; i < sizeof(MST_PrintVals) / 2; i++ ) {
      Serial.print(MST_PrintVals[i]); Serial.print(" ");
    } Serial.println();
    for ( uint16_t i = 0; i < sizeof(MST_PrintVals) / sizeof(MST_PrintVals[0]); i++ ) {
      Serial.print(MST_PrintVals[i]); Serial.print(" ");
    } Serial.println();

with both JUST PRINTING, result? LOCKUP!
Code:
F&F (OT=0)
0.00 1.00 2.00 3.00 4.00 5.00 6.00 7.00 8.00 9.00 10.00 11.00 2.48 0.00 0.00 0.00 0.00 nan

NO ACTIVITY

comment out the first for loop, and we get: NO LOCKUPS!
Code:
[COLOR="#FF0000"]12.00 13.00 14.00 15.00 16.00 17.00 18.00 19.00 20.00 21.00 22.00 23.00[/COLOR] 
MST_PrintVals: 48 --> 12
double: 176 --> 44
float: 88 --> 44
 OT_CALC==100  micros() _time==134
127:255
F&F (OT=2)
[COLOR="#FF0000"]24.00 25.00 26.00 27.00 28.00 29.00 30.00 31.00 32.00 33.00 34.00 35.00 [/COLOR]
MST_PrintVals: 48 --> 12
double: 176 --> 44
float: 88 --> 44
 OT_CALC==100  micros() _time==134
127:255
 
Back
Top