Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 3 1 2 3 LastLast
Results 1 to 25 of 67

Thread: Serial Problem

  1. #1
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23

    Serial Problem

    I am working on a GPS logger using Teensy 3.6, Adafruit GPS breakout (Serial1) an OLED display (SPI) and an MPU9255 accelerometer (SPI).

    The problem I am having is that sometimes when re-programming the board, the serial bus (Serial1) sees no GPS data (even though it is being provided by the GPS breakout board). I know that data is arriving at pin RX1 pin because when I connect this pin to RX2 and call Serial2.begin(9600), I see the data.

    When the problem occurs I want to recover from it in the fastest, least invasive manor. I have tried calling the following to reset communication, but this still does not enable the serial device to see the data.
    Serial1.clear();
    Serial1.end();
    Serial1.begin(9600);
    It seems to me that I cannot recover in code and a reboot is required.

    My thoughts to the cause of the problem are:
    When Teensy is booting, the GPS chip is streaming data to RX1, and this (sometimes) affects and corrupts the serial bus. If this is true, then there must be a better circuit design I could use to prevent the problem e.g. somehow only set the EN pin to the GPS board when I am ready for serial data?

    I tried a bare bones test with very little code, just listening to the serial ports, and I could not reproduce the problem. I haven't posted code here, as it's a big project, and feel that someone probably recognises the problem from the info given.

    Any thoughts as to what could cause this or how to avoid this would be great.

  2. #2
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    3,688
    First question is, are you sure it is not receiving data?

    That is, could it be seeing data, but it is not picking out valid packets from the stream?
    If you are actually receiving data. If you are actually seeing data. I believe that it can send between 1 and 10 updates per second. So I would try to make sure to throw away all data at the start of program and keep trying to read until you find a gap between bytes of something like 50ms or maybe longer depending on the rate of messages. That should hopefully get you synchronized to start reading at start of packets...

    That is sometimes people have had issues with programs that soft reboot as the device connected has had power though out the process and is still outputting data.
    And/Or the code tries to do some setup code that the device may not like if it had already been init or...

    Not knowing much about your tracker. not sure what else you have tried.
    Example looks like there is an enable pin, that you can pull low. Have you tried connecting this up to your teensy and have the Init code pull it low during setup and then go back high?

  3. #3
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23
    First question is, are you sure it is not receiving data?
    Yes. I'm using serialEvent to sniff for data. The counter serial_count records how much data received.

    Code:
    int serial_count = 0;
    
    void serialEvent1() {
      serial_count++; // serial_count > 0 indicates data received.
      processData();
    }
    I ensure that the system loops and provide delay() functions to evoke serialEvent usage (both yield() and delay() will do this).

    And/Or the code tries to do some setup code that the device may not like if it had already been init or...
    When the problem occurs (not very often), I can manually connect RX1 to RX2 and call Serial2.begin(9600). serialEvent2() will then print the characters sent, Serial1 will not and remains in the state (serial_count == 0 and Serial1.available() == 0).

    The fact that both serial_count == 0 and Serial1.available() == 0 persists even though I try to restart the serial connection, is puzzling.

    Example looks like there is an enable pin, that you can pull low. Have you tried connecting this up to your teensy and have the Init code pull it low during setup and then go back high?
    I have not tried using the enable pin yet. I didn't want to that until I knew what I was doing and why I was doing it. I can imagine restart problems (in the GPS breakout board) where current is cut then quickly restored sometimes leading to a corrupt state in that device.

    That is sometimes people have had issues with programs that soft reboot as the device connected has had power though out the process and is still outputting data.
    This seems to be relevant, but why? Indeed during reboot, the GPS board will continue to pump out data, but why might that be a problem? The experiment that challenges that notion is that in my bare-bones test (same board without the code to initialise all the fancy add-ons), I didn't manage to see the same problem yet.

  4. #4
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23
    Looking at the problem another way, what could you do in code or circuitry to render Serial1 corrupt (data-blind) and unable to recover simply without a reboot?

    By simply I mean, calling the usual Serial functions to reset the connection:

    Code:
    Serial1.end();
    Serial1.begin(9600);
    Is there some (more internal) code that I could call to reset / re-initialise Serial1 (the hardware / interrupts etc.)?

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,041
    It seems you have something else going on perhaps? If all else is well and right I can only guess pin/hardware fault - unless there is a device conflict changing the Mux on that pin? On T_3.6 you could move the Serial1 Rx from Pin 0 to either pin 21 or 27 with:
    Serial1.setRX(pin)
    Configure the serial port to use an alternate receive pin. Teensy LC and 3.x support only specific alternate pins. This function may be called before Serial1.begin(baud), to pre-configure the pin used. It may also be used while the serial port is active. Physical pullup resistors are recommended for applications which change pins while running.
    I've done a bit with Serial GPS and MPU that was i2c - didn't have a display but tied two Teensy SPI ports together for a few hundred+ messages per second after using second serial for a bit of debugging.

    Others have done that as well and 2 years of other stuff and nothing has dropped out Serial Rx pin as you describe that I've seen. Particularly KurtE above who adjusted the T_3.6 Serials #1-#6 to work on T_3.5 and T_3.6 from Beta onward.

    <edit>: A quick check might be to do setRX(0) - AFTER setRX() to 21 or 27 if either is free. That may restore the pin settings if something else wiped them out.
    Last edited by defragster; 10-04-2018 at 07:01 AM.

  6. #6
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,649
    Quote Originally Posted by microderm View Post
    Is there some (more internal) code that I could call to reset / re-initialise Serial1 (the hardware / interrupts etc.)?
    Using Serial1.begin(baud) does indeed fully initialize the hardware, including the interrupt.

    If you *really* want to dig into the code, you certainly can. In HardwareSerial.h on line 257, you can see Serial1.begin() simply calls serial_begin() with a pre-computed divisor based on the baud rate you used. The hardware init code is within serial1.c, in that serial_begin() function.


    I haven't posted code here, as it's a big project, and feel that someone probably recognises the problem from the info given.
    We do see this sort of problem here on this forum pretty regularly. It's almost always a buffer overflow or risky use of non-reentrant code/functions from interrupts. The buffer overflows are especially common, where you have a loop writing to an array and you make a common mistake like "for (i=0; i<=MAXSIZE; i++)" which should be less than, not less than or equal, because the "or equal" case causes your code to write something into whatever memory exists just beyond the array. When that something happens to be variables used by the serial1 code, or other pointers that later get used for storing stuff to memory, it's easy to mess up things up in ways that look like a hardware or driver-level problem.


    I tried a bare bones test with very little code, just listening to the serial ports, and I could not reproduce the problem.
    This very likely means something is wrong somewhere in your large problem.

    It's also possible, but unlikely, that you may have found a new previously-unknown bug. But I'm not going to investigate unless you can share a test program which reproduces it.


    Having said all that, and with some reluctance because this is likely to send you down a fruitless path, I will mention there currently is one known bug on my list to fix. First, I want to be absolutely clear: this bug causes Serial1 to be unresponsive to new data until the serial line has an idle time of approx 9 bits. So even if your GPS is outputting horribly wrong data with corrupted stop bits, if the data is NEMA or any other format where a burst of data is sent for each new update and then idle times occur between those updates, the serial port would certainly recover during those times. With that in mind, there is the only currently known bug:

    https://forum.pjrc.com/threads/53850...l=1#post188193

    If you really are sure there's something wrong in the code or hardware, maybe that test case code will give you something useful for testing. Again, I want to be clear that I do not investigate reports of problems unless a complete program is provided.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,649
    One unlikely situation might depend on whatever code you have in processData().

    Quote Originally Posted by microderm View Post
    Code:
    int serial_count = 0;
    
    void serialEvent1() {
      serial_count++; // serial_count > 0 indicates data received.
      processData();
    }
    If processData() is waiting for another serial event in some cases, it will never happen. The code in yield() which calls the serial event functions has a check to prevent recursively calling the serial event functions. It will not call any other serial events until you've returned.

    Of course this is just blind guessing, since we can't see what's in your processData() function.

  8. #8
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23
    Thanks for all the info and ideas.

    I have now managed to break Serial1 with my bare-bones test, using Teensy 3.6 with Adafruit Ultimate GPS, a board with 3 buttons (held HIGH with 10K resistors and 47nF capacitors) and an external LED.

    I'm using Mac 10.13.6 (High Sierra), Teensy Loader 1.41. The build uploads to an active board (obviously), so GPS data will be streaming in throughout (programming and reboot). The GPS board streams NMEA packet data until all packets are sent, then waits for the next cycle, so there will be communication pauses.

    The program itself tries to group all related NMEA packets together at the start of the loop cycle. The code requests the GPS board to run at a higher baud so shifts from 9600 (default) to 115200 (max). The three buttons enable me to probe the Serial status in different ways:
    1) Button 1 toggles raw data display (shows characters read).
    2) Button 2 restarts Serial1 toggling between 9600 and 115200 baud.
    3) Button 3 starts Serial3 toggling between 9600 and 115200 baud.

    I upload the build, check whether it's working then repeat until it breaks. On my system, it usually takes between 1 and 10 cycles to break. I've put an external LED on the board to indicate when broken. The LED will light during setup then switch off.

    A periodic health check runs every few seconds, where if Serial1 has received no data (since the last check) and has no data waiting, it lights the external LED again, indicating the broken status. I did this so that I could test whether it breaks when connected to external power in the field. Field tests have not yet shown a problem, but that might be dependent on how quickly I can turn power off and on again (currently not quick, as I have to unplug and replug a cable)?

    So far, tests have revealed two problem types:
    1) Serial1 breaks, and a calling Serial1.begin(9600) does not fix it.
    2) Serial1 claims to receive data. The data is all null, (not real).

    When (1) occurs, I can connect the free wire to RX3, press button 3 and see the data. I may need to toggle the baud to synch with the current GPS output baud.

    Problem (2) occurs less frequently and I haven't yet looked at this much. It doesn't illuminate the external LED. I will try to see what the numerical value of the data is...

    If problem (1) occurs while the free wire is connected to RX2 (RX1 connected to RX2) then both Serial1 and Serial2 break.

    I feel that the problems occur more readily on a more complex system, with extra hardware attached and more code running.

    I haven't yet had a chance to experiment with changing the pins on the fly using setRX(). Could be interesting!

    I'll post additional observations as I find them...
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	board-min.jpg 
Views:	17 
Size:	105.4 KB 
ID:	14899  
    Attached Files Attached Files

  9. #9
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,743
    I took a quick look at your ino file - It's not easy without having your hardware.
    One thing: Why all the delays? Better is to directly call yield() instead. Yield() calls the serial events, if data is available, without needless waiting.

    Code:
      while ((int)millis() < free_time) {
        interruptChecks();
         delay(1); //<-- remove, use yield() instead
      }
      // Should have received packets: wait remaining time //
      while ((int)millis() < (next_time - 2)) {
        interruptChecks();
        delay(1);//<-- remove, use yield() instead
      }
      serialCheck(); // Quick //
      blinker(); // Toggle LED //
      while ((int)millis() < next_time) {
        // busy waiting // <-- insert yield() here
      }

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,041
    How long are the GPS message strings? And what update rate? 1 Hz or more?

    In that simplified state it is similar and simpler to what I used for months with no issues. I started with that Adafruit and went to a NeoBlox unit as it supported the messages the other thread was using.

    I never used the serialEvent1() method - just monitored that all the strings came in and passed checksum - and ended up extending the internal buffer to hold a whole message of ~105 bytes when the system was busy as it was doing a ton of math on the GPS data and we had the serial data rates running from GPS at over 400KB with 10 Hz updates.

    The delay 1ms could cause lots of data buffering - not so much as slower baud rates - but not helpful. But that should just be lost data not stalled Serial1 hardware interface as I saw it.

    Moving the Rx pin might show a change in behavior if that pin isn't healthy. In the code I did above I wrote an interrupt to detect GPS start of message to make sure the long math work was delayed during incoming message. I could post that code and you could monitor for loss of the message starting - and then know when it is incoming.

  11. #11
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23
    Quote Originally Posted by Frank B View Post
    Why all the delays? Better is to directly call yield() instead.
    Yes, I'll adapt my code to do that.

    Quote Originally Posted by defragster View Post
    How long are the GPS message strings? And what update rate? 1 Hz or more?
    In the test, I'm getting updates at 10 Hz, with a range of packets (GPGGA,GPGSA,GPGSV,GPRMC) sized about 70 bytes long. If my calculations are correct, at 115200 baud that is 14400 bytes/sec. That is no more than 14 chars per millisecond.

    The buffer size is 63 bytes, so I should be fine with delays (or workload) of less than 4 ms. Calling delay() will poll the serial bus for me (I believe). Once the set of packets have all arrived, I can then do more intense work (more than 4 ms, e.g. drawing to graphics display or writing to SD), knowing that I won't receive any packets (hence the loop timing stuff).

    It'll probably be better (more elegant) long term to use interrupts or threading to handle larger processing workloads, but I'll need to experiment with those things a bit before I'm ready to do that.

  12. #12
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23
    I tried changing the assigned pins using setRX() and setTX():
    - This works beautifully when Serial is working normally (you can pin swap on-the-fly).
    - When broken, the newly assigned pins don't work and changing back to the original doesn't work either.

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,041
    Where the wires physically moved to one of the ALT Serial1 Rx pins? And did the problem repro in that setup?

  14. #14
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,649
    I ordered the GPS board from Adafruit.

  15. #15
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23
    Quote Originally Posted by defragster View Post
    Where the wires physically moved to one of the ALT Serial1 Rx pins? And did the problem repro in that setup?
    Yes, I unplugged the wires, pressed button 3 (now re-programmed to toggle the RX and TX pins) and plugged them into the alternative pins. Still no GPS data visible.

    It seems that when broken, it is Serial itself and not the pin assignment that it broken. By the way, I'm sure it is not a broken Teensy, as I did the bare-bones test on my second board. (Why have only one Teensy when you could have two? ;-))

  16. #16
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23
    Quote Originally Posted by PaulStoffregen View Post
    I ordered the GPS board from Adafruit.
    Wow, this is getting serious!

    I've found it to be a good GPS board especially when used with an external antenna. It has been giving me really good results. I bought a NeoBlox unit too, but haven't got round to testing yet, as the Adafruit unit is giving the data quality I want.

    I did a bit of work with iPhone GPS a while back and found that data to be unreliable, jumping around a lot. At 1 Hz top speed, it doesn't give a good track of motion at all.

    I recommend the external antenna (with the Adafruit GPS unit) as you can place it outside while testing indoors, and get a location fix quickly from startup.

  17. #17
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,649
    When it arrives, do I need to change any of its non-volatile settings?

  18. #18
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23
    Quote Originally Posted by PaulStoffregen View Post
    When it arrives, do I need to change any of its non-volatile settings?
    No, just plug in and play.

    Likewise, I should also test my NeoBlox GPS too, just to help confirm that the issue is general, rather than specific to a particular piece of external hardware. Should be able to do that sometime this weekend. For the moment I'm testing the effect of using the EN enable pin on the GPS unit.

  19. #19
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,041
    I dug under my desk pile and found the Adafruit ULT. GPS.

    I see three working buttons, but In Button.cpp :
    > Had to remove unknown :: //#include "Utilities.h"
    > made buttons INPUT_PULLUP because I wasn't adding resistors
    > Had to move that to libraries to compile

    Then I saw the failure mode GOTCHA >> Only because my GPS had no power - using a long breadboard and needed to jumper GND/Power rails. (wondered why LED wouldn't light)

    With setup as in photo all works well on this T_3.6. Only known diff other than INPUT_PULLUP is the DUAL run of GND and Power to feed the GPS across the breadboard.

    Click image for larger version. 

Name:	adaGPS.jpg 
Views:	14 
Size:	150.4 KB 
ID:	14905

    I can toggle all three buttons and stuff changes - but no PANIC LED and only see such as the following on multiple restarts::
    *** Loop [1282550] ***
    [0,0,0] serialCheck() = ok
    Pulled 2nd Power and GND lines and still running::
    [0,0,0] serialCheck() = ok
    *** Loop [1574720] ***

  20. #20
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,041
    Moved it over to the window and restarted - now I have a FIX. No Serial issues seen. LMP LED still off.

    *** Loop [5335330] ***
    [0,0,0] serialCheck() = ok
    <edit>
    left it running overnight - another 36+ Million Loop counts and going - No error LMP and still has the fix:
    *** Loop [41717240] ***
    [0,0,0] serialCheck() = ok
    This was just another T_3.6 I had on hand that had not been soldered to, I soldered on pins as shown.

    BTW: Windows 10 with IDE 1.87 and TD 1.44. Through I was using this about 10 months back with then current versions for some weeks before moving to the UBlox and saw no issues then.

    The GPS wire loops are minimally soldered - alternated top and bottom so I could remove them easily as I wasn't sure of what the final use case might be. I used PPS before, and I see I did not solder anything to the EN pin.
    Last edited by defragster; 10-07-2018 at 08:21 PM.

  21. #21
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23
    I think I'm narrowing in on what the problem is. It isn't something many folks have experienced. There are reasons for that...

    This weekend I started experimenting with the use of the EN (enable) pin on GPS device. I connected pin 24 to the GPS EN pin and held that LOW with a 4,7K resister. This would then disable the GPS unit until I call digitalWrite(24, HIGH). In setup I tried different length delays (before enabling) and found that 2000 ms was sufficient for the GPS device to forget its previous settings. The device would then always start with the same configuration and things worked well.

    I have been testing the GPS unit without the battery backup installed so as to get the full range of different start conditions. With the battery in, the unit will remember sat tables (get a fix quickly), sample rate and serial baud rate etc. But batteries can fail or be removed etc, so I code for all scenarios. That means I assume the initial baud rate is the default value of 6900 and send commands to change the baud rate to 115200, and the data and GPS sample rates to 10Hz.

    The problem there is changing the serial speed on the fly. Historically, I would just send the commands in sequence and they would usually work:

    Code:
    Serial1.println(PMTK_SET_BAUD_115200); // Set to 115200 baud.
    Serial1.begin(115200); // Start communication at new speed.
    Serial1.println(PMTK_SET_DATA_100MS); // Set output to 10Hz.
    Serial1.println(PMTK_SET_FIX_100MS); // Set GPS scanning to 10HZ.
    Programming the Teensy had a slight complication in that usually when I pressed the upload button in the IDE, Teensy was running and had sent the command to change to 115200 baud. Upon reboot, we have our Teensy listening to Serial1 at 9600 with the unit continuing to send data at 115200 baud.

    That shouldn't be a problem, since once the setup() runs it will request the speed change. The GPS unit won't understand the garbled message and will ignore it. We change Serial1 to 115200 baud and send a couple more messages. GPS understands and honours the request. Happy days.

    Switching to using the GPS EN pin seemed to make things more robust by not exposing Teensy to GPS data (possibly at the wrong speed) before being ready to use it. Experimenting further with GPS initialisation I find the problem to be two-fold:
    a) we don't know what baud setting the GPS unit is currently using. (holding EN low at start won't reset with battery backup installed)
    b) we don't know if the GPS unit has responded to the commands sent.

    I wrote some code to help solve these problems. It reads the GPS output using Serial1 at 9600 and Serial2 at 115200. Only one of these will succeed, so I solve problem (a) above:

    Code:
    /*
     * Initialise GPS.
     */
    void initGPS() {
      digitalWrite(GPS_EN, HIGH); // GPS on - prevents Teensy start up problems //
      Serial2.begin(115200);
      Serial1.begin(9600);
      // Poll for first character //
      int rate = checkBaud(false);
      delay(100); // Allow packets to be read GPS unit messages //
      Serial.println("*** Finished? ***");
      int count = 0;
      while (rate != 115200 && count <= 5) {
        Serial.println("[" + String(millis()) + "] *** PMTK_SET_BAUD_115200 ***");
        Serial1.println(PMTK_SET_BAUD_115200);
        Serial1.flush(); // Ensure sent //
        rate = checkBaud(true); // Read data to prevent buffer overflow //
        count++;
      }
      Serial2.end(); // No longer needed //
      Serial1.begin(115200);
      Serial1.clear();
      delay(1);
      Serial.println("[" + String(millis()) + "] *** PMTK_SET_DATA_100MS ***");
      Serial1.println(PMTK_SET_DATA_100MS); // PMTK_SET_DATA_100MS -> $PMTK001,220,3*30 //
      Serial.println("[" + String(millis()) + "] *** PMTK_SET_FIX_100MS ***");
      Serial1.println(PMTK_SET_FIX_100MS); // PMTK_SET_FIX_100MS -> $PMTK001,300,3*33 //
    }
    
    /*
     * Returns the data rate of Serial1 in baud.
     * @param rd whether to read or peek at the values.
     * @return the data rate of Serial1 in baud.
     */
    int checkBaud(bool rd) {
      enabled = false; // Disable SerialEvents //
      int rate = 0; // Default unknown value //
      unsigned int timeout = millis() + 1000; // Set poll timeout //
      char ch1, ch2;
      while (millis() < timeout) {
        if (Serial1.available() || Serial2.available()) {
          ch1 = rd ? Serial1.read() : Serial1.peek();
          ch2 = rd ? Serial2.read() : Serial2.peek();
          if (ch1 =='$') {
            rate = 9600; break;
          } else if (ch2 =='$') {
            rate = 115200; break;
          }
        }
        delay(1);
      }
      Serial.println("*** Baud " + String(rate) + " *** [" + String(millis()) + "]");
      enabled = true; // Enable SerialEvents //
      return rate;
    }
    With the GPS unit just connected, the fist character received should be a $. The checkBaud(false) function peeks at the data stream (leaving it intact) and determines which serial device can read the data and hence the speed used. The code then only requests a speed change if necessary. When necessary, the speed change request is performed in a finite loop, since it doesn't always succeed! When it succeed, we change Serial1 rate to 115200 to match.

    With all these improvements, it all works pretty well, but not always! I have since experienced the "Gotcha" message (a couple of times), where Serial1 died after initialisation (having successfully changed GPS baud rate and update frequency). The good news is that Serial2 had been running at a different speed and was not affected by the communication in the same way. In my Gotcha code, I could simply switch over to reading Serial2 and things would then work.

    So, I strongly believe that the problem lies in the speed mismatch, which explains why it is rarely encountered.

    Are there low level functions that can calculate incoming baud rate, without having to listen to all possible frequencies? Could be useful!

    I couldn't reproduce the problem using my Ublox GPS unit, as it doesn't work the same way. You have to pre-encode the settings before use, so no speed changes required.

    Tomorrow, I'll try to write a simple sequential bare-bones to directly show the effect, without having to unplug and replug Teensy into USB a dozen times...

  22. #22
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,041
    Indeed as noted EN pin connected not ever - and I don't know the state of where it was when I moved to the UBLOX, though it seemed to be showing data at 115Kbps.

    Some mods were done IIRC to message and baud, but EN not used and used on one or more other prior Teensy's and never saw loss of Serial in use to it.

    And the only GOTCHA that came was when the device wasn't powered/transmitting.

    *** Loop [53600490] ***
    [0,0,0] serialCheck() = ok
    <edit> - left it running:
    *** Loop [87761970] ***
    [0,0,0] serialCheck() = ok
    Seems something in the GPS as configured could explain it failing on two T_3.6's as tried and not seen here. Make sure you document what it takes to make your setup unique from the attempted copy [post #19] that works here so Paul can see it repro when he gets it hooked up to match. I do have a battery in my unit.
    Last edited by defragster; 10-08-2018 at 05:43 PM.

  23. #23
    Member
    Join Date
    Oct 2018
    Location
    London
    Posts
    23
    I have written a new bare-bones that breaks without having to restart or re-upload to Teensy. Pin 24 controls EN of GPS unit. Pin 28 controls Gotcha LED.

    It attempts to re-create the start conditions faced by the system that appear to cause failure. The sequence is as follows:
    1) Reset - GPS disabled through EN pin and Serial1 stopped.
    2) Start - GPS enabled and Serial1 set to 9600 baud.
    3) Rate-change - GPS requested to run at 115200 baud and Serial1 set to 115200 baud.
    4) Settings - GPS data rate requested to be 10 Hz.
    5) Run - Allow time to output incoming data before performing a health check.

    On my system it usually breaks on cycle 2, 3, or 4.

    It is interesting to note that within the killSerial() function, setting the first delay to 2500 ms doesn't kill Serial! The higher value will presumably allow the GPS unit to fully forget its settings and so will restart at 9600 baud. Otherwise I believe we have Serial1 at 9600 and GPS at 115200 baud.

    I originally coded it to be interactive, so that functions were called upon button presses. When I managed to break it, I replicated the timing in the loop by simulating button presses (hence the strange calls to buttonEventHandler).

    Have a play and let me know if it breaks for you too. (Button.h & .cpp go in Library)
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	circuit.jpg 
Views:	6 
Size:	162.1 KB 
ID:	14918  
    Attached Files Attached Files

  24. #24
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,041
    Old system
    *** Loop [116969490] ***
    [0,0,0] serialCheck() = ok
    <edit> had not wired EN to pin 24 - same results when I do - GOTCHA on 5th restart - all fine up until then. So reset code is breaking something after 'working 4 times'

    <edit #2> : after wiring EN and then a second restart of T_3.6 after " Restart Sequence 49 " - there were NO GOTCHA instances - then #50 caused a GOTCHA

    Pulled the zip - moved button code to libraries and changed to input_pullup.

    Uploaded the new sketch and saw gotcha's. Cleared the TyCommander serial output window and reset the Teensy - and no GOTCHA until 5th restart sequence.

    Seems to be showing valid GPS location - output with some edits on locate below::

    Code:
    *** Setup complete *** 
    
    *** Loop *** 
    ************************************************************
    ******************** Restart Sequence 1 ********************
    ************************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    *** Setting 115200 baud ***
    [time] (baud) packet-data
    *** PMTK_SET_DATA_100MS ***
    [3599] (115200) $GPGGA,204109.000,4812.8673,N,01234.0316,W,1,07,1.10,41.2,M,-17.0,M,,*6E
    [3606] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [3611] (115200) $GPRMC,204109.000,A,4812.8673,N,01234.0316,W,2.22,22.94,081018,,,A*45
    [3617] (115200) $GPVTG,48.94,T,,M,0.30,N,0.56,K,A*0C
    [3620] (115200) $PMTK001,220,3*30
    [3697] (115200) $GPGGA,204109.100,4812.8673,N,01234.0316,W,1,07,1.10,41.2,M,-17.0,M,,*6F
    [3704] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [3709] (115200) $GPRMC,204109.100,A,4812.8673,N,01234.0316,W,0.30,49.10,081018,,,A*49
    [3715] (115200) $GPVTG,49.10,T,,M,0.30,N,0.55,K,A*02
    [3797] (115200) $GPGGA,204109.200,4812.8673,N,01234.0316,W,1,07,1.10,41.2,M,-17.0,M,,*6C
    [3804] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [3809] (115200) $GPRMC,204109.200,A,4812.8673,N,01234.0316,W,0.30,49.28,081018,,,A*41
    [3815] (115200) $GPVTG,49.28,T,,M,0.30,N,0.55,K,A*09
    [3898] (115200) $GPGGA,204109.300,4812.8673,N,01234.0316,W,1,07,1.10,41.2,M,-17.0,M,,*6D
    [3904] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [3909] (115200) $GPGSV,3,1,12,20,75,058,19,10,73,266,28,27,53,272,,21,50,119,27*7E
    [3915] (115200) $GPGSV,3,2,12,08,32,309,19,15,29,052,24,32,27,188,19,24,15,089,18*79
    [3922] (115200) $GPGSV,3,3,12,14,07,194,,16,04,240,,18,01,299,,40,,,*4F
    [3927] (115200) $GPRMC,204109.300,A,4812.8673,N,01234.0316,W,2.11,49.44,081018,,,A*42
    [3933] (115200) $GPVTG,49.44,T,,M,0.29,N,0.55,K,A*0B
    [3997] (115200) $GPGGA,204109.400,4812.8673,N,01234.0316,W,1,07,1.10,41.2,M,-17.0,M,,*6A
    [4004] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [4009] (115200) $GPRMC,204109.400,A,4812.8673,N,01234.0316,W,2.11,49.62,081018,,,A*41
    [4015] (115200) $GPVTG,49.62,T,,M,0.29,N,0.54,K,A*0E
    
    serialCheck(avail: 0, count: 1451) = ok
    
    [4097] (115200) $GPGGA,204109.500,4812.8673,N,01234.0316,W,1,07,1.11,41.2,M,-17.0,M,,*6A
    [4104] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.95,1.11,1.60*02
    [4109] (115200) $GPRMC,204109.500,A,4812.8673,N,01234.0316,W,2.11,49.80,081018,,,A*4C
    [4115] (115200) $GPVTG,49.80,T,,M,0.29,N,0.54,K,A*02
    [4197] (115200) $GPGGA,204109.600,4812.8673,N,01234.0316,W,1,07,1.10,41.2,M,-17.0,M,,*68
    [4204] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [4208] (115200) $GPRMC,204109.600,A,4812.8673,N,01234.0316,W,0.28,49.96,081018,,,A*49
    [4215] (115200) $GPVTG,49.96,T,,M,0.28,N,0.53,K,A*03
    [4297] (115200) $GPGGA,204109.700,4812.8673,N,01234.0316,W,1,07,1.11,41.2,M,-17.0,M,,*68
    [4304] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.11,1.60*03
    [4309] (115200) $GPRMC,204109.700,A,4812.8673,N,01234.0316,W,0.28,50.13,081018,,,A*4D
    [4315] (115200) $GPVTG,50.13,T,,M,0.28,N,0.52,K,A*07
    **********************************************************
    ******************** Toggle Baud Rate ********************
    **********************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    
    *** Loop *** 
    ************************************************************
    ******************** Restart Sequence 2 ********************
    ************************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    *** Setting 115200 baud ***
    [time] (baud) packet-data
    *** PMTK_SET_DATA_100MS ***
    [7398] (115200) $GPGGA,204112.800,4812.8674,N,01234.0313,W,1,07,1.10,41.2,M,-17.0,M,,*6E
    [7404] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [7409] (115200) $GPGSV,3,1,12,20,74,058,19,10,73,266,27,27,53,271,,21,50,119,26*72
    [7415] (115200) $GPGSV,3,2,12,48,33,194,,08,32,309,20,15,29,052,23,32,27,188,20*74
    [7421] (115200) $GPGSV,3,3,12,24,15,089,17,14,07,194,,16,04,240,,18,02,299,*7D
    [7427] (115200) $GPRMC,204112.800,A,4812.8674,N,01234.0313,W,0.24,58.26,081018,,,A*48
    [7434] (115200) $GPVTG,58.26,T,,M,0.24,N,0.44,K,A*02
    [7437] (115200) $PMTK001,220,3*30
    [7497] (115200) $GPGGA,204112.900,4812.8674,N,01234.0312,W,1,07,1.10,41.2,M,-17.0,M,,*6E
    [7504] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [7509] (115200) $GPRMC,204112.900,A,4812.8674,N,01234.0312,W,0.24,58.60,081018,,,A*4A
    [7515] (115200) $GPVTG,58.60,T,,M,0.24,N,0.45,K,A*01
    [7597] (115200) $GPGGA,204113.000,4812.8674,N,01234.0312,W,1,07,1.11,41.2,M,-17.0,M,,*67
    [7604] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.95,1.11,1.60*02
    [7609] (115200) $GPRMC,204113.000,A,4812.8674,N,01234.0312,W,0.25,58.95,081018,,,A*49
    [7615] (115200) $GPVTG,58.95,T,,M,0.25,N,0.45,K,A*0A
    [7697] (115200) $GPGGA,204113.100,4812.8674,N,01234.0312,W,1,07,1.10,41.2,M,-17.0,M,,*67
    [7703] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [7708] (115200) $GPRMC,204113.100,A,4812.8674,N,01234.0312,W,0.24,59.29,081018,,,A*4F
    [7715] (115200) $GPVTG,59.29,T,,M,0.24,N,0.45,K,A*0D
    [7797] (115200) $GPGGA,204113.200,4812.8674,N,01234.0312,W,1,07,1.10,41.2,M,-17.0,M,,*64
    [7804] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [7809] (115200) $GPRMC,204113.200,A,4812.8674,N,01234.0312,W,0.24,59.63,081018,,,A*42
    [7815] (115200) $GPVTG,59.63,T,,M,0.24,N,0.45,K,A*03
    
    serialCheck(avail: 0, count: 1460) = ok
    
    [7898] (115200) $GPGGA,204113.300,4812.8674,N,01234.0312,W,1,07,1.11,41.2,M,-17.0,M,,*64
    [7905] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.95,1.11,1.60*02
    [7910] (115200) $GPGSV,3,1,12,20,74,058,19,10,73,266,27,27,53,271,,21,50,119,26*72
    [7916] (115200) $GPGSV,3,2,12,48,33,194,,08,32,309,20,15,29,052,23,32,27,188,20*74
    [7922] (115200) $GPGSV,3,3,12,24,15,089,17,14,07,194,,16,04,240,,18,02,299,*7D
    [7927] (115200) $GPRMC,204113.300,A,4812.8674,N,01234.0312,W,0.24,59.96,081018,,,A*49
    [7934] (115200) $GPVTG,59.96,T,,M,0.24,N,0.45,K,A*09
    [7997] (115200) $GPGGA,204113.400,4812.8674,N,01234.0312,W,1,07,1.10,41.2,M,-17.0,M,,*62
    [8004] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [8008] (115200) $GPRMC,204113.400,A,4812.8674,N,01234.0312,W,0.24,60.29,081018,,,A*40
    [8015] (115200) $GPVTG,60.29,T,,M,0.24,N,0.45,K,A*07
    **********************************************************
    ******************** Toggle Baud Rate ********************
    **********************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    
    *** Loop *** 
    ************************************************************
    ******************** Restart Sequence 3 ********************
    ************************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    *** Setting 115200 baud ***
    [time] (baud) packet-data
    *** PMTK_SET_DATA_100MS ***
    [11120] (115200) $PMTK001,220,3*30
    [11197] (115200) $GPGGA,204116.600,4812.8675,N,01234.0309,W,1,07,1.10,41.2,M,-17.0,M,,*6E
    [11204] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [11208] (115200) $GPRMC,204116.600,A,4812.8675,N,01234.0309,W,0.23,69.60,081018,,,A*4F
    [11215] (115200) $GPVTG,69.60,T,,M,0.23,N,0.43,K,A*02
    [11297] (115200) $GPGGA,204116.700,4812.8675,N,01234.0309,W,1,07,1.10,41.2,M,-17.0,M,,*6F
    [11304] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [11309] (115200) $GPRMC,204116.700,A,4812.8675,N,01234.0309,W,0.23,69.85,081018,,,A*45
    [11315] (115200) $GPVTG,69.85,T,,M,0.23,N,0.43,K,A*09
    [11398] (115200) $GPGGA,204116.800,4812.8675,N,01234.0309,W,1,07,1.10,41.2,M,-17.0,M,,*60
    [11404] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [11409] (115200) $GPGSV,3,1,12,20,74,059,20,10,73,266,26,27,53,271,,21,50,120,25*71
    [11415] (115200) $GPGSV,3,2,12,48,33,194,,08,32,309,19,15,29,052,23,32,27,188,20*7E
    [11421] (115200) $GPGSV,3,3,12,24,15,089,14,14,07,194,,16,04,240,,18,02,299,*7E
    [11427] (115200) $GPRMC,204116.800,A,4812.8675,N,01234.0309,W,0.23,70.10,081018,,,A*4E
    [11434] (115200) $GPVTG,70.10,T,,M,0.23,N,0.42,K,A*0C
    [11497] (115200) $GPGGA,204116.900,4812.8675,N,01234.0308,W,1,07,1.11,41.2,M,-17.0,M,,*61
    [11504] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.95,1.11,1.60*02
    [11509] (115200) $GPRMC,204116.900,A,4812.8675,N,01234.0308,W,0.22,70.35,081018,,,A*48
    [11515] (115200) $GPVTG,70.35,T,,M,0.22,N,0.42,K,A*0A
    [11597] (115200) $GPGGA,204117.000,4812.8675,N,01234.0308,W,1,07,1.10,41.2,M,-17.0,M,,*68
    [11604] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.95,1.10,1.60*03
    [11609] (115200) $GPRMC,204117.000,A,4812.8675,N,01234.0308,W,0.23,70.60,081018,,,A*41
    
    serialCheck(avail: 0, count: 1426) = ok
    
    [11615] (115200) $GPVTG,70.60,T,,M,0.23,N,0.42,K,A*0B
    [11697] (115200) $GPGGA,204117.100,4812.8675,N,01234.0308,W,1,07,1.11,41.2,M,-17.0,M,,*68
    [11703] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.95,1.11,1.60*02
    [11708] (115200) $GPRMC,204117.100,A,4812.8675,N,01234.0308,W,0.23,70.84,081018,,,A*4A
    [11715] (115200) $GPVTG,70.84,T,,M,0.23,N,0.42,K,A*01
    [11797] (115200) $GPGGA,204117.200,4812.8675,N,01234.0308,W,1,07,1.10,41.2,M,-17.0,M,,*6A
    [11804] (115200) $GPGSA,A,3,08,21,20,32,15,24,10,,,,,,1.94,1.10,1.60*02
    [11809] (115200) $GPRMC,204117.200,A,4812.8675,N,01234.0308,W,0.23,71.08,081018,,,A*4C
    [11815] (115200) $GPVTG,71.08,T,,M,0.23,N,0.42,K,A*04
    **********************************************************
    ******************** Toggle Baud Rate ********************
    **********************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    
    *** Loop *** 
    ************************************************************
    ******************** Restart Sequence 4 ********************
    ************************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    *** Setting 115200 baud ***
    [time] (baud) packet-data
    *** PMTK_SET_DATA_100MS ***
    
    ******************** Gotcha! ********************
    
    **********************************************************
    ******************** Toggle Baud Rate ********************
    **********************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    
    *** Loop *** 
    ************************************************************
    ******************** Restart Sequence 5 ********************
    ************************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    *** Setting 115200 baud ***
    [time] (baud) packet-data
    *** PMTK_SET_DATA_100MS ***
    
    ******************** Gotcha! ********************
    
    **********************************************************
    ******************** Toggle Baud Rate ********************
    **********************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    
    *** Loop *** 
    ************************************************************
    ******************** Restart Sequence 6 ********************
    ************************************************************
    *** Setting 9600 baud ***
    [time] (baud) packet-data
    Last edited by defragster; 10-08-2018 at 10:05 PM.

  25. #25
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    7,041
    To see steady state running >> start with TESTING=TRUE, then set it FALSE in first LOOP() with edit to loop() code below - edits in BOLD.

    Without initial testing pass in loop() I only got GOTCHA. Allowing first testing pass showing valid data - then stopping testing it continues fine, with baud rate left at 115K.

    Something in the recurring testing or changing BAUD process if causing the lockup - not general Teensy function.

    With this loop() code it had passes 325 loops and running fine

    Code:
    void loop() {
    static uint32_t cLoops=0;
      Serial.print("\n*** Loop *** =");
      Serial.println(++cLoops);
      if (testing) {
        buttonEventHandler(BTN_1, 0); // Attempt to kill Serial - usually doesn't succeed - the force is strong in that one!
        delayMillis(250); // Allow to adjust to higher baud //
        //serial1_9600_baud = false; // Toggle to 9600 baud //
        buttonEventHandler(BTN_2, 0); // Restore Serial1 to 9600 baud - will fail to read incoming 115200 baud data //
        delayMillis(250); // Allow to settle in //
        testing = false;
      } else {
        //delayMillis(1000);
      delayMillis(500);                      // Allow time to receive data //
      serialEvent1();
      serialCheck(); // Check Health: should have received data by now! //
      delayMillis(500);                      // Allow time to receive data //
      serialEvent1();
      serialCheck(); // Check Health: should have received data by now! //
      }
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •