Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 16 of 16

Thread: Teensy I2C Sniffer for MPU6050

  1. #1

    Teensy I2C Sniffer for MPU6050

    I believe I have finally succeeded in creating a usable I2C sniffer, somewhat specialized for monitoring traffic between an I2C master and a MPU6050 slave.

    The complete sniffer program is available from my Github account here. The complete Arduino Mega program I used to test the sniffer program is given below.

    Thanks to everyone who contributed their suggestions and ideas for this project; I had a lot of fun and learned a lot about I2C, Teensy programming and ISRs.

    For all the gory details, see my 'Paynters Palace' blog post here.

    Frank

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,369
    Very cool looking. I don't have an MPU6050 to watch - wondering what happens if it just watches any random i2C transfers?

    Looks like this external file is really needed - not on my system:
    >> #include "helper_3dmath.h" //Arduino\Libraries\i2cdevlib\Arduino\MPU6050\ needed to compute yaw from MPU6050 DMP packet
    T:\tCode\i2c\Teensy_I2C_Sniffer_V11-master\Teensy_I2C_Sniffer_V11\Teensy_I2C_Sniffer_V 11.ino:37:120: fatal error: helper_3dmath.h: No such file or directory
    compilation terminated.
    www gives me that from :: https://github.com/ElectronicCats/mp...elper_3dmath.h

    > ignores Silly #pragma warnings like in IDE based build from SublimeText editor: #pragma region PROCESSING_VARIABLES
    > fails build on T_4.0 because of GPIO access:
    -- > T:\tCode\i2c\Teensy_I2C_Sniffer_V11-master\Teensy_I2C_Sniffer_V11\Teensy_I2C_Sniffer_V 11.ino:139:21: error: 'GPIOB_PDIR' was not declared in this scope
    -- > current_portb = GPIOB_PDIR & 12; //reads state of SDA (18) & SCL (19) at same time
    > builds for T_3.6 and seems ready to run:
    Serial available after 1500 mSec
    2001: Waiting for Data...
    2201: Waiting for Data...
    2401: Waiting for Data...
    Not sure why but the T_3.6 had some false starts - after starting as above - then re-uploading code and it is running and running ...

    And hooking it up to a T4 running an i2c SSD1306 at 400 MHz:
    Code:
    485542 I2C(3c) writing 31 bytes to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    485542 I2C(3c) writing 31 bytes to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    485542 I2C(3c) writing 31 bytes to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    485542 I2C(3c) writing 1 bytes to 40... 0 . Done
    485542 I2C(3c) writing 5 bytes to 0... 22 0 ff 21 0 . Done
    485542 I2C(3c) writing 1 bytes to 0... 7f . Done
    485541: processed = 2048 elements in 1 mSec
    
    485555 I2C(3c) writing 31 bytes to 40... 49 49 49 49 49 49 49 49 49 29 29 29 29 29 29 29 29 a5 a5 a5 a5 a5 a5 a5 a5 95 95 95 55 55 55 . Done
    485555 I2C(3c) writing 31 bytes to 40... 55 55 55 55 55 55 d5 b5 b5 b5 ad ad ad ad 6d 6d 6d 6d 5b 5b 5b 5b 3b 3b 3b 3b 37 37 2f 2f 1f . Done
    485555 I2C(3c) writing 31 bytes to 40... 1f 1f 1f 1f 1f 1f 1f f f f f f f f f 7 7 7 7 7 7 7 7 3 3 3 3 3 3 3 3 . Done
    485555 I2C(3c) writing 11 bytes to 40... 1 1 1 1 11 11 11 11 91 91 89 . Done
    485554: processed = 2048 elements in 1 mSec
    
    485567 I2C(3c) writing 31 bytes to 40... 22 12 12 12 12 12 12 12 12 a a 9 9 9 9 9 9 5 5 5 5 4 4 4 4 2 2 2 2 2 2 . Done
    485567 I2C(3c) writing 31 bytes to 40... 2 2 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    485567 I2C(3c) writing 31 bytes to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    485567 I2C(3c) writing 11 bytes to 40... 0 0 0 0 0 0 0 0 1 1 1 . Done
    485566: processed = 2048 elements in 1 mSec
    
    …
    
    
    485651 I2C(3c) writing 1 bytes to 40... 0 . Done
    485651 I2C(3c) writing 5 bytes to 0... 22 0 ff 21 0 . Done
    485651 I2C(3c) writing 1 bytes to 0... 7f . Done
    485651 I2C(3c) writing 31 bytes to 40... 11 11 11 11 11 11 11 11 91 91 91 91 91 91 91 91 89 89 89 89 89 89 89 89 49 49 49 49 49 49 49 . Done
    485651 I2C(3c) writing 31 bytes to 40... 49 49 49 49 49 49 49 49 49 29 29 29 29 29 29 29 29 a5 a5 a5 a5 a5 a5 a5 a5 95 95 95 55 55 55 . Done
    485651 I2C(3c) writing 31 bytes to 40... 55 55 55 55 55 55 d5 b5 b5 b5 ad ad ad ad 6d 6d 6d 6d db db db db bb bb 7b 7b 77 77 6f 6f 5f . Done
    485650: processed = 2048 elements in 1 mSec
    
    485664 I2C(3c) writing 31 bytes to 40... 1 1 1 1 11 11 11 11 91 91 89 89 88 88 88 88 48 48 48 48 44 44 44 44 24 24 24 24 24 24 24 . Done
    485664 I2C(3c) writing 31 bytes to 40... 22 12 92 92 92 92 92 92 52 4a 4a 49 49 49 49 29 29 25 25 25 25 14 14 14 14 12 12 a a a a . Done
    485664 I2C(3c) writing 31 bytes to 40... a a 9 5 5 5 5 5 5 3 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 . Done
    485664 I2C(3c) writing 11 bytes to 40... 0 0 0 0 0 0 0 0 0 0 0 . Done
    485664: processed = 2048 elements in 1 mSec

    Not sure what this is telling me from the VS2019 here?:
    1>------ Build started: Project: Teensy_I2C_Sniffer_V11, Configuration: Debug Win32 ------
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: The "VCMessage" task failed unexpectedly.
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: System.FormatException: Index (zero based) must be greater than or equal to zero and less than the size of the argument list.
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: at System.Text.StringBuilder.AppendFormatHelper(IForm atProvider provider, String format, ParamsArray args)
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: at System.String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: at System.String.Format(IFormatProvider provider, String format, Object[] args)
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: at Microsoft.Build.Shared.ResourceUtilities.FormatStr ing(String unformatted, Object[] args)
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: at Microsoft.Build.Utilities.TaskLoggingHelper.Format String(String unformatted, Object[] args)
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: at Microsoft.Build.Utilities.TaskLoggingHelper.Format ResourceString(String resourceName, Object[] args)
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: at Microsoft.Build.Utilities.TaskLoggingHelper.LogErr orWithCodeFromResources(String messageResourceName, Object[] messageArgs)
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: at Microsoft.Build.CPPTasks.VCMessage.Execute()
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: at Microsoft.Build.BackEnd.TaskExecutionHost.Microsof t.Build.BackEnd.ITaskExecutionHost.Execute()
    1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Mi crosoft.CppBuild.targets(382,5): error MSB4018: at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstan tiatedTask>d__26.MoveNext()
    1>Done building project "Teensy_I2C_Sniffer_V11.vcxproj" -- FAILED.
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
    Glad the FASTRUN helped!

    the bDone is still there as it was? I see it runs continuously - maybe after filling one buffer toggle to a second buffer ? The it would never be Done - just run and toggle the buffer? Didn't look any deeper.

  3. #3
    Defragster,

    The only MPU6050-specific feature is the ability to recognized and decode the 28-byte DMP FIFO packet containing accelerometer data (this is the only thing the helper_3dmath.h library is used for). If you replace


    Code:
    void OutputFormattedSentence(int RW, uint8_t dev, uint8_t reg, uint8_t numbytes, uint8_t* bytearray, uint16_t startidx)
    {
        Serial.printf("%lu I2C(%x) %s %d bytes %s %x... ",
            millis(), dev, (RW == 0 ? "writing" : "reading"),  numbytes - startidx, (RW == 0 ? "to" : "from"), reg);
        for (size_t i = startidx; i < numbytes; i++)
        {
            Serial.printf("%x ", bytearray[i]);
        }
    
        //01/18/20 experiment to decode 28-byte packet into yaw value
        if (numbytes == 28)
        {
            dmpGetQuaternion(&q, bytearray);
            dmpGetGravity(&gravity, &q);
            dmpGetYawPitchRoll(ypr, &q, &gravity);
    
            //compute the yaw value
            global_yawval = ypr[0] * 180 / M_PI;
            Serial.printf("yawval = %3.2f\n", global_yawval);
        }
        else
        {
            Serial.printf(". Done\n");
        }
    }
    with

    Code:
    void OutputFormattedSentence(int RW, uint8_t dev, uint8_t reg, uint8_t numbytes, uint8_t* bytearray, uint16_t startidx)
    {
        Serial.printf("%lu I2C(%x) %s %d bytes %s %x... ",
            millis(), dev, (RW == 0 ? "writing" : "reading"),  numbytes - startidx, (RW == 0 ? "to" : "from"), reg);
        for (size_t i = startidx; i < numbytes; i++)
        {
            Serial.printf("%x ", bytearray[i]);
        }
    	
    	Serial.printf(". Done\n");
    }
    Then you can get rid of 'helper_3dmath.h' and all the support functions dealing with yaw value calculation (everything in #pragma region YAW_COMPUTATIONS). Then the code should work with any master/slave I2C setup, regardless of the slave device, with the following assumptions.

    The code assumes a 'burst' of I2C data of 2048 bytes or fewer, followed by at least 2500 IDLE (0xc 0xc 0xc ...) bytes, followed by 1-2 mSec for processing/printing. If more than 2048 bytes are captured without IDLE detection, the program toggles the 'Done' flag anyway to avoid buffer overrun, at the cost of losing part of the I2C traffic. In my application, the bursts were typically 1200-1400 bytes over 5-10 mSec, followed by 195-190 mSec of IDLE. Processing takes just 1-2 mSec on a T3.2.

    At one time I worked on a scheme that would load captured bytes into a circular buffer to avoid the above problem, but abandoned it when I couldn't get the circular buffer code to work, and I discovered that MPU6050 conversations in my application were 'bursts' of well less than 2048 bytes followed by long pauses (200 mSec in my case).

    The program should run fine with larger buffers, up to whatever the processor can handle. The real limitation is the 1 uSec sample rate; you need at least two samples per baud, so it will probably do fine for 200Kbs I2C bus rate, and maybe even 400Kbs. If the T4 can sample faster, then higher I2C bus rates are possible.

    The program is designed to run continuously. The original (and current) application is for long-term logging to troubleshoot intermittent failures where the I2C bus quits working for some unknown reason after minutes/hours/days. The idea is to analyze the sniffer logs up to the failure point and maybe determine what happened.

    I use #pragma region to allow me to toggle blocks of code lines in/out, just for ease of reading. Add '-Wno-unknown-pragmas' to the 'extra cpp flags' line in Visual Micro->Compiler->Advanced to disable these warnings (see my thread in the VM forum about making that available as a global VM option).

    No idea about the VS2019 error messages - compiles fine here on a T3.2. Here's the verbose compile output:

    Code:
    Compiling debug version of 'Teensy_I2C_Sniffer_V11' for 'Teensy 3.2 / 3.1'
    Build Folder: "file:///C:/Users/Frank/AppData/Local/Temp/VMBuilds/Teensy_I2C_Sniffer_V11/teensy31/Debug"
    Additional Defines: VM_DEBUGGER_TYPE_HARDWARESERIAL 0;VM_DEBUGGER_TYPE_SOFTWARESERIAL 1;VM_DEBUGGER_TYPE_FASTSERIAL 2;VM_DEBUGGER_TYPE_USB 3;VM_DEBUGGER_TYPE_TEENSY 4;VM_DEBUGGER_TYPE_UART 5;VM_DEBUGGER_TYPE_USART 6;VM_DEBUGGER_TYPE_USBSERIAL 7;VM_DEBUGGER_TYPE_TTYUART 8;VM_DEBUGGER_TYPE_NET_CONSOLE 9;VM_DEBUGGER_TYPE_Uart 10;VM_DEBUGGER_TYPE_COSA 11;VM_DEBUGGER_TYPE_CDCSerialClass 12;VM_DEBUGGER_TYPE_HARDWARESERIAL1 13;VM_DEBUGGER_TYPE_HARDWARESERIAL2 14;VM_DEBUGGER_TYPE_HARDWARESERIAL3 15;VM_DEBUGGER_TYPE_NET_UDP 16;VM_DEBUGGER_TYPE_USBAPI 17;VM_DEBUGGER_TYPE_SERIALUSB 18;VM_DEBUGGER_TYPE_MS430_SERIAL_ 19;VM_DEBUGGER_TYPE_NO_SERIAL 20;VM_DEBUGGER_TYPE_GENERIC_OBJECT 21;VM_DEBUG_ENABLE 1;VM_DEBUG;VM_DEBUG_BANDWIDTH_THROTTLE_MS 50;VM_DEBUGGER_SOFT_TRANSPORT Serial;VM_DEBUGGER_SOFT_TRANSPORT_WRITER Serial;VM_DEBUGGER_TYPE VM_DEBUGGER_TYPE_GENERIC_OBJECT;VM_DEBUG_BREAKPAUSE;
    Architecture Tools: "file:///C:/Program%20Files%20(x86)/Arduino/hardware/tools/"
    Api: 1.1911.23-1
    Sketch Book: "file:///C:/Users/Frank/Documents/Arduino"
    Sketch Include Paths
    Core Include Paths
    Include Path "file:///C:/Program%20Files%20(x86)/Arduino/hardware/teensy/avr/cores/teensy3"
     
    Deep search for libraries ...
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\Teensy_I2C_Sniffer_V11.cpp" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\Teensy_I2C_Sniffer_V11.cpp" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\Teensy_I2C_Sniffer_V11.cpp" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne\utility" "C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne\TimerOne.cpp" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\utility" "c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\VM_DBG.cpp" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\utility" "c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\VM_mem_check.c" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\utility" "c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\VM_mem_check_sam.cpp" -o "nul"
    recipe.hooks.sketch.prebuild.1.pattern
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/precompile_helper" "C:\Program Files (x86)\Arduino\hardware\teensy\avr/cores/teensy3" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug" "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -x c++-header -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Program Files (x86)\Arduino\hardware\teensy\avr/cores/teensy3" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/pch/Arduino.h" -o "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/pch/Arduino.h.gch"
     
    Building core ...
     
    Using previously compiled file: C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\pch\Arduino.h.gch
    Building libraries ...
    
    Using library TimerOne version 1.1 in folder "file:///C:/Program%20Files%20(x86)/Arduino/hardware/teensy/avr/libraries/TimerOne"
      Using previously compiled file: C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\TimerOne\TimerOne.cpp.o
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant  -Wno-unknown-pragmas -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0 -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/pch" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" "c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\VM_DBG.cpp" -o "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\VM_DBG\VM_DBG.cpp.o"
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant  -Wno-unknown-pragmas -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0 -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/pch" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" "c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\VM_mem_check_sam.cpp" -o "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\VM_DBG\VM_mem_check_sam.cpp.o"
     
    Building project code ...
      Using previously compiled file: C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\Teensy_I2C_Sniffer_V11.cpp.o
     
    Linking it all together ...
    # Coping cached core C:\Users\Frank\AppData\Local\Temp\VMBCore\arduino16x\ab727a508ff6ae253f543daa72752d82\core.a to C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\core.a
    
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-gcc" -O2 -Wl,--gc-sections,--relax,--defsym=__rtc_localtime=1579425138 "-TC:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3/mk20dx256.ld" -lstdc++ -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -o "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/Teensy_I2C_Sniffer_V11.ino.elf" "Teensy_I2C_Sniffer_V11.cpp.o" "TimerOne\TimerOne.cpp.o" "VM_DBG\VM_DBG.cpp.o" "VM_DBG\VM_mem_check_sam.cpp.o" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/core.a" "-LC:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug" -larm_cortexM4l_math -lm
    ## recipe.objcopy.eep.pattern
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/Teensy_I2C_Sniffer_V11.ino.elf" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/Teensy_I2C_Sniffer_V11.ino.eep"
    ## recipe.objcopy.hex.pattern
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-objcopy" -O ihex -R .eeprom "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/Teensy_I2C_Sniffer_V11.ino.elf" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/Teensy_I2C_Sniffer_V11.ino.hex"
    
    Program Teensy_I2C_Sniffer_V11 size: 38,928 bytes (used 15% of a 262,144 byte maximum) (3.08 secs)
    Minimum Memory Usage: 11652 bytes (18% of a 65536 byte maximum)
     
    recipe.hooks.postbuild.1.pattern
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/stdout_redirect" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/Teensy_I2C_Sniffer_V11.ino.lst" "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-objdump" -d -S -C "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/Teensy_I2C_Sniffer_V11.ino.elf"
    recipe.hooks.postbuild.2.pattern
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/stdout_redirect" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/Teensy_I2C_Sniffer_V11.ino.sym" "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-objdump" -t -C "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/Teensy_I2C_Sniffer_V11.ino.elf"
    recipe.hooks.postbuild.3.pattern
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/teensy_post_compile" "-file=Teensy_I2C_Sniffer_V11.ino" "-path=C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug" "-tools=C:\Program Files (x86)\Arduino\hardware\teensy/../tools/" "-board=TEENSY31"
    # Copy build result to 'Project>Property Pages>Intermediate Directory'
    # Destination: file:///C:/Users/Frank/Documents/Arduino/Teensy_I2C_Sniffer_V11/Debug/



    Frank

  4. #4
    Anyone,

    I have been trying to generalize my I2C sniffer for all I2C devices. Only the code that computes a yaw value from a 28-byte packet returned from a MPU6050 register is specific to the device; everything else should work fine with any I2C slave.

    So, I placed #ifdef MPU6050_SPECIFIC/#endif guards around all these bits, expecting everything to compile fine, but of course it didn't :-(. The following code compiles fine.


    Code:
    /*
        Name:       Teensy_I2C_Sniffer_V11.ino
        Created:	1/18/2020 10:55:55 AM
        Author:     FRANKNEWXPS15\Frank
    */
    /* 'Notes:
    
        A typical I2C sentence when communicating with a MPU6050 IMU module goes something like:
            "I2C(68) wrote 1 byte to 75 - C0 Done."
            "I2C(68) wrote 3 bytes to 72 - C0 0C 10 Done."
            "I2C(68) read 5 bytes from 6A - C0 0C 10 14 03 Done."
    
        To form a sentence, we need:
            Device addr: 68 in the above examples
            Read/Write direction
            To/From register address:  75, 72 and 6A in the above examples
            Data:  C0, C0 0C 10, and C0 0C 10 14 03 in the above examples
            number of bytes written/read:  1,3 & 5 in the above examples
    
         Each I2C communication proceeds as follows (assuming a START from an IDLE condition):
             A START or RESTART condition, denoted by SDA & SCL HIGH, followed by SDA LOW, SCL HIGH
             A 7-bit device address, MSB first (0x8/0xC = 1, 0x0/0x4 = 0)
             A R/W bit (0x8/0xC = read, 0x0/0x4 = write)
             An ACK bit (0x8/0xC = NAK, 0x0/0x4 = ACK)
             If the bus direction is WRITE, then
                 A register address for read/write
                 zero or more additional data bytes
             Else (the bus direction is READ)
                One or more additional data bytes
             Endif
    
        This version uses a fixed-size (2048 bytes) array instead of tonton81's circular buffer library.
    */
    //#define MPU6050_SPECIFIC
    
    #include <TimerOne.h> //needed for ISR
    
    //#ifdef MPU6050_SPECIFIC
    #include "helper_3dmath.h" //Arduino\Libraries\i2cdevlib\Arduino\MPU6050\ needed to compute yaw from MPU6050 DMP packet
    //#endif // MPU6050_SPECIFIC
    
    //#define PARSE_LOOP_DEBUG
    
    const uint16_t CAPTURE_ARRAY_SIZE = 2048;
    const uint16_t VALID_DATA_ARRAY_SIZE = 2048;
    const int WAITING_PRINT_INTERVAL_MSEC = 200;//interval timer for 'Waiting for data...' printout
    
    #define MONITOR_OUT1 2 //so can monitor ISR activity with O'scope
    #define MONITOR_OUT2 3 //so can monitor ISR activity with O'scope
    #define MONITOR_OUT3 4 //so can monitor ISR activity with O'scope
    #define SDA_PIN 18 
    #define SCL_PIN 19
    
    #pragma region PROCESSING_VARIABLES
    uint8_t devAddr;
    uint8_t regAddr;
    uint8_t databytes[2048]; //holds multiple databytes for later output sentence construction
    uint16_t numbytes = 0; //number of data bytes extracted from data stream
    int ACKNAKFlag; //can be negative
    uint16_t databyte_idx = 0; //index into databyte_array
    uint8_t killbuff[2]; //used to consume start/stop bytes
    elapsedMillis mSecSinceLastWaitingPrint;
    uint8_t valid_data[2048];
    uint16_t numvalidbytes = 0; //number of valid bytes in this burst
    uint16_t read_idx = 0; //pointer to next byte pair to be processed
    
    //added for bus direction labels
    enum BUSDIR
    {
        WRITE,
        READ,
        UNKNOWN = -1
    } RWDir;
    BUSDIR BusDir = BUSDIR::UNKNOWN;
    #pragma endregion ProcVars
    
    
    #pragma region ISR_SUPPORT
    uint8_t raw_data[CAPTURE_ARRAY_SIZE]; //holds data captured from I2C bus
    volatile uint16_t  write_idx = 0;
    volatile uint8_t   current_portb = 0xFF;
    volatile uint8_t   last_portb = 0xFF;
    volatile uint16_t mult0xCCount = 0;
    const uint16_t MAX_IDLE_COUNT = 2500;
    
    volatile bool bDone = false;
    volatile bool bWaitingForStart = true;
    volatile bool bIsData = true;
    volatile bool bIsStart = false;
    volatile bool bIsStop = false;
    volatile uint8_t last_current;
    #pragma endregion ISR Support
    
    #ifdef MPU6050_SPECIFIC
    Quaternion q;           // [w, x, y, z]         quaternion container
    VectorInt16 aa;         // [x, y, z]            accel sensor measurements
    VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
    VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
    VectorFloat gravity;    // [x, y, z]            gravity vector
    float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector
    float global_yawval = 0; //updated by GetIMUHeadingDeg()
    #endif // MPU6050_SPECIFIC
    
    void setup()
    {
        unsigned long now = millis();
        Serial.begin(1); //rate value ignored
        int idx = 0;
        while (!Serial && (millis() - now) < 3000)
        {
            delay(500);
            idx++;
        }
        Serial.printf("Serial available after %lu mSec\n", millis() - now);
    
        pinMode(MONITOR_OUT1, OUTPUT);
        digitalWrite(MONITOR_OUT1, LOW);
        pinMode(MONITOR_OUT2, OUTPUT);
        digitalWrite(MONITOR_OUT2, LOW);
        pinMode(MONITOR_OUT3, OUTPUT);
        digitalWrite(MONITOR_OUT3, LOW);
    
        pinMode(SCL_PIN, INPUT);
        pinMode(SDA_PIN, INPUT);
    
        //reset port byte vars & start timer
        last_portb = current_portb = 0;
        write_idx = 0;
        memset(raw_data, 255, CAPTURE_ARRAY_SIZE);
        //PrintNextArrayBytes(raw_data, 255, 20);
        Timer1.initialize(1); // run every mico second
        Timer1.attachInterrupt(capture_data);
    
    
        mSecSinceLastWaitingPrint = 0;
    }
    //-------------------------------------------------------------------------------
    //--------------------------------    ISR    ------------------------------------
    //-------------------------------------------------------------------------------
    FASTRUN void capture_data()
    //void capture_data()
    {
        last_portb = current_portb;
        current_portb = GPIOB_PDIR & 12; //reads state of SDA (18) & SCL (19) at same time
    
        if (!bDone && last_portb != current_portb)
        {
            mult0xCCount = 0; //reset IDLE counter
            digitalWriteFast(MONITOR_OUT1, HIGH);
    
            //01/17/20: joepasquariello suggestion
            last_current = (last_portb << 4) | (current_portb);
            bIsStart = (last_current == 0xC4);
            bIsStop = (last_current == 0x4C);
            bIsData = (last_current == 0x04) || (last_current == 0x8C);
    
            if (bIsStart) //START  
            {
                digitalWriteFast(MONITOR_OUT2, HIGH);
                if (bWaitingForStart)
                {
                    digitalWriteFast(MONITOR_OUT3, HIGH); //start of entire capture
                    bWaitingForStart = false;
                }
            }
            else if (bIsStop) //STOP
            {
                digitalWriteFast(MONITOR_OUT2, LOW);
            }
    
            if (!bWaitingForStart && (bIsData || bIsStart || bIsStop))
            {
                //digitalWriteFast(MONITOR_OUT3, HIGH);
                raw_data[write_idx] = last_portb;
                write_idx++;
                raw_data[write_idx] = current_portb;
                write_idx++;
                if (write_idx >= CAPTURE_ARRAY_SIZE)
                {
                    bDone = true;
                    digitalWriteFast(MONITOR_OUT3, LOW);
                }
            }
            digitalWriteFast(MONITOR_OUT1, LOW);
        }
        else if (!bDone && mult0xCCount < MAX_IDLE_COUNT && last_portb == 0xc && current_portb == 0xc)
        {
            mult0xCCount++;
            if (mult0xCCount >= MAX_IDLE_COUNT)
            {
                digitalWriteFast(MONITOR_OUT3, LOW);
                bDone = true;
            }
        }
    }
    //-------------------------------------------------------------------------------
    //-------------------------------- END ISR    ---------------------------------
    //-------------------------------------------------------------------------------
    
    void loop()
    {
        if (bDone)
        { 
            if (write_idx > 14)
            {
                //OK, we have some data to process. IDLE detection must have been EOM
                Timer1.stop();
    
                unsigned long startMsec = millis();
    
                //Serial.printf("%lu\t %d\t", millis(), write_idx);
                //PrintNextArrayBytes(raw_data, 0, 50);
                //Serial.printf(" - %lu\n", millis());
                uint16_t numprocessed = DecodeAndPrintValidData(raw_data); //decode and print everything captured so far
                unsigned long endMsec = millis();
                Serial.printf("%lu: processed = %d elements in %lu mSec\n\n", startMsec, numprocessed, endMsec-startMsec);
    
                Timer1.start();
            }
    
            read_idx = 0;
            bDone = false;
            mult0xCCount = 0;
            write_idx = 0;
            bWaitingForStart = true;
        }    
        else
        {
            //no data to process, but don't blow prints out every mSec...
            if (mSecSinceLastWaitingPrint > WAITING_PRINT_INTERVAL_MSEC)
            {
                mSecSinceLastWaitingPrint -= WAITING_PRINT_INTERVAL_MSEC;
                Serial.printf("%lu: Waiting for Data...\n", millis());
            }
        }
    }
    
    void PrintNextArrayBytes(uint8_t* data, uint16_t startidx, uint16_t numbytes)
    {
        Serial.printf("%d bytes starting at %d: ", numbytes, startidx);
        for (uint16_t i = 0; i < numbytes; i++)
        {
            Serial.printf("%x ", data[i + startidx]);
        }
    }
    
    
    uint16_t DecodeAndPrintValidData(byte* data)
    {
        //Purpose:  decode and print I2C conversation held in raw_data array
        //Inputs:  
        //  cb = 2048 element FIFO
        //Outputs:
        //  returns number of bytes processed, or -1 for failure
        //  outputs structured I2C sentence to serial monitor
        //Plan:
        //  Step1: Cull out invalid bytes
        //  Step2: Determine if there is anything to do (have to have more than one transition in FIFO)
        //  Step3: Parse transitions into I2C sentence structure
        //  Step4: Output sentence to serial monitor
    
        memset(valid_data, 0, VALID_DATA_ARRAY_SIZE);
    #ifdef PARSE_LOOP_DEBUG
        PrintNextArrayBytes(valid_data, 0, 20); //print out first 20 bytes for verification
    #endif
        numvalidbytes = RemoveInvalidBytes(raw_data, valid_data);
    #ifdef PARSE_LOOP_DEBUG
        Serial.printf("Removed %d invalid bytes, leaving %d remaining\n", write_idx + 1 - numvalidbytes, numvalidbytes);
        PrintNextArrayBytes(valid_data, 0, numvalidbytes); //print out first 20 bytes of valid_data array
    #endif
    
    
        if (numvalidbytes < 2)
        {
            return 0;
        }
    
        while (read_idx < numvalidbytes)
        {
    #ifdef PARSE_LOOP_DEBUG
            Serial.printf("At top of while (read_idx < numvalidbytes): read_idx = %d\n", read_idx);
            Serial.printf("Next two bytes in valid_data are %x, %x\n", valid_data[read_idx], valid_data[read_idx + 1]);
    #endif
            //Find a START sequence (0xC followed by 0x4)
            while (!IsStart(valid_data, read_idx) && read_idx < numvalidbytes)
            {
                //Serial.printf("looking for start...\n");
                read_idx++;
            }
            //at this point, read_idx should point to next valid byte pair
    
    #ifdef PARSE_LOOP_DEBUG
            Serial.printf("Start sequence found at %d\n", read_idx - 2);
            //PrintNextFIFOBytes(valid_data, 20);
    #endif
    
            if (numvalidbytes - read_idx > 14)//14 entries required for 7-bit address
            {
                //Get 7-bit device address
                devAddr = Get7BitDeviceAddr(valid_data, read_idx);
    #ifdef PARSE_LOOP_DEBUG
                Serial.printf("devAddr = %x\n", devAddr);
    #endif
            }
            else
            {
    
    #ifdef PARSE_LOOP_DEBUG
                Serial.printf("ran out of data at readidx = %d - exiting!\n", read_idx);
    #endif
                break;
            }
    
            //get read/write flag  1 = Read, 0 = Write, -1 = error
            BusDir = (BUSDIR)GetReadWriteFlag(valid_data, read_idx);
    
    #ifdef PARSE_LOOP_DEBUG
            Serial.printf("BusDir = %s\n", ((BusDir == BUSDIR::WRITE) ? "WRITE" : "READ"));
            //PrintNextFIFOBytes(valid_data, 20);
    #endif
    
        //get ACK/NAK flag
            ACKNAKFlag = GetACKNAKFlag(valid_data, read_idx);
            numbytes = GetDataBytes(valid_data, read_idx, databytes); //terminates on a START, but the start bytes are not consumed
    #ifdef PARSE_LOOP_DEBUG
            Serial.printf("Got %d bytes from GetDataBytes() --> ", numbytes);
            for (size_t i = 0; i < numbytes; i++)
            {
                Serial.printf(" %x ", databytes[i]);
            }
            Serial.printf("\n");
    
            //PrintNextFIFOBytes(cb_trans, 20);
    #endif
        //If the bus direction is WRITE, then extract
        //    A register address for read / write
        //    zero or more additional data bytes
            if (BusDir == BUSDIR::WRITE)
            {
                regAddr = databytes[0];
    #ifdef PARSE_LOOP_DEBUG
                Serial.printf("regAddr = %x, read_idx = %d\n", regAddr, read_idx);
    #endif
    
                //check for additional data
                if (numbytes > 1)
                {
    #ifdef PARSE_LOOP_DEBUG
                    Serial.printf("Additional data found!\n");
                    for (size_t i = 0; i < numbytes; i++)
                    {
                        Serial.printf("data[%d] = %x\n", i, databytes[i]);
                    }
    #endif
                    //1st byte is register addr, subsequent bytes are data
                    OutputFormattedSentence(BusDir, devAddr, regAddr, numbytes, databytes, 1);
                }
            }
            else  //all bytes are data
            {
    #ifdef PARSE_LOOP_DEBUG
                Serial.printf("In data block:  got %d bytes of data\n", numbytes);
                for (size_t i = 0; i < numbytes; i++)
                {
                    Serial.printf("data[%d] = %x\n", i, databytes[i]);
                }
    #endif
                OutputFormattedSentence(BusDir, devAddr, regAddr, numbytes, databytes, 0);
            }
    #ifdef PARSE_LOOP_DEBUG
            Serial.printf("At end of while (read_idx < numvalidbytes): read_idx = %d\n", read_idx);
    #endif
    
        }//while (read_idx < numvalidbytes)
        return numvalidbytes;
    }
    
    
    #pragma region Support Functions
    bool IsStart(byte* data, uint16_t& readidx)
    {
        bool result = false;
    
        //Serial.printf("IsStart[%d] = %x, IsStart[%d] = %x\n",
        //    readidx, data[readidx], readidx + 1, data[readidx + 1]);
    
        if (data[readidx] == 0xC && data[readidx + 1] == 0x4)
        {
            result = true;
            readidx += 2; //bump to next byte pair
        }
        return result;
    }
    
    bool IsStop(byte* data, uint16_t& readidx)
    {
        bool result = false;
    
        //Serial.printf("IsStop[%d] = %x, IsStop[%d] = %x\n",
            //readidx, data[readidx], readidx + 1, data[readidx + 1]);
    
        if (data[readidx] == 0x4 && data[readidx + 1] == 0xC)
        {
            result = true;
            readidx += 2; //bump to next byte pair
        }
        return result;
    }
    
    uint8_t Get7BitDeviceAddr(byte* data, uint16_t& readidx)
    {
        //Purpose: Construct a 7-bit address starting from dataidx
        //Inputs:
        //  data = pointer to valid data array
        //  readidx = starting index of 7-bit address sequence (MSB first)
        //Outputs:
        //  returns the address as an 8-bit value with the MSB = 0, or 0x0 if unsuccessful
        //  dataidx = pointer to next data entry
        //Plan:
        //  Step1: Convert a pair of data entries into a 0 or 1
        //  Step2: Add the appropriate value to an ongoing sum
        //  Step3: return the total.
        //Notes:
        //  A '0' is coded as a 0x0 followed by a 0x4
        //  A '1' is coded as a 0x8 followed by a 0xC
    
        uint8_t devAddr = 0x0; //failure return value
    
        //Serial.printf("Get7BitDeviceAddr: readidx = %d\n",readidx);
    
        //devAddr is exactly 7 bits long, so 8 bits with MSB = 0
        for (size_t i = 0; i < 7; i++)
        {
            if (data[readidx] == 0x0 && data[readidx + 1] == 0x4)
            {
                readidx += 2; //advance the pointer, but don't add to sum
            }
    
            else if (data[readidx] == 0x8 && data[readidx + 1] == 0xC)
            {
                //Serial.printf("Get7BitDeviceAddr: '1' found at i = %d, adding %x to devAddr to get %x\n",
                //    i, 1 << (7 - i), devAddr + (1 << (7-i)));
    
                readidx += 2; //advance the pointer
                devAddr += (1 << (7 - i)); //add 2^(7-i) to sum
            }
        }
    
        devAddr = devAddr >> 1; //divide result by 2 to get 7-bit addr from 8 bits
        return devAddr;
    }
    
    int Get8BitDataByte(byte* data, uint16_t& readidx)
    {
        //Purpose: Construct a 8-bit data byte starting from dataidx
        //Inputs:
        //  data = pointer to valid data array
        //  readidx = starting index of 8-bit data byte (MSB first)
        //Outputs:
        //  returns the address as an 8-bit value, or 0x0 if unsuccessful
        //  dataidx = pointer to next data entry
        //Plan:
        //  Step1: Convert a pair of data entries into a 0 or 1
        //  Step2: Add the appropriate value to an ongoing sum
        //  Step3: return the total.
        //Notes:
        //  A '0' is coded as a 0x0 followed by a 0x4
        //  A '1' is coded as a 0x8 followed by a 0xC
        //  12/29/19 - changed return val to int, so can return -1 when a 'short byte' is detected
    
        int dataval = 0x0; //failure return value
    
    #ifdef GET_8BIT_DATABYTE_DEBUG
        Serial.printf("Get8BitDataByte: data[%d] = %x, data[%d] = %x\n",
            readidx, data[readidx], readidx + 1, data[readidx + 1]);
    #endif
    
        //8 bits with MSB = 0
        int numbytes = 0;
        for (size_t i = 0; i < 8; i++)
        {
            if (data[readidx] == 0x0 && data[readidx + 1] == 0x4)
            {
                readidx += 2; //advance the pointer, but don't add to sum
                numbytes++;
            }
    
            else if (data[readidx] == 0x8 && data[readidx + 1] == 0xC)
            {
    #ifdef GET_8BIT_DATABYTE_DEBUG
                Serial.printf("Get8BitDataByte: '1' found at i = %d, adding %x to devAddr to get %x\n",
                    i, 1 << (7 - i), dataval + (1 << (7 - i)));
    #endif
                readidx += 2; //advance the pointer
                dataval += (1 << (7 - i)); //add 2^(8-i) to sum
                numbytes++;
            }
        }
    
    #ifdef GET_8BIT_DATABYTE_DEBUG
        Serial.printf("Get8BitDataByte: numbytes = %d\n", numbytes);
    #endif
        if (numbytes != 8)
        {
            dataval = -1; //error return value
        }
    
        return dataval;
    }
    
    int GetReadWriteFlag(byte* data, uint16_t& readidx)
    {
        //Purpose: decode R/W byte pair
        //Inputs:
        //  data = pointer to valid data array
        //  readidx = index into data to start of R/W byte pair
        //Outputs:
        //  readidx = if successful, points to next byte pair in data
        //  returns 1 for Read (0x8/0xC), 0 for Write (0x0/0x4), -1 for failure
        //Notes:
        //  
    
        //Serial.printf("GetReadWriteFlag: readidx = %d, data[readidx] = %x, data[readidx+1]= %x\n",
        //    readidx, data[readidx], data[readidx + 1]);
        int result = 0;
        if (data[readidx] == 0x8 && data[readidx + 1] == 0xC)
        {
            result = 1; //read detected
            readidx += 2; //point to next byte pair
        }
    
        else if (data[readidx] == 0x0 && data[readidx + 1] == 0x4)
        {
            result = 0; //write detected
            readidx += 2; //point to next byte pair
        }
        else
        {
            result = -1; //failed to detect read or write
        }
    
        return result;
    }
    
    int GetACKNAKFlag(byte* data, uint16_t& readidx)
    {
        //Purpose: decode ACK/NAK byte pair
        //Inputs:
        //  data = pointer to valid data array
        //  readidx = index into data to start of ACK/NAK byte pair
        //Outputs:
        //  readidx = if successful, points to next byte pair in data
        //  returns 1 for NAK (0x8/0xC), 0 for ACK (0x0/0x4), -1 for failure
        //Notes:
        //  
    
        //Serial.printf("GetACKNAKFlag: readidx = %d, data[readidx] = %x, data[readidx+1]= %x\n",
        //    readidx, data[readidx], data[readidx + 1]);
        int result = 0;
        if (data[readidx] == 0x8 && data[readidx + 1] == 0xC)
        {
            result = 1; //NAK detected
            readidx += 2; //point to next byte pair
        }
    
        else if (data[readidx] == 0x0 && data[readidx + 1] == 0x4)
        {
            result = 0; //ACK detected
            readidx += 2; //point to next byte pair
        }
        else
        {
            result = -1; //failed to detect ACK or NAK
        }
    
        return result;
    }
    
    int GetDataBytes(uint8_t* data, uint16_t& readidx, uint8_t* databytes)
    {
        //Notes:
        //  01/01/2020: removed databyteidx from sig - always starts at zero
    
        uint16_t numbytes = 0;
        uint16_t databyte_idx = 0;
    
        bool StartFlag = false;
        bool StopFlag = false;
    
        do
        {
            int dataval = Get8BitDataByte(data, readidx);
    
            //watch out for 'short byte' reads
            if (dataval >= 0)
            {
                uint8_t databyte = (uint8_t)dataval;
                databytes[databyte_idx] = databyte;
                databyte_idx++;
                numbytes++;
            }
    
            ACKNAKFlag = GetACKNAKFlag(data, readidx);
            StartFlag = IsStart(data, readidx);
            StopFlag = IsStop(data, readidx);
    
    #ifdef PARSE_LOOP_DEBUG
            Serial.printf("IsStart returned %d, IsStop returned %d, dataidx = %d\n",
                StartFlag, StopFlag, readidx);
    #endif
    
        } while (!StartFlag && !StopFlag && readidx < numvalidbytes);
    
    
        readidx -= 2;//back readidx up so loop top is positioned correctly.
    
        return numbytes;
    }
    
    void OutputFormattedSentence(int RW, uint8_t dev, uint8_t reg, uint8_t numbytes, uint8_t* bytearray, uint16_t startidx)
    {
        Serial.printf("%lu I2C(%x) %s %d bytes %s %x... ",
            millis(), dev, (RW == 0 ? "writing" : "reading"),  numbytes - startidx, (RW == 0 ? "to" : "from"), reg);
        for (size_t i = startidx; i < numbytes; i++)
        {
            Serial.printf("%x ", bytearray[i]);
        }
    
    #ifdef MPU6050_SPECIFIC
    
    
        //01/18/20 experiment to decode 28-byte packet into yaw value
        if (numbytes == 28)
        {
            dmpGetQuaternion(&q, bytearray);
            dmpGetGravity(&gravity, &q);
            dmpGetYawPitchRoll(ypr, &q, &gravity);
    
            //compute the yaw value
            global_yawval = ypr[0] * 180 / M_PI;
            Serial.printf("yawval = %3.2f\n", global_yawval);
        }
        else
        {
            Serial.printf(". Done\n");
        }
    #endif // MPU6050_SPECIFIC
    
    
    
    }
    
    uint16_t RemoveInvalidBytes(uint8_t* rawdata, uint8_t* validdata)
    {
        uint16_t numvalid = 0;
        uint16_t valididx = 0;
    
        //Serial.printf("raw data array contains %d bytes\n", write_idx + 1);
        //PrintNextArrayBytes(raw_data, 0, 20);
    
        //OK, now go back through the array, excising invalid sequences
        for (uint16_t rawidx = 0; rawidx < write_idx;/*rawidx incremented internally*/)
        {
            uint8_t firstByte = raw_data[rawidx]; //get the first byte
            uint8_t secondByte = raw_data[rawidx + 1]; //get the next byte
            bool validpair =
                (
                (firstByte == 0xC && secondByte == 0x4) //START or RESTART
                    || (firstByte == 0x4 && secondByte == 0xC) //STOP
                    || (firstByte == 0x0 && secondByte == 0x4) //0 OR ACK
                    || (firstByte == 0x8 && secondByte == 0xC) //1 or NAK
                    );
    
            //Serial.printf("rawidx %d: Considering %x and %x: validity = %d\n",
                //rawidx, firstByte, secondByte, validpair);
            if (validpair)
            {
                //save valid bytes to valid_bytes array
                validdata[valididx] = firstByte;
                validdata[valididx + 1] = secondByte;
                numvalid += 2;
                //Serial.printf("Added %x & %x at idx = %d & %d\n", firstByte, secondByte, valididx, valididx + 1);
                //PrintNextArrayBytes(validdata,0,numvalid);
                rawidx += 2;
                valididx += 2;
            }
            else
            {
                rawidx++; //on invalid, just go to next byte
            }
        }
    
        return numvalid;
    }
    #pragma endregion Support Functions
    
    #ifdef MPU6050_SPECIFIC
    
    #pragma region YAW_COMPUTATIONS
    //01/18/2020: I copied these functions from MPU6050_6Axis_MotionApps_V6_12.h and
    //  modified them to be called directly instead of from an 'mpu' object
        
    uint8_t dmpGetQuaternion(int16_t* data, const uint8_t* packet) 
    {
        // TODO: accommodate different arrangements of sent data (ONLY default supported now)
        if (packet != 0) 
        {
            data[0] = ((packet[0] << 8) | packet[1]);
            data[1] = ((packet[4] << 8) | packet[5]);
            data[2] = ((packet[8] << 8) | packet[9]);
            data[3] = ((packet[12] << 8) | packet[13]);
        }
        return 0;
    }
    
    uint8_t dmpGetQuaternion(Quaternion* q, const uint8_t* packet) 
    {
        // TODO: accommodate different arrangements of sent data (ONLY default supported now)
        int16_t qI[4]{ 0,0,0,0 };
        uint8_t status = dmpGetQuaternion(qI, packet);
        if (status == 0) {
            q->w = (float)qI[0] / 16384.0f;
            q->x = (float)qI[1] / 16384.0f;
            q->y = (float)qI[2] / 16384.0f;
            q->z = (float)qI[3] / 16384.0f;
            return 0;
        }
        return status; // int16 return value, indicates error if this line is reached
    }
    
    uint8_t dmpGetYawPitchRoll(float* data, Quaternion* q, VectorFloat* gravity) {
        // yaw: (about Z axis)
        data[0] = atan2(2 * q->x * q->y - 2 * q->w * q->z, 2 * q->w * q->w + 2 * q->x * q->x - 1);
        // pitch: (nose up/down, about Y axis)
        data[1] = atan2(gravity->x, sqrt(gravity->y * gravity->y + gravity->z * gravity->z));
        // roll: (tilt left/right, about X axis)
        data[2] = atan2(gravity->y, gravity->z);
        if (gravity->z < 0) {
            if (data[1] > 0) {
                data[1] = PI - data[1];
            }
            else {
                data[1] = -PI - data[1];
            }
        }
        return 0;
    }
    
    
    uint8_t dmpGetGravity(VectorFloat* v, Quaternion* q) {
        v->x = 2 * (q->x * q->z - q->w * q->y);
        v->y = 2 * (q->w * q->x + q->y * q->z);
        v->z = q->w * q->w - q->x * q->x - q->y * q->y + q->z * q->z;
        return 0;
    }
    #pragma endregion YAW_COMPUTATIONS
    #endif //MPU6050_SPECIFIC
    All of the MPU6050 code *except* the '#include #include "helper_3dmath.h" ' has been #ifdef'd out. However, if I then UNcomment the #ifdef surrounding that one remaining MPU6050-specific line, then the code no longer compiles, and instead blows a bunch of errors, as shown below in the verbose compile output.

    Code:
    Compiling debug version of 'Teensy_I2C_Sniffer_V11' for 'Teensy 3.2 / 3.1'
    Build Folder: "file:///C:/Users/Frank/AppData/Local/Temp/VMBuilds/Teensy_I2C_Sniffer_V11/teensy31/Debug"
    Additional Defines: VM_DEBUGGER_TYPE_HARDWARESERIAL 0;VM_DEBUGGER_TYPE_SOFTWARESERIAL 1;VM_DEBUGGER_TYPE_FASTSERIAL 2;VM_DEBUGGER_TYPE_USB 3;VM_DEBUGGER_TYPE_TEENSY 4;VM_DEBUGGER_TYPE_UART 5;VM_DEBUGGER_TYPE_USART 6;VM_DEBUGGER_TYPE_USBSERIAL 7;VM_DEBUGGER_TYPE_TTYUART 8;VM_DEBUGGER_TYPE_NET_CONSOLE 9;VM_DEBUGGER_TYPE_Uart 10;VM_DEBUGGER_TYPE_COSA 11;VM_DEBUGGER_TYPE_CDCSerialClass 12;VM_DEBUGGER_TYPE_HARDWARESERIAL1 13;VM_DEBUGGER_TYPE_HARDWARESERIAL2 14;VM_DEBUGGER_TYPE_HARDWARESERIAL3 15;VM_DEBUGGER_TYPE_NET_UDP 16;VM_DEBUGGER_TYPE_USBAPI 17;VM_DEBUGGER_TYPE_SERIALUSB 18;VM_DEBUGGER_TYPE_MS430_SERIAL_ 19;VM_DEBUGGER_TYPE_NO_SERIAL 20;VM_DEBUGGER_TYPE_GENERIC_OBJECT 21;VM_DEBUG_ENABLE 1;VM_DEBUG;VM_DEBUG_BANDWIDTH_THROTTLE_MS 50;VM_DEBUGGER_SOFT_TRANSPORT Serial;VM_DEBUGGER_SOFT_TRANSPORT_WRITER Serial;VM_DEBUGGER_TYPE VM_DEBUGGER_TYPE_GENERIC_OBJECT;VM_DEBUG_BREAKPAUSE;
    Architecture Tools: "file:///C:/Program%20Files%20(x86)/Arduino/hardware/tools/"
    Api: 1.1911.23-1
    Sketch Book: "file:///C:/Users/Frank/Documents/Arduino"
    Sketch Include Paths
    Core Include Paths
    Include Path "file:///C:/Program%20Files%20(x86)/Arduino/hardware/teensy/avr/cores/teensy3"
     
    Deep search for libraries ...
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\Teensy_I2C_Sniffer_V11.cpp" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\Teensy_I2C_Sniffer_V11.cpp" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\Teensy_I2C_Sniffer_V11.cpp" -o "nul"
    Using previous search results: C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne\TimerOne.cpp
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\utility" "c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\VM_DBG.cpp" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\utility" "c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\VM_mem_check.c" -o "nul"
    "C:\Program Files (x86)\Arduino\hardware\teensy\..\tools\arm\bin\arm-none-eabi-g++" -E -CC -x c++ -w  -g -Wall -ffunction-sections -fdata-sections -nostdlib -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0  -Wno-unknown-pragmas   -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\utility" "c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\VM_mem_check_sam.cpp" -o "nul"
    recipe.hooks.sketch.prebuild.1.pattern
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/precompile_helper" "C:\Program Files (x86)\Arduino\hardware\teensy\avr/cores/teensy3" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug" "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -x c++-header -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Program Files (x86)\Arduino\hardware\teensy\avr/cores/teensy3" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/pch/Arduino.h" -o "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/pch/Arduino.h.gch"
     
    Using previously compiled file: C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\pch\Arduino.h.gch
    Building core ...
     
    Building libraries ...
    
    Using library TimerOne version 1.1 in folder "file:///C:/Program%20Files%20(x86)/Arduino/hardware/teensy/avr/libraries/TimerOne"
      Using previously compiled file: C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\TimerOne\TimerOne.cpp.o
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant  -Wno-unknown-pragmas -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0 -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/pch" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" "c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\VM_DBG.cpp" -o "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\VM_DBG\VM_DBG.cpp.o"
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant  -Wno-unknown-pragmas -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0 -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/pch" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" "c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG\VM_mem_check_sam.cpp" -o "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\VM_DBG\VM_mem_check_sam.cpp.o"
     
    Building project code ...
    "C:\Program Files (x86)\Arduino\hardware\teensy/../tools/arm/bin/arm-none-eabi-g++" -c -O2 -g -Wall -ffunction-sections -fdata-sections -nostdlib -MMD -fno-exceptions -fpermissive -felide-constructors -std=gnu++14 -Wno-error=narrowing -fno-rtti -mthumb -mcpu=cortex-m4 -fsingle-precision-constant  -Wno-unknown-pragmas -DVM_DEBUG_BREAKPAUSE -DVM_DEBUGGER_TYPE=VM_DEBUGGER_TYPE_GENERIC_OBJECT -DVM_DEBUGGER_SOFT_TRANSPORT_WRITER=Serial -DVM_DEBUGGER_SOFT_TRANSPORT=Serial -DVM_DEBUG_BANDWIDTH_THROTTLE_MS=50 -DVM_DEBUG -DVM_DEBUG_ENABLE=1 -DVM_DEBUGGER_TYPE_GENERIC_OBJECT=21 -DVM_DEBUGGER_TYPE_NO_SERIAL=20 -DVM_DEBUGGER_TYPE_MS430_SERIAL_=19 -DVM_DEBUGGER_TYPE_SERIALUSB=18 -DVM_DEBUGGER_TYPE_USBAPI=17 -DVM_DEBUGGER_TYPE_NET_UDP=16 -DVM_DEBUGGER_TYPE_HARDWARESERIAL3=15 -DVM_DEBUGGER_TYPE_HARDWARESERIAL2=14 -DVM_DEBUGGER_TYPE_HARDWARESERIAL1=13 -DVM_DEBUGGER_TYPE_CDCSerialClass=12 -DVM_DEBUGGER_TYPE_COSA=11 -DVM_DEBUGGER_TYPE_Uart=10 -DVM_DEBUGGER_TYPE_NET_CONSOLE=9 -DVM_DEBUGGER_TYPE_TTYUART=8 -DVM_DEBUGGER_TYPE_USBSERIAL=7 -DVM_DEBUGGER_TYPE_USART=6 -DVM_DEBUGGER_TYPE_UART=5 -DVM_DEBUGGER_TYPE_TEENSY=4 -DVM_DEBUGGER_TYPE_USB=3 -DVM_DEBUGGER_TYPE_FASTSERIAL=2 -DVM_DEBUGGER_TYPE_SOFTWARESERIAL=1 -DVM_DEBUGGER_TYPE_HARDWARESERIAL=0 -D__MK20DX256__ -DTEENSYDUINO=148 -DARDUINO=108010 -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH "-IC:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug/pch" -I"C:\Users\Frank\Documents\Arduino\Teensy_I2C_Sniffer_V11" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3" -I"C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\TimerOne" -I"c:\program files (x86)\microsoft visual studio\2019\community\common7\ide\extensions\t4fb1en2.4xb\Micro Platforms\default\debuggers\VM_DBG" "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\Teensy_I2C_Sniffer_V11.cpp" -o "C:\Users\Frank\AppData\Local\Temp\VMBuilds\Teensy_I2C_Sniffer_V11\teensy31\Debug\Teensy_I2C_Sniffer_V11.cpp.o"
     
    Teensy_I2C_Sniffer_V11.ino: 63:26: error: 'uint8_t dmpGetQuaternion' redeclared as different kind of symbol
       elapsedMillis mSecSinceLastWaitingPrint
    Teensy_I2C_Sniffer_V11.ino:62: note  previous declaration uint8_t dmpGetQuaternion(int16_t*, const uint8_t*)
       uint8_t killbuff[2]; \\used to consume start\stop bytes
     
    Teensy_I2C_Sniffer_V11.ino: 63:26: error: 'Quaternion' was not declared in this scope
    Error compiling project sources
       elapsedMillis mSecSinceLastWaitingPrint
     
    Teensy_I2C_Sniffer_V11.ino: 63:38: error: 'q' was not declared in this scope
       elapsedMillis mSecSinceLastWaitingPrint
     
    Teensy_I2C_Sniffer_V11.ino: 63:41: error: expected primary-expression before 'const
     
    Teensy_I2C_Sniffer_V11.ino: 64:41: error: 'Quaternion' has not been declared
     
    Teensy_I2C_Sniffer_V11.ino: 64:56: error: 'VectorFloat' has not been declared
     
    Teensy_I2C_Sniffer_V11.ino: 65:23: error: 'VectorFloat' was not declared in this scope
       uint16_t numvalidbytes = 0; \\number of valid bytes in this burst
     
    Teensy_I2C_Sniffer_V11.ino: 65:36: error: 'v' was not declared in this scope
       uint16_t numvalidbytes = 0; \\number of valid bytes in this burst
     
    Teensy_I2C_Sniffer_V11.ino: 65:39: error: 'Quaternion' was not declared in this scope
       uint16_t numvalidbytes = 0; \\number of valid bytes in this burst
     
    Teensy_I2C_Sniffer_V11.ino: 65:51: error: 'q' was not declared in this scope
       uint16_t numvalidbytes = 0; \\number of valid bytes in this burst
    Teensy_I2C_Sniffer_V11.ino: 65:52: warning: expression list treated as compound expression in initializer [-fpermissive]
       uint16_t numvalidbytes = 0; \\number of valid bytes in this burst
    Debug build failed for project 'Teensy_I2C_Sniffer_V11'
    Anyone have any idea why this is happening?

    TIA,

    Frank

  5. #5
    Never mind. I found this post that explains the problem. Apparently the Arduino pre-processor 'sees' the #include line before it 'sees' the #ifdef/#endif block - bummer.

    So, to generalize the code I'll use #define MPU6050_SPECIFIC and #ifdef/#endif blocks to exclude all the necessary inline code blocks, but the user will have to manually comment out the #include "helper_3dmath.h" line to complete the task. I'll try and get this up on my Github site soon.

    Frank

  6. #6
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,955
    For whatever it is worth I was able to compile it for Arduino 3.2 after I uncommented the #if/#endif around the include of the math library at the top.

    Arduino does give me lots of warnings like: bar:379: warning: ignoring #pragma region Support

    Note it will not compile for T4 as it is using T3.x specific register names...

  7. #7
    All,

    I have updated the Teensy sniffer on my Github account to allow its use with any I2C slave device via a #ifdef MPU6050_SPECIFIC pre-processor switch. By default this switch is disabled, so the code will operate with any I2C slave device.

    To specialize it for the MPU6050 simply uncomment the line

    //#define MPU6050_SPECIFIC

    and recompile.

    The 'ignoring unknown pragma' warning can be silenced by adding '-Wno-unknown-pragmas' to the 'extra cpp flags'. If you are using Visual Studio and Visual Micro this is accomplished with vMicro->Compiler->Advanced. I like using this feature to easily collapse large sections of code.

    I would entertain a pull request to allow the code to be used on a T4, especially if someone wants to send me one for testing ;-)))

    Frank

  8. #8
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,369
    Running it against i2c SSD1306 OLED at 100 MHz and it looks to be catching data - mostly works if bumped to 400 MHz - but that will not sample at right rate and enough at 1 us - and it hangs after some cycles … running on a T_3.6 at 180 or 256 MHz.

    Nice work. Would be good to have forum and blog links on the github.

  9. #9
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,955
    I did a quick and dirty update to build on T4... I may do a PR, but I did a Arduino code format on my version and it

    It is up at: https://github.com/KurtE/Teensy_I2C_Sniffer_V11/tree/T4

    I did it pretty quick and dirty:
    Code:
    FASTRUN void capture_data()
    //void capture_data()
    {
      last_portb = current_portb;
    #if defined(__IMXRT1062__)
      current_portb = (digitalReadFast(SCL_PIN) << 2) | (digitalReadFast(SDA_PIN) << 3);
    #else
      current_portb = GPIOB_PDIR & 12; //reads state of SDA (18) & SCL (19) at same time
    #endif

  10. #10
    defragster,

    Good suggestion. I edited the ReadMe to include the links

  11. #11
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,369
    Quote Originally Posted by KurtE View Post
    I did a quick and dirty update to build on T4... I may do a PR, but I did a Arduino code format on my version and it
    ...
    I did it pretty quick and dirty:
    Code:
    FASTRUN void capture_data()
    //void capture_data()
    {
      last_portb = current_portb;
    #if defined(__IMXRT1062__)
      current_portb = (digitalReadFast(SCL_PIN) << 2) | (digitalReadFast(SDA_PIN) << 3);
    #else
      current_portb = GPIOB_PDIR & 12; //reads state of SDA (18) & SCL (19) at same time
    #endif
    Put this in copy here and on T4 versus T_3.6 it is missing many of the i2c address values as '3c' to the SSD1306. Showing as : 28,6f,51,3b,24,a,73,3f,0,other. There were some few odd #'s using T_3.6 - but they were rare and usually hit the same non-3c value.

  12. #12
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,369
    Is this somehow right - with the bits in the right order and location?

    Code:
        /*
        #define CORE_PIN18_PORTREG  GPIO6_DR
        #define CORE_PIN19_PORTREG  GPIO6_DR
    
        #define CORE_PIN18_BIT      17  // SDA
        #define CORE_PIN19_BIT      16  // SCL
    
                    } else if (pin == 18) {
                        CORE_PIN18_PORTSET = CORE_PIN18_BITMASK;
                    } else if (pin == 19) {
                        CORE_PIN19_PORTSET = CORE_PIN19_BITMASK;
        */
    
    #if defined(__IMXRT1062__)
    #define IMXRT_GPIO6_DIRECT  (*(volatile uint32_t *)0x42000000)
    #define IO_SCL_SDA ((IMXRT_GPIO6_DIRECT & (CORE_PIN18_BITMASK | CORE_PIN19_BITMASK)) >> 14)
        current_portb = IO_SCL_SDA;
    Majority showing "I2C(3c)":
    Code:
    157116 I2C(3c) writing 31 bytes to 40... aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa . Done
    157116 I2C(3c) writing 31 bytes to 40... aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa . Done
    157116 I2C(3c) writing 31 bytes to 40... aa aa aa aa aa aa aa aa aa aa aa aa aa ab a8 af a0 bf 80 ff 0 ff 0 ff 0 ff 0 ff ff 80 bf . Done
    157116 I2C(3c) writing 11 bytes to 40... a0 af a8 ab aa aa aa aa aa aa aa . Done
    157116: processed = 2048 elements in 0 mSec
    <edit> : hacked from Reading-multiple-GPIO-pins-on-the-Teensy-4-0-"atomically"

    Should be written to use : #define IMXRT_GPIO6 (*(IMXRT_REGISTER32_t *)0x42000000)
    Last edited by defragster; Yesterday at 08:11 PM.

  13. #13
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    5,955
    Hi @defragster - I should warn that I have not given this a ton of thought. I was simply trying to emulate getting the two values for SCL/SDA into the same bits...

    A safer way maybe not to assume 0 and 1... So I have also now have:
    Code:
      current_portb = (digitalReadFast(SCL_PIN)? 4 : 0) | (digitalReadFast(SDA_PIN)? 8 : 0);
    This is updating the SSD1306 that has different address than Adafruit default:
    Code:
    18681: processed = 2048 elements in 0 mSec
    
    18685 I2C(38) writing 30 bytes to 80... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 c 1d 3d 7d d9 e6 ef 2d ef ef ef c9 . Done
    18685 I2C(38) writing 30 bytes to 80... 30 30 30 0 0 0 0 0 0 8 8 0 0 0 0 0 8 10 30 0 0 0 0 0 0 0 0 0 0 0 . Done
    18685 I2C(3c) writing 13 bytes to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    18685: processed = 2048 elements in 0 mSec
    
    18688 I2C(3c) writing 30 bytes to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 c c 1d 3d 7d dd bb . Done
    18688 I2C(38) writing 30 bytes to 80... fe bd fb b1 e0 c1 80 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    18688 I2C(3c) writing 31 bytes to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    18688 I2C(3c) writing 12 bytes to 0... 0 0 0 0 80 80 80 80 0 0 c0 e1 . Done
    18688: processed = 2048 elements in 0 mSec
    
    18692 I2C(3c) writing 30 bytes to 40... 7 3 3 0 2 6 e 1e 1e 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    18692 I2C(38) writing 31 bytes to 80... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    18692 I2C(3c) writing 30 bytes to 40... 0 0 0 0 0 0 0 0 0 1 8b b7 ce a7 e7 cf ee 9f 59 81 3 1 6 0 0 0 0 0 0 0 . Done
    18692 I2C(3c) writing 13 bytes to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    18692: processed = 2048 elements in 0 mSec
    Speed wise, I did a quick and dirty and did a digitalWriteFast(5, HIGH) at start of ISR and LOW and end. The last line in Logic analyzer trace shows this line.
    Top two lines shows LA analyzer of I2C communications. and other lines were existing debug IO pin outputs 2-4

    Click image for larger version. 

Name:	screenshot.jpg 
Views:	1 
Size:	68.4 KB 
ID:	18812

  14. #14
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,369
    Using the port read in p#12 with an altered test SSD1306 code not slamming the display I get:
    Code:
    494522 I2C(3c) Wr 5 B to 0... 22 0 ff 21 0 . Done
    494522 I2C(3c) Wr 1 B to 0... 7f . Done
    494522 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 c0 e0 e0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    494522 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    494522 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    494522 I2C(3c) Wr 1 B to 40... 0 . Done
    494522: processed = 2048 elements in 0 mSec
    
    494535 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 6 e 1e be ec 6c bf f3 bf 6f ef 7c 3c 38 18 18 0 0 0 0 0 0 . Done
    494535 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    494535 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    494535 I2C(3c) Wr 11 B to 40... 0 0 0 0 0 0 0 0 0 0 0 . Done
    494535: processed = 2048 elements in 0 mSec
    
    494547 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 c f f 7 7 3 3 7 f 1f 1e 0 0 0 0 0 0 . Done
    494547 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    494547 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    494547 I2C(3c) Wr 11 B to 40... 0 0 0 0 0 0 0 0 0 0 0 . Done
    Using KurtE updated p#13 code I get a cleaner looking:
    Code:
    4350 I2C(3c) Wr 5 B to 0... 22 0 ff 21 0 . Done
    4350 I2C(3c) Wr 1 B to 0... 7f . Done
    4350 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 c0 e0 e0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    4350 I2C(3c) Wr 27 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    4350: processed = 2048 elements in 0 mSec
    
    4363 I2C(3c) Wr 31 B to 40... 0 0 0 0 0 0 0 0 0 6 e 1e be ec 6c bf f3 bf 6f ef 7c 3c 38 18 18 0 0 0 0 0 0 . Done
    4363 I2C(3c) Wr 16 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    4363 I2C(3c) Wr 3 B to 40... 0 0 0 . Done
    4363 I2C(3c) Wr 11 B to 40... 0 0 0 0 0 0 0 0 0 0 0 . Done
    4363: processed = 2048 elements in 0 mSec
    
    4375 I2C(3c) Wr 28 B to 40... 0 0 0 0 0 0 0 0 0 0 0 0 0 0 c f f 7 7 3 3 7 f 1f 1e 0 0 0 . Done
    4375 I2C(3c) Wr 7 B to 40... 0 0 0 0 0 0 0 . Done
    4375 I2C(3c) Wr 11 B to 40... 0 0 0 0 0 0 0 0 0 0 0 . Done
    The PORT way will be faster and more Atomic on the bits - the DATA looks to be sniffed the same - not sure why it triggers the SPARE ZERO chars in the output?

    You can see I truncated the "I2C(3c) Wr 11 B to 40" so it better fits the screen.

    I put waits in the SSD1306 test code as well to still the screen - so I added to the 'waiting for data delay' with : const int WAITING_PRINT_INTERVAL_MSEC = 1000;

  15. #15
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    4,500
    For the fun of it I hooked it up a T4 running my FRAM test sketch and got the following which shows reading and writing to the FRAM. This is after the change to the Wire buffer lenght.

    Code:
    1801: Waiting for Data...
    2001: Waiting for Data...
    2201: Waiting for Data...
    2236 I2C(7c) reading 3 bytes from a0... 0 a5 10 . Done
    2236 I2C(50) writing 53 bytes to 0... 25 1 0 0 0 8f c2 ad 3f 2f cb 4 0 8e 0 0 0 50 54 68 65 20 51 75 69 63 6b 20 42 72 6f 77 6e 20 46 6f 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    2236 I2C(50) writing 1 bytes to 0... 25 . Done
    2236 I2C(50) reading 47 bytes from 0... 1 0 0 0 8f c2 ad 3f 2f cb 4 0 8e 0 0 0 50 54 68 65 20 51 75 69 63 6b 20 42 72 6f 77 6e 20 46 6f 78 0 0 0 0 0 0 0 0 0 0 0 . Done
    2236: processed = 2048 elements in 1 mSec

  16. #16
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    10,369
    Quote Originally Posted by mjs513 View Post
    For the fun of it I hooked it up a T4 running my FRAM test sketch and got the following which shows reading and writing to the FRAM. This is after the change to the Wire buffer lenght.

    Code:
    1801: Waiting for Data...
    2001: Waiting for Data...
    2201: Waiting for Data...
    2236 I2C(7c) reading 3 bytes from a0... 0 a5 10 . Done
    2236 I2C(50) writing 53 bytes to 0... 25 1 0 0 0 8f c2 ad 3f 2f cb 4 0 8e 0 0 0 50 54 68 65 20 51 75 69 63 6b 20 42 72 6f 77 6e 20 46 6f 78 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 . Done
    2236 I2C(50) writing 1 bytes to 0... 25 . Done
    2236 I2C(50) reading 47 bytes from 0... 1 0 0 0 8f c2 ad 3f 2f cb 4 0 8e 0 0 0 50 54 68 65 20 51 75 69 63 6b 20 42 72 6f 77 6e 20 46 6f 78 0 0 0 0 0 0 0 0 0 0 0 . Done
    2236: processed = 2048 elements in 1 mSec
    Mike - that is running sniffer on T4? If so using which version of the SCL/SDA read p#12 or p#13?

    For 'text' transfer devices it might be handy to have the typical HEX/ASCII table dump for printable chars: 65 65 65 13 09 66 66 66 ... :: A A A . . B B B …

Posting Permissions

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