Kenneth Dunlop / Mbed 2 deprecated Ken_CAN_test

Dependencies:   mbed

Revision:
11:abd3df435a2b
Parent:
10:3e15baff40e7
Child:
12:e950feba910d
--- a/Ken_CAN_test.cpp	Tue Jun 28 13:27:11 2022 +0000
+++ b/Ken_CAN_test.cpp	Wed Jul 06 11:19:51 2022 +0000
@@ -65,6 +65,9 @@
 int unexpectedCANstreak = 0;
 int unexpectedCANstreakstartid = 0;
 int failsthistest = 0;
+int failsstreak = 0;
+int failsstreakstart = 0;
+int reportfailsindividually = 0;
 int noreplyfailsthistest = 0;
 int noreplystreak = 0;
 int noreplystreakstartid = 0;
@@ -72,22 +75,33 @@
 int mismatchfailsthistest = 0;
 int matchesthistest = 0;
 int addnewlinetonextmessage = 0;
-int checklaterbytes = 0;
+int checklaterbytes = 1;
 int aspamisgoing = 0;
 int CANpassthrough = 1;
 int speedspamison = 0;
 int messagesincount = 0;
+int messageinisneeded = 0;
+
+int idwasfound = 0;
+int columnidwasfound = 0;
 
 int mbedCANbusspeed = 500 * 1000;
 int CANGatewayCANbusspeed = 500 * 1000;
 int listen = 1;
+int testwasaborted = 0;
+
+int customentry = 0;
+int normalkeypresses = 1;
+string customentrystring = "";
+int hextotal = 0;
 
 //Array of IDs to translate can be overwritten with the 'copyarray'.
 //It's arranged in columns of IDs that are translated to the ID in the next column.
 //NOTE: Array must be a large enough size to contain all ID translations.
-int idsarray[2][8] = {};
+int idsarray[2][8][10] = {};
 int arrayx = 2;
 int arrayy = 8;
+int arrayz = 10;
 
 //A function to easily get the total of seconds a spam has taken
 int getspamsecondstotal(void)
@@ -115,6 +129,10 @@
     //pc.printf("\r\nSent %d messages for %d ticks (%d seconds) at %d ticks per second. Messages per second is %d.\r\n", spamcount, spamtickstotal, spamsecondstotal, CLOCKS_PER_SEC, spamspersecond); //Old version of the message
     if (speedspamison == 0)
         {
+        if (aspamisgoing == 1)
+            {
+            pc.printf("\n");
+            }
         pc.printf("\rSent %d messages over %d seconds. Messages per second is %d.\r\n", spamcount, spamsecondstotal, spamspersecond);
         }
     return(spamsecondstotal, spamspersecond);
@@ -136,10 +154,19 @@
     }
 
 //A function to clear all test-related variables
+void resetCANbuses()//A quick method to reset both CAN buses conveniently
+    {
+    CanBus.reset(); // Clear any bus errors. Will this stop the 'cached' CAN sticking around?
+    CanBus2.reset(); // Clear any bus errors. Will this stop the 'cached' CAN sticking around?
+    }
+
 void resettest(void)
     {
     //pc.printf("Resetting test.\r\n");
+    listen = 1;
     failsthistest = 0;
+    failsstreak = 0;
+    failsstreakstart = 0;
     spamcount = 0;
     noreplyfailsthistest = 0;
     goodnoreplies = 0;
@@ -156,6 +183,7 @@
     unexpectedCANstreak = 0;
     unexpectedCANstreakstartid = 0;
     messagesincount = 0;
+    testwasaborted = 0;
     }
 
 //A function to add a carriage return in the output if the system has been writing out the CAN messages it sends.
@@ -177,21 +205,32 @@
 //A function to end a test and report on findings.
 void endtest()
     {
+    listen = 0;
     expectationresolved = 1;
-    if (failsthistest == 0)
+    if (testwasaborted == 1)
         {
-        pc.printf("\033[1;32mTest passed.\r\n");
-        pc.printf("\033[1;32m%d IDs sent out. ", spamcount);
-        pc.printf("\033[1;32m%d failures found.\r\n", failsthistest);
+        pc.printf("\033[1;35mTest was aborted, results invalid.\033[0m\r\n");
+        pc.printf("\033[1;35m%d IDs sent out. %d failures found so far.\033[0m\r\n", spamcount, failsthistest);
         if (CANpassthrough == 0)
             {
-            pc.printf("%d expected non-replies found. ", goodnoreplies);
+            pc.printf("\033[1;35m%d expected non-replies found so far. \033[0m", goodnoreplies);
             }
-        pc.printf("%d CAN matches found.\033[0m\r\n", matchesthistest);
+        pc.printf("\033[1;35m%d CAN matches found so far.\033[0m\r\n", matchesthistest);
         }
-    if (failsthistest > 0)
+    if (failsthistest == 0 and testwasaborted == 0)
         {
-        pc.printf("\033[1;31mTest failed.\r\n%d failures found.\r\n", failsthistest);
+        pc.printf("\033[1;32mTest passed.\033[0m\r\n");
+        pc.printf("\033[1;32m%d IDs sent out. \033[0m", spamcount);
+        pc.printf("\033[1;32m%d failures found.\033[0m\r\n", failsthistest);
+        if (CANpassthrough == 0)
+            {
+            pc.printf("\033[1;32m%d expected non-replies found. \033[0m", goodnoreplies);
+            }
+        pc.printf("\033[1;32m%d CAN matches found.\033[0m\r\n", matchesthistest);
+        }
+    if (failsthistest > 0 and testwasaborted == 0)
+        {
+        pc.printf("\033[1;31mTest failed.\r\n%d failures found.\033[0m\r\n", failsthistest);
         pc.printf("\033[1;31m%d mismatch failures, %d 'no reply' failures, %d unexpected CAN messages.\033[0m\r\n", mismatchfailsthistest, noreplyfailsthistest, unexpectedCANfails);
         if (goodnoreplies > 0)
             {
@@ -201,6 +240,22 @@
     //addnewlineifneeded();
     pc.printf("-------------------------------------\r\n");
     failsthistest = 0;
+    normalkeypresses = 1;
+    }
+
+//'End ID spam test' function so you can end it by reaching 2048 IDs or pressing 'Esc' while it's running
+void endidspamtest()
+    {
+    spamendtime = clock();
+    getspamsecondstotal();//Process the spam information
+    idspamon = 0;
+    aspamisgoing = 0;
+    normalkeypresses = 0;
+    addnewlinetonextmessage = 1;
+    //addnewlineifneeded();
+    //pc.printf("Ending ID spam sequence. %d IDs checked total.\r\n", idscheckedcount);
+    idlistincrementer = 0;
+    endtest();
     }
     
 void endspeedtest()//A different 'end' routine for speed tests.
@@ -210,20 +265,37 @@
         //pc.printf("messagesincount is only one less than spamcount, setting it.\r\n");
         //messagesincount = spamcount;
         //}
+    listen = 0;
     pc.printf("Ending CAN speed test.\r\n");
     pc.printf("%d messages sent. ", spamcount);
-    pc.printf("%d messages detected coming back in.\r\n", messagesincount);
-    pc.printf("%d messages in per second.\r\n", messagesinpersecond);
+    pc.printf("%d messages detected coming back in over %d seconds.\r\n", messagesincount, spamsecondstotal);
     int speedtestpercentage = ((messagesincount * 100)/spamcount);
     int speedtestpasslevel = 90;
     if (speedtestpercentage >= speedtestpasslevel)
         {
-        pc.printf("\033[1;32mTest pass: %d%% of messages detected back.\033[0m\r\n\n", speedtestpercentage);
+        //pc.printf("\033[1;32mTest pass: %d%% of messages detected back.\033[0m\r\n\n", speedtestpercentage);
         }
     else
         {
-        pc.printf("\033[1;31mTest fail: %d%% of messages detected back.\033[0m\r\n\n", speedtestpercentage);
+        //pc.printf("\033[1;31mTest fail: %d%% of messages detected back.\033[0m\r\n\n", speedtestpercentage);
         }
+    speedtestpasslevel = (CANGatewayCANbusspeed / 1000) * 8; //The HD2 can do 80 channels at 100Hz, so 8,000 messages per second are required at top baud rate (1000kbit/s)
+    if (CANGatewayCANbusspeed == mbedCANbusspeed)
+        {
+        if (messagesinpersecond >= speedtestpasslevel)
+            {
+            pc.printf("\033[1;32mTest pass: %d messages in per second. (%d required for pass at Gateway baud rate %d.)\033[0m\r\n", messagesinpersecond, speedtestpasslevel, CANGatewayCANbusspeed / 1000);
+            }
+        if (messagesinpersecond < speedtestpasslevel)
+            {
+            pc.printf("\033[1;31mTest fail: %d messages in per second. (%d required for pass at Gateway baud rate %d.)\033[0m\r\n", messagesinpersecond, speedtestpasslevel, CANGatewayCANbusspeed / 1000);
+            }
+        }
+    if (CANGatewayCANbusspeed != mbedCANbusspeed)
+        {
+        pc.printf("\033[1;35mTest invalid: Mbed CAN bus baud rate (%d) does not match presumed CAN Gateway baud rate (%d).\033[0m\r\n", mbedCANbusspeed / 1000, CANGatewayCANbusspeed / 1000);
+        }
+    pc.printf("\n");//Add an extra new line so the whole baud rate test is separate from the rest of the text.
     }
 
 //A generic 'send CAN' function to send CAN with a standard message
@@ -244,7 +316,7 @@
 //A function to deal with each CAN message part (e.g.: 301, 8, 01, 02...)
 void dealwithpart(void)
 {
-    int hextotal = 0;
+    hextotal = 0;
     partincrement = partincrement + 1;
     //pc.printf("Dealing with part %d. (%s)\r\n", partincrement, part);
     //int partincrementb = 0;
@@ -299,29 +371,34 @@
     //pc.printf("StringSteam says '%s'.\r\n", sstream.str());
     if (partincrement == 1)
         {
+        if (hextotal > 0xFFF)
+            {
+            hextotal = 0xFFF;
+            }
         messageOut1.id = hextotal;
         expected1 = hextotal;
+        if (customentry == 1)
+            {
+            idlistincrementer = hextotal;
+            }
         //For IDs, check if the ID is represented in the idsarray.
-        int idwasfound = 0;
-        idwasfound = 0;
         shouldntcomein = 0;
         if (mbedCANbusspeed != CANGatewayCANbusspeed)
             {
             shouldntcomein = 1;
-            if (aspamisgoing == 0)
-                {
-                reportbaudrates();
-                }
             }
+        idwasfound = 0;
         if (CANpassthrough == 0)
             {
             for(int i = 0; i <=arrayy-1; i++)
                 {
-                if(idsarray[0][i] == expected1)
+                if(idsarray[0][i][0] == expected1)
                     {
+                    //pc.printf("ID was found in the array at %d.\r\n", i);
                     idwasfound = 1;
+                    //pc.printf("IDwasfound is now '%d'.\r\n", idwasfound);
+                    columnidwasfound = i;
                     int originalexpectedvalue = expected1;
-                    expected1 = idsarray[1][i];
                     //Get string of hex code for original expected value (ID code found in array)
                     std::stringstream sstream;
                     sstream << std::hex << originalexpectedvalue;
@@ -335,14 +412,15 @@
                 }
             if (idwasfound == 0 and CANpassthrough == 0)
                 {
-                //pc.printf("ID of %d was never found, expecting it NOT to come in.\r\n", expected1);
                 //pc.printf("CANpassthrough is %d.\r\n", CANpassthrough);
                 shouldntcomein = 1;
+                //pc.printf("ID of %d was never found, expecting it NOT to come in.\r\n", expected1);
                 }
             if (shouldntcomein == 0 and unexpectedCANstreak > 0) //If data is expected to come in, this ends any unexpected-CAN streak.
                 {
                 if (aspamisgoing == 1) //Add a new line if it's in spam mode here to report new non-unexpected-CAN-streak stuff.
                     {
+                    //pc.printf("\r\n(FrombreakingunexpectedCANstreak 2)\n");
                     pc.printf("\r\n\n");
                     }
                 unexpectedCANstreak = 0;
@@ -391,6 +469,22 @@
         {
         expected10 = hextotal;
         }
+    //pc.printf("IDwasfound says '%d'.\r\n", idwasfound);
+    if (idwasfound == 1 and partincrement == 10)//If the ID was found in the table earlier, use it as the basis for the expected values instead.
+        {
+        //pc.printf("ID was found in table earlier, setting expectations\r\n");
+        int i = columnidwasfound;
+        expected1 = idsarray[1][i][0];
+        expected2 = idsarray[1][i][1];
+        expected3 = idsarray[1][i][2];
+        expected4 = idsarray[1][i][3];
+        expected5 = idsarray[1][i][4];
+        expected6 = idsarray[1][i][5];
+        expected7 = idsarray[1][i][6];
+        expected8 = idsarray[1][i][7];
+        expected9 = idsarray[1][i][8];
+        expected10 = idsarray[1][i][9];
+        }
     //pc.printf("Part %d complete.\r\n", partincrement);
     //pc.printf("--------------------------------------\r\n");
 }
@@ -398,7 +492,7 @@
 //A function to get a coherent CAN message from one, uninterrupted string
 void getCANfrommessageOutText(void)
 {
-    //pc.printf("messageOutText is '%s'\r\n", messageOutText);
+    //pc.printf("messageOutText before space-removal is '%s'\r\n", messageOutText);
     messageOutTextWithSpaces = messageOutText;
     remove(messageOutText.begin(), messageOutText.end(), ' '); //Remove the spaces from the text to send out so it can be parsed.
     //pc.printf("After removing spaces, messageOutText is '%s'\r\n", messageOutText);
@@ -415,6 +509,14 @@
         }
     expectationwasfulfilled = 0;
     partincrement = 0;
+    if (mbedCANbusspeed != CANGatewayCANbusspeed) // If the two bus speeds don't match, note that CAN should not be expected to ocme in and report the issue.
+    {
+    shouldntcomein = 1;
+    if (aspamisgoing == 0)
+        {
+        reportbaudrates();
+        }
+    }
     part = startofstring.substr(0,3);
     dealwithpart();
     part = startofstring.substr(3,1);
@@ -437,21 +539,27 @@
     dealwithpart();
 }
 
-void defineCANmessage(void)
-{
-    //pc.printf("Defining CAN message 1.\r\n");
-    //messageOut1.format = CANStandard;
-    //messageOut1.id = 0x301;
-    //messageOut1.len = 8;
-    //messageOut1.data[0] = 0x06;
-    //messageOut1.data[1] = 0x3f;
-    //messageOut1.data[2] = 0xb2;
-    //messageOut1.data[3] = 0x29;
-    //messageOut1.data[4] = 0x19;
-    //messageOut1.data[5] = 0x97;
-    //messageOut1.data[6] = 0x67;
-    //messageOut1.data[7] = 0x37;
-}
+void displayhelp(void)
+    {
+    pc.printf("\033[1;32m---------------HELP---------------\r\n");
+    pc.printf("Ken_CAN_Test is a program designed by Ken Dunlop to test CAN on the CAN Gateway.\r\n");
+    pc.printf("The program is designed to send CAN, then test the response.\r\n");
+    pc.printf("Press 'z' to begin sending a series of incrementing messages. Press 'Esc' to finish the test.\r\n");
+    pc.printf("Press 'v' to send a message on all IDs (000 - 7FF). Press 'Esc' to abort the test.\r\n");
+    pc.printf("Use 'q', 'w', 'e', and 'r' to change the Mbed's CAN bus speed.\r\n");
+    pc.printf("Use 't', 'y', 'u', and 'i' to change the presumed CAN bus speed of the CAN Gateway.\r\n");
+    pc.printf("If the two CAN bus speeds are different, the program will expect to get no CAN messages back.\r\n");
+    pc.printf("Press 'a' to begin a baud rate test. This sends CAN messages quickly and measures how many come back.\r\n");
+    pc.printf("Press 'k' to enter Custom Entry mode. This allows you to enter an CAN ID manually and then send a CAN message.\r\n");
+    pc.printf("Press 'z' to begin sending incrementing CAN messages. The data in the message will increment by 1 each time.\r\n");
+    pc.printf("Press 'o' while sending incrementing messages to multiply the incrementation by 16. This shifts the number up one half-byte.\r\n");
+    pc.printf("Press 'k' to enter Custom Entry mode. This allows you to enter an CAN ID manually and then send a CAN message.\r\n");
+    pc.printf("Press 'm' to set up an expectation table. This changes what CAN the system expects back when sending certain CAN IDs.\r\n");
+    pc.printf("Press 'n' to cancel the expectation table and re-enter CAN passthrough mode. This will simply expect the same CAN back as was sent.\r\n");
+    pc.printf("Press the number keys from '1' to '0' to send various pre-defined CAN messages out.\r\n");
+    pc.printf("Press '?' to bring up this help screen!\r\n");
+    pc.printf("---------------------------------\033[0m\r\n");
+    }
 
 void printMessageOut (void)
 {
@@ -482,6 +590,7 @@
     pc.printf("Using pins 9 and 10 for CANBus 1 (out) and 30 and 29 for CANBus 2 (in).\r\n");
     pc.printf("Version %d.%d\r\n",kMajorVersion,kMinorVersion);
     pc.printf("Build date %s %s\r\n",__DATE__,__TIME__);
+    pc.printf("\033[1;32mFor help, press '?'.\033[0m\r\n");
     pc.printf("------------------------------------------\r\n");
     char c;
     
@@ -501,7 +610,7 @@
                     CANmatchstreakstartID = 0;
                     if (aspamisgoing == 1)
                         {
-                        pc.printf("\r\n\n");//Add a return into the terminal to show the old streak on a line by itself.
+                        pc.printf("\r\n\nFrombreakingCANmatchstreak");//Add a return into the terminal to show the old streak on a line by itself.
                         }
                     }
                 if (goodnoreplystreak > 0 and shouldntcomein == 0) //A missing expected reply breaks any combos for expected no-replies
@@ -514,7 +623,7 @@
                     goodnoreplystreak = 0;
                     goodnoreplystreakstartid = 0;
                     }
-                // Add a line here if it's breaking an 'unexpected data...' combo
+                // If data did not come in when it was expected...
                 if (shouldntcomein == 0)
                     {
                     expectationwasfulfilled = 0;
@@ -529,9 +638,18 @@
                         goodnoreplystreak = 0;
                         if (aspamisgoing == 1)
                             {
-                            pc.printf("(From ending goodnoreplystreak)\r\n");//Add an extra line if breaking an 'as expected' no reply streak.
+                            pc.printf("(\r\n\n");//Add an extra line if breaking an 'as expected' no reply streak.
                             }
                         }
+                    if (failsstreak > 0)
+                        {
+                        if (aspamisgoing == 1)
+                            {
+                            pc.printf("\r\n\n");//Add an extra line if breaking a failure 'does not match expectation' streak
+                            }
+                        failsstreak = 0;
+                        failsstreakstart = 0;
+                        }
                     if (aspamisgoing == 1)
                         {
                         if (noreplystreak == 0)
@@ -562,6 +680,7 @@
                         {
                             if (aspamisgoing == 1) //Add a new line if it's in spam mode here to report new expected-non-message stuff.
                                 {
+                                //pc.printf("\r\n\n(FrombreakingunexpectedCANstreak)");
                                 pc.printf("\r\n\n");
                                 }
                         unexpectedCANstreak = 0;
@@ -578,6 +697,17 @@
                         noreplystreak = 0;
                         noreplystreakstartid = 0;
                         }
+                    // Also, getting an expected non-reply breaks any CAN-fail streaks
+                    if (failsstreak > 0 )
+                        {
+                        if (aspamisgoing == 1)
+                            {
+                            //pc.printf("\r\n(From breaking CAN-mismatch streak)\n");
+                            pc.printf("\r\n\n");
+                            }
+                        failsstreak = 0;
+                        failsstreakstart = 0;
+                        }
                     if (goodnoreplystreak == 0) //If there isn't yet a good no-reply streak, set the starting no-reply ID to this one
                         {
                         goodnoreplystreakstartid = idlistincrementer;
@@ -602,7 +732,7 @@
                         }
                     if (aspamisgoing == 0)
                         {
-                        pc.printf("\r\n"); //If it's not spamming, you can safely add a new line after the fail message.
+                        pc.printf("\r\n\n"); //If it's not spamming, you can safely add a new line after the fail message.
                         }
                     goodnoreplies++;
                     goodnoreplystreak++;
@@ -615,6 +745,10 @@
                     idscheckedcount++;
                     idlistincrementer++; //Only add 1 to the idlist incrementer at the end so the first ID it sends is '000'.
                     }
+                if (customentry == 1)
+                    {
+                    pc.printf("Enter CAN ID to send: ");
+                    }
                 }
             wait(0.01);
         }
@@ -628,65 +762,67 @@
                 //pc.printf("A key was pressed! (%c)\r\n", c);
                 messageOutText = "";
                 buttonPressMessageOutText = "";
-                if (c == '1' and aspamisgoing == 0)
+                if (c == '1' and normalkeypresses == 1)
                     {
-                    buttonPressMessageOutText = "301 8 01 01 01 01 01 01 01 01";
+                    buttonPressMessageOutText = "301 8 01 02 03 04 05 06 07 08";
                     idlistincrementer = 0x301;
                     }
-                if (c == '2' and aspamisgoing == 0)
+                if (c == '2' and normalkeypresses == 1)
                     {
-                    buttonPressMessageOutText = "302 8 02 02 02 02 02 02 02 02";
+                    buttonPressMessageOutText = "302 8 01 02 03 04 05 06 07 08";
                     idlistincrementer = 0x302;
                     }
-                if (c == '3' and aspamisgoing == 0)
+                if (c == '3' and normalkeypresses == 1)
                     {
-                    buttonPressMessageOutText = "303 8 00 00 00 00 00 00 00 33";
+                    buttonPressMessageOutText = "303 8 01 02 03 04 05 06 07 08";
                     idlistincrementer = 0x303;
                     }
-                if (c == '4' and aspamisgoing == 0)
+                if (c == '4' and normalkeypresses == 1)
                     {
-                    buttonPressMessageOutText = "304 8 04 04 04 04 04 04 04 04";
+                    buttonPressMessageOutText = "304 8 01 02 03 04 05 06 07 08";
                     idlistincrementer = 0x304;
                     }
-                if (c == '5' and aspamisgoing == 0)
+                if (c == '5' and normalkeypresses == 1)
                     {
-                    buttonPressMessageOutText = "305 8 05 05 05 05 05 05 05 05";
-                    idlistincrementer = 0x305;
+                    buttonPressMessageOutText = "15B 8 01 02 03 04 05 06 07 08";
+                    idlistincrementer = 0x15B;
                     }
-                if (c == '6' and aspamisgoing == 0)
+                if (c == '6' and normalkeypresses == 1)
                     {
-                    buttonPressMessageOutText = "306 8 06 06 06 06 06 06 06 06";
+                    buttonPressMessageOutText = "306 8 01 02 03 04 05 06 07 08";
                     idlistincrementer = 0x306;
                     }
-                if (c == '7' and aspamisgoing == 0)
+                if (c == '7' and normalkeypresses == 1)
                     {
-                    buttonPressMessageOutText = "307 8 07 07 07 07 07 07 07 07";
+                    buttonPressMessageOutText = "307 8 01 02 03 04 05 06 07 08";
                     idlistincrementer = 0x307;
                     }
-                if (c == '8' and aspamisgoing == 0)
+                if (c == '8' and normalkeypresses == 1)
                     {
-                    buttonPressMessageOutText = "308 8 08 08 08 08 08 08 08 08";
+                    buttonPressMessageOutText = "308 8 01 02 03 04 05 06 07 08";
                     idlistincrementer = 0x308;
                     }
-                if (c == '9' and aspamisgoing == 0)
+                if (c == '9' and normalkeypresses == 1)
                     {
-                    buttonPressMessageOutText = "309 8 09 09 09 09 09 09 09 09";
+                    buttonPressMessageOutText = "309 8 01 02 03 04 05 06 07 08";
                     idlistincrementer = 0x309;
                     }
-                if (c == '0' and aspamisgoing == 0)
+                if (c == '0' and normalkeypresses == 1)
                     {
                     buttonPressMessageOutText = "7FF 8 FF FF FF FF FF FF FF FF";//NOTE: CAN IDs only go to 7FF, not FFF.
                     idlistincrementer = 0x7FF;
                     }
-                if (c == 'a' and aspamisgoing == 0)
+                if (c == 'a' and normalkeypresses == 1)
                     {
-                    pc.printf("Starting baud rate speed test. Mbed at %d and CAN Gateway presumed %d. (Press 'x' to end.)\r\n", mbedCANbusspeed / 1000, CANGatewayCANbusspeed / 1000);
+                    listen = 1;
+                    pc.printf("Starting baud rate speed test. Mbed at %d and CAN Gateway presumed %d. (Press 'Esc' to end.)\r\n", mbedCANbusspeed / 1000, CANGatewayCANbusspeed / 1000);
                     pc.printf("");
                     resettest();
                     incrementer = 0x333;
                     spamstarttime = clock();
                     speedspamison = 1;
                     aspamisgoing = 1;
+                    normalkeypresses = 0;
                     messageOut1.format = CANStandard; //Quickly define a convenient messageOut for the speed spam to use.
                     messageOut1.id = 0x301;
                     messageOut1.len = 8;
@@ -698,11 +834,13 @@
                     messageOut1.data[5] = 0x97;
                     messageOut1.data[6] = 0x67;
                     messageOut1.data[7] = 0x37;
+                    pc.printf("Will send out '%03X %01X %02X %02X %02X %02X %02X %02X %02X %02X' as fast as possible.\r\n", messageOut1.id, messageOut1.len, messageOut1.data[0], messageOut1.data[1], messageOut1.data[2], messageOut1.data[3], messageOut1.data[4], messageOut1.data[5], messageOut1.data[6], messageOut1.data[7]);
                     }
-                if (c == 'x' and speedspamison == 1)//Cancel speed spam mode
+                if (c == 27 and speedspamison == 1)//Cancel speed spam mode
                     {
                     //pc.printf("\r\nEnding baud rate speed test mode from upper key press method.\r\n");
                     aspamisgoing = 0;
+                    normalkeypresses = 1;
                     spamendtime = clock();
                     //endtest();
                     getspamsecondstotal();
@@ -714,77 +852,162 @@
                     if (aspamisgoing == 0)
                         {
                         //addnewlineifneeded();
+                        //resetCANbuses();
+                        listen = 1;
                         messageOutText = buttonPressMessageOutText;
                         addnewlinetonextmessage = 1;
                         checklaterbytes = 1;//Check all bytes for button-press messages.
                         }
                     buttonPressMessageOutText = "";
                     }
-                if (c == 'q' and aspamisgoing == 0)
+                if (c == '/' and normalkeypresses == 1)
+                    {
+                    displayhelp();
+                    }
+                if (c == '?' and normalkeypresses == 1)
+                    {
+                    displayhelp();
+                    }
+                if (c == 'q' and normalkeypresses == 1)
                     {
                     pc.printf("Changing Mbed CAN bus speed to 125.\r\n");
                     CanBus.frequency(125 * 1000); // CAN bus at 125k
                     CanBus2.frequency(125 * 1000); // CAN bus at 125k
                     mbedCANbusspeed = (125 * 1000);
                     }
-                if (c == 'w' and aspamisgoing == 0)
+                if (c == 'w' and normalkeypresses == 1)
                     {
                     pc.printf("Changing Mbed CAN bus speed to 250.\r\n");
                     CanBus.frequency(250 * 1000); // CAN bus at 250k
                     CanBus2.frequency(250 * 1000); // CAN bus at 250k
                     mbedCANbusspeed = (250 * 1000);
                     }
-                if (c == 'e' and aspamisgoing == 0)
+                if (c == 'e' and normalkeypresses == 1)
                     {
                     pc.printf("Changing Mbed CAN bus speed to 500.\r\n");
                     CanBus.frequency(500 * 1000); // CAN bus at 500k
                     CanBus2.frequency(500 * 1000);// CAN bus at 500k
                     mbedCANbusspeed = (500 * 1000);
                     }
-                if (c == 'r' and aspamisgoing == 0)
+                if (c == 'r' and normalkeypresses == 1)
                     {
                     pc.printf("Changing Mbed CAN bus speed to 1000.\r\n");
                     CanBus.frequency(1000 * 1000); // CAN bus at 1000k
                     CanBus2.frequency(1000 * 1000); // CAN bus at 1000k
                     mbedCANbusspeed = (1000 * 1000);
                     }
-                if (c == 't' and aspamisgoing == 0)
+                if (c == 't' and normalkeypresses == 1)
                     {
                     CANGatewayCANbusspeed = (125 * 1000);
                     pc.printf("CAN Gateway is now presumed to be at CAN bus speed %d.\r\n", CANGatewayCANbusspeed / 1000);
                     }
-                if (c == 'y' and aspamisgoing == 0)
+                if (c == 'y' and normalkeypresses == 1)
                     {
                     CANGatewayCANbusspeed = (250 * 1000);
                     pc.printf("CAN Gateway is now presumed to be at CAN bus speed %d.\r\n", CANGatewayCANbusspeed / 1000);
                     }
-                if (c == 'u' and aspamisgoing == 0)
+                if (c == 'u' and normalkeypresses == 1)
                     {
                     CANGatewayCANbusspeed = (500 * 1000);
                     pc.printf("CAN Gateway is now presumed to be at CAN bus speed %d.\r\n", CANGatewayCANbusspeed / 1000);
                     }
-                if (c == 'i' and aspamisgoing == 0)
+                if (c == 'i' and normalkeypresses == 1)
                     {
                     CANGatewayCANbusspeed = (1000 * 1000);
                     pc.printf("CAN Gateway is now presumed to be at CAN bus speed %d.\r\n", CANGatewayCANbusspeed / 1000);
                     }
-                if (c == 'n' and CANpassthrough == 0 and aspamisgoing == 0)
+                if (c == 'k' and normalkeypresses == 1)
+                    {
+                    pc.printf("Will enter custom CAN entry mode. (Press 'Esc' to end.)\r\nEnter CAN ID to send: ");
+                    customentry = 1;
+                    normalkeypresses = 0;
+                    c = NULL;
+                    customentrystring = "";
+                    }
+                if (c == 27 and customentry == 1)//Pressing Esc ends Custom Entry mode
+                    {
+                    customentry = 0;
+                    normalkeypresses = 1;
+                    pc.printf("\r\nEnding custom entry mode.\r\n");
+                    c = NULL;
+                    }
+                if (c == 13 and customentry == 1 and customentrystring != "")//Pressing enter in Custom Entry mode tries to send a CAN message
+                    {
+                    pc.printf("\r\n");
+                    //pc.printf("Will try to confirm CES ('%s').\r\n", customentrystring);
+                    if (customentrystring.length() < 3)
+                        {
+                        customentrystring = "0" + customentrystring;
+                        }
+                    if (customentrystring.length() < 3)
+                        {
+                        customentrystring = "0" + customentrystring;
+                        }
+                    checklaterbytes = 1;
+                    partincrement = 0;
+                    part = customentrystring;
+                    dealwithpart();
+                    //pc.printf("Hextotal now says '%d'.\r\n", hextotal);
+                    if (hextotal > 0x7FF)//If the measured total is more than 0x7FF (the max ID), reduce it.
+                        {
+                        hextotal = 0x7FF;
+                        customentrystring = "7FF";
+                        }
+                    if (hextotal < 0) // If the measured total is less than zero, make it zero instead.
+                        {
+                        hextotal = 0x000;
+                        customentrystring = "000";
+                        }
+                    messageOutText = customentrystring + " 8 01 02 03 04 05 06 07 08";
+                    customentrystring = "";
+                    if (expectationresolved == 1 and messageOutText == "")
+                        {
+                        pc.printf("Enter CAN ID to send: ");
+                        }
+                    }
+                if (c != NULL and customentry == 1 and expectationresolved == 1 and messageOutText == "")
+                    {
+                    //pc.printf("Custom entry detected! (%c)\r\n", c);
+                    if (c != '\r' and c != 8 and customentrystring.length() < 3) //Normal key presses add to the custom string.
+                        {
+                        customentrystring.push_back(toupper(c));
+                        //pc.printf("Custom entry string now says '%s'.", customentrystring);
+                        }
+                    if (c == 8 and customentrystring.length() > 0) //Backspace (character 8) causes the text to go back one character.
+                        {
+                        pc.printf("\b ");
+                        customentrystring.erase(customentrystring.size()-1,1);
+                        }
+                    pc.printf("\rEnter CAN ID to send: %s", customentrystring);
+                    }
+                if (c == 'n' and CANpassthrough == 0 and normalkeypresses == 1)
                     {
                     pc.printf("Starting CAN passthrough mode. Will expect to recieve the same CAN that is sent.\r\n");
                     CANpassthrough = 1;
                     }
-                if (c == 'm' and CANpassthrough == 1 and aspamisgoing == 0)
+                if (c == 'm' and CANpassthrough == 1 and normalkeypresses == 1)
                     {
                     pc.printf("Will make a CAN ID translation array.\r\n");
                     //Making a two-dimensional array with 301-309 in the first column, then 401-409 in the second column.
-                    int copyarray[2][8] = {{769, 770, 771, 772, 773, 774, 776, 777}, {1025, 1026, 1027, 1028, 1029, 1030, 1032, 1033}};
+                    int copyarray[2][8][10] = {
+                                              { {0x301,0x8, 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x302,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x303,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x304,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x305,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x306,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x308,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08}, {0x309,0x8,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08} },
+                                              { {0x401,0x8,0x08,0x00,0x00,0x00,0x04,0x05,0x06,0x01}, {0x402,0x8,0x04,0x05,0x06,0x07,0x06,0x07,0x08,0x00}, {0x403,0x8,0x03,0x04,0x05,0x05,0x06,0x80,0x00,0x00}, {0x404,0x8,0x04,0x05,0x06,0x07,0x06,0x07,0x08,0x00}, {0x405,0x8,0x04,0x05,0x06,0x07,0x06,0x07,0x08,0x00}, {0x406,0x8,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00}, {0x408,0x8,0x06,0x07,0x08,0x00,0x00,0x00,0x00,0x00}, {0x409,0x8,0x06,0x07,0x08,0x00,0x00,0x00,0x00,0x00} },
+                                              };
+                    //int copyarray[2][8][10] = {{769, 770, 771, 772, 773, 774, 776, 777}, {1025, 1026, 1027, 1028, 1029, 1030, 1032, 1033}};
                     //int copyarray[2][1] = {{2047}, {1025}};
                     memcpy(idsarray, copyarray, sizeof(copyarray)); //Copy the new array over the old 'idsarray'.
                     arrayx = 2;
                     arrayy = 8;
+                    arrayz = 10;
                     //pc.printf("Array is %dx%d.\r\n", arrayx, arrayy); //Report the size variables of the new array.
-                    pc.printf("1st column of IDs array says \033[0;30;47m%03X, %03X, %03X, %03X, %03X, %03X, %03X, %03X\033[0m\r\n", idsarray[0][0], idsarray[0][1], idsarray[0][2], idsarray[0][3], idsarray[0][4], idsarray[0][5], idsarray[0][6], idsarray[0][7]);
-                    pc.printf("2nd column of IDs array says \033[0;30;47m%03X, %03X, %03X, %03X, %03X, %03X, %03X, %03X\033[0m\r\n", idsarray[1][0], idsarray[1][1], idsarray[1][2], idsarray[1][3], idsarray[1][4], idsarray[1][5], idsarray[1][6], idsarray[1][7]);
+                    for(int i = 0; i <arrayy; i++)
+                        {
+                        //pc.printf("Will show contents of table at column %d.\r\n", i);
+                        pc.printf("1st column of CAN array (%d) says \033[0;30;47m%03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\033[0m\r\n", i, idsarray[0][i][0], idsarray[0][i][1], idsarray[0][i][2], idsarray[0][i][3], idsarray[0][i][4], idsarray[0][i][5], idsarray[0][i][6], idsarray[0][i][7], idsarray[0][i][8], idsarray[0][i][9]);
+                        pc.printf("2nd column of CAN array (%d) says \033[0;30;47m%03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\033[0m\r\n", i, idsarray[1][i][0], idsarray[1][i][1], idsarray[1][i][2], idsarray[1][i][3], idsarray[1][i][4], idsarray[1][i][5], idsarray[1][i][6], idsarray[1][i][7], idsarray[1][i][8], idsarray[1][i][9]);
+                        }
+                    //pc.printf("1st column of IDs array says \033[0;30;47m%03X, %01X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\033[0m\r\n", idsarray[0][0][0], idsarray[0][0][1], idsarray[0][0][2], idsarray[0][0][3], idsarray[0][0][4], idsarray[0][0][5], idsarray[0][0][6], idsarray[0][0][7], idsarray[0][0][8], idsarray[0][0][9]);
+                    //pc.printf("2nd column of IDs array says \033[0;30;47m%03X, %01X, %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X\033[0m\r\n", idsarray[1][0][0], idsarray[1][0][1], idsarray[1][0][2], idsarray[1][0][3], idsarray[1][0][4], idsarray[1][0][5], idsarray[1][0][6], idsarray[1][0][7], idsarray[1][0][8], idsarray[1][0][9]);
                     //pc.printf("1st column of IDs array says %d.\r\n", idsarray[0][0]);
                     //pc.printf("2nd column of IDs array says %d.\r\n", idsarray[1][0]);
                     CANpassthrough = 0;
@@ -800,7 +1023,6 @@
                             }
                         }
                     */
-                    //pc.printf("It got here.\r\n"); //To check if it got stuck at this point.
                     }
                 //if (c == 's')
                 //  {
@@ -829,39 +1051,49 @@
                     //pc.printf("Will try to send '%s'.\r\n", messageOutText);
                     }
                 messageOut1.format = CANStandard;
-                if (c == 'z' and aspamisgoing == 0)
+                if (c == 'z' and normalkeypresses == 1)
                     {
                     resettest();
-                    pc.printf("Starting spam sequence for ID %s. Press 'x' to end. Press 'o' to increase incrementer.\r\n", spampreamble);
+                    pc.printf("Starting spam sequence for ID %s. Press 'Esc' to end. Press 'o' to increase incrementer.\r\n", spampreamble);
                     idlistincrementer = 0x333;
                     reportbaudrates();
                     spamon = 1;
                     aspamisgoing = 1;
+                    normalkeypresses = 0;
                     checklaterbytes = 1;
                     incrementer = 0;
                     spamcount = 0;
                     spamstarttime = clock();
                     //pc.printf("Spam start time is %d.\r\n", spamstarttime);
                     }
-                if (c == 'x' and spamon == 1)//Cancel normal '333' incrementing spam mode
+                if (c == 27 and spamon == 1)//Cancel normal '333' incrementing spam mode
                     {
                     pc.printf("\r\n");
                     spamon = 2;
                     aspamisgoing = 0;
+                    normalkeypresses = 1;
                     spamendtime = clock();
                     getspamsecondstotal();//Process the spam information
                     //pc.printf("Total spams ever are %d.\r\n", totalspamsever);
                     endtest();
                     //pc.printf("-------------------------\r\n");
                     }
-                if (c == 'v' and aspamisgoing == 0)
+                if (c == 27 and idspamon ==  1)//Cancel CAN ID spam mode
+                    {
+                    //pc.printf("Cancelling ID test mode.\r\n");
+                    testwasaborted = 1;
+                    endidspamtest();
+                    normalkeypresses = 1;
+                    }
+                if (c == 'v' and normalkeypresses == 1)
                     {
                     resettest();
                     idspamon = 1; //Set the 'idspamon' integer to 1 so ID spam happens.
                     aspamisgoing = 1;
-                    checklaterbytes = 0;
+                    normalkeypresses = 0;
+                    checklaterbytes = 1;
                     idlistincrementer = 0;
-                    pc.printf("Beginning check of all possible CAN IDs (000 - 7FF).\r\n");
+                    pc.printf("Beginning check of all possible CAN IDs (000 - 7FF). Press 'Esc' to abort.\r\n");
                     reportbaudrates();
                     spamstarttime = clock();
                     //pc.printf("Spam started at clock time %d.\r\n", spamstarttime);
@@ -869,6 +1101,10 @@
                         {
                         pc.printf("Will only check CAN IDs, not later bytes.\r\n");
                         }
+                    if (checklaterbytes == 1)
+                        {
+                        pc.printf("Will check all bytes in each CAN message.\r\n");
+                        }
                     }
                 if (messageOutText != "" and speedspamison == 0)
                     {
@@ -904,15 +1140,7 @@
                     }
                 if (idspamon == 1 and idlistincrementer >= 2048 and expectationresolved == 1) //If the spam value gets to 2048 (7FF), end the spam sequence. RL only go up to 7FF.
                     {
-                       spamendtime = clock();
-                       getspamsecondstotal();//Process the spam information
-                       idspamon = 0;
-                       aspamisgoing = 0;
-                       addnewlinetonextmessage = 1;
-                       //addnewlineifneeded();
-                       //pc.printf("Ending ID spam sequence. %d IDs checked total.\r\n", idscheckedcount);
-                       idlistincrementer = 0;
-                       endtest();
+                       endidspamtest();
                     }
                 if (idspamon == 1 and expectationresolved == 1)
                     {
@@ -939,19 +1167,17 @@
                     //CanBus.write(messageOut1);
                     //CanBus2.write(messageOut1);
                     //pc.printf("ID list incrementer is now %d\r\n", idlistincrementer);
-
                     wait(0.01);//ID spam at 100Hz
                     }
-        
-        //Count each CAN message coming in during speed spam
-        //if (CanBus2.read(messageIn) and speedspamison == 1)
+
+        //Optional: mention any un-listened-to CAN messages. Having this stopped it from reading messages in when listen was on.
+        //if (CanBus2.read(messageIn) and listen == 0)
         //  {
-        //  messagesincount++;
-        //  pc.printf("\033[0;36m Speed spam message IN: %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\033[0m\r\n",messageIn.id,messageIn.len,messageIn.data[0],messageIn.data[1],messageIn.data[2],messageIn.data[3],messageIn.data[4],messageIn.data[5],messageIn.data[6],messageIn.data[7]);
+        //  pc.printf("(Un-listened-to CAN message came in.)\r\n");
         //  }
-        
-        //Check for CAN messages coming in (not in speed spam)
-        if (CanBus2.read(messageIn))
+
+        //Check for CAN messages coming in
+        if (CanBus2.read(messageIn) and listen == 1)
             {
             if (speedspamison == 1)
                 {
@@ -971,15 +1197,27 @@
                     {
                     goodnoreplystreak = 0;
                     goodnoreplystreakstartid = 0;
-                    pc.printf("\r\n\n");
+                    if (aspamisgoing == 1)
+                        {
+                        pc.printf("\r\n\n");
+                        }
                     }
                 CANCount++;
-                reportsentCAN();
                 if (1 == 1)//Prepare to print out the message coming in
                     {
                     //Data shouldn't come in at all if 'shouldntcomein' is 1!
+                    //pc.printf("Wah! Unexpected CAN came in!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n");
                     if (shouldntcomein == 1)
                         {
+                        if (failsstreak > 0)
+                            {
+                            failsstreak = 0;
+                            failsstreakstart = 0;
+                            if (aspamisgoing == 1)
+                                {
+                                pc.printf("\n\n\r");
+                                }
+                            }
                         if (unexpectedCANstreak == 0)//If it's the start of a new unexpected-CAN streak, mark the starting ID.
                             {
                             unexpectedCANstreakstartid = idlistincrementer;
@@ -988,6 +1226,7 @@
                             {
                             unexpectedCANstreakstartid = idlistincrementer;
                             }
+                        reportsentCAN();
                         if (unexpectedCANstreakstartid != idlistincrementer)
                             {
                             pc.printf("\033[0;35mUnexpected data came in for IDs %03X to %03X!\033[0m", unexpectedCANstreakstartid, idlistincrementer);
@@ -1022,13 +1261,55 @@
                         {itsamatch = 0;}
                     if (expected10 != messageIn.data[7] and checklaterbytes >= 1)
                         {itsamatch = 0;}
+
+                    //pc.printf("itsamatch %d, shouldntcomein %d.", itsamatch, shouldntcomein);
                     if (itsamatch == 0 and shouldntcomein == 0)
                         {
-                        pc.printf("\033[0;31mIncoming data for ID %03X does not match expectation!\033[0m", idlistincrementer);
+                        if (failsstreak == 0)
+                            {
+                            failsstreakstart = idlistincrementer;
+                            }
+                        failsstreak++;
+                        if (aspamisgoing == 0)
+                            {
+                            failsstreakstart = idlistincrementer;
+                            }
+                        reportsentCAN(); //Report sent CAN before any 'does not match...' messages
+                        if (failsstreakstart == idlistincrementer)
+                            {
+                            pc.printf("\033[0;31mData for ID %03X does not match expectation!\033[0m", idlistincrementer);
+                            }
+                        if (failsstreakstart != idlistincrementer)
+                            {
+                            pc.printf("\033[0;31mData for IDs %03X to %03X does not match expectation!\033[0m", failsstreakstart, idlistincrementer);
+                            }
+                        }
+                    //Decide if a message in will need to be printed ('Message received was:...')
+                    messageinisneeded = 0;
+                    if (aspamisgoing == 0)
+                        {messageinisneeded = 1;}
+                    //if (itsamatch == 0 and shouldntcomein == 0)
+                    //    {messageinisneeded = 1;}
+                    if (reportfailsindividually == 1)
+                        {messageinisneeded = 1;}
+                    // If a message in is destined to be printed, reset the failsstreak if needed
+                    if (messageinisneeded == 1 and failsstreak > 0)
+                        {
+                        failsstreak = 0;
+                        failsstreakstart = 0;
                         }
                     // Once it's known whether the data matches expectation, set the match streak
                     if (itsamatch == 1 and shouldntcomein == 0)
                         {
+                        if (failsstreak > 0)
+                            {
+                            failsstreak = 0;
+                            failsstreakstart = 0;
+                            if (aspamisgoing == 1)
+                                {
+                                pc.printf("\r\n\n");
+                                }
+                            }
                         if (CANmatchstreak == 0)
                             {
                             CANmatchstreakstartID = idlistincrementer;
@@ -1041,11 +1322,7 @@
                         CANmatchstreakstartID = 0;
                         }
                     // Print needed message
-                    int messageinisneeded = 0;
-                    if (aspamisgoing == 0)
-                        {messageinisneeded = 1;}
-                    if (itsamatch == 0 and shouldntcomein == 0)
-                        {messageinisneeded = 1;}
+                    reportsentCAN();
                     if (messageinisneeded == 0) //If a message in is NOT needed, simply report what the CAN is doing on the same line.
                         {
                         if (itsamatch == 1 and CANmatchstreakstartID == idlistincrementer and CANmatchstreak > 0)
@@ -1076,7 +1353,7 @@
                             }
                         else
                             {
-                            pc.printf("%01X\033[0m ", messageIn.len);
+                            pc.printf("\033[1;32m%01X\033[0m ", messageIn.len);
                             }
                         if (expected3 != messageIn.data[0] and checklaterbytes >= 1)
                             {
@@ -1085,7 +1362,7 @@
                             }
                         else
                             {
-                            pc.printf("%02X\033[0m ", messageIn.data[0]);
+                            pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[0]);
                             }
                         if (expected4 != messageIn.data[1] and checklaterbytes >= 1)
                             {
@@ -1094,7 +1371,7 @@
                             }
                         else
                             {
-                            pc.printf("%02X\033[0m ", messageIn.data[1]);
+                            pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[1]);
                             }
                         if (expected5 != messageIn.data[2] and checklaterbytes >= 1)
                             {
@@ -1103,7 +1380,7 @@
                             }
                         else
                             {
-                            pc.printf("%02X\033[0m ", messageIn.data[2]);
+                            pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[2]);
                             }
                         if (expected6 != messageIn.data[3] and checklaterbytes >= 1)
                             {
@@ -1113,7 +1390,7 @@
                             
                         else
                             {
-                            pc.printf("%02X\033[0m ", messageIn.data[3]);
+                            pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[3]);
                             }
                         if (expected7 != messageIn.data[4] and checklaterbytes >= 1)
                             {
@@ -1122,7 +1399,7 @@
                             }
                         else
                             {
-                            pc.printf("%02X\033[0m ", messageIn.data[4]);
+                            pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[4]);
                             }
                         if (expected8 != messageIn.data[5] and checklaterbytes >= 1)
                             {
@@ -1131,7 +1408,7 @@
                             }
                         else
                             {
-                            pc.printf("%02X\033[0m ", messageIn.data[5]);
+                            pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[5]);
                             }
                         if (expected9 != messageIn.data[6] and checklaterbytes >= 1)
                             {
@@ -1140,7 +1417,7 @@
                             }
                         else
                             {
-                            pc.printf("%02X\033[0m ", messageIn.data[6]);
+                            pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[6]);
                             }
                         if (expected10 != messageIn.data[7] and checklaterbytes >= 1)
                             {
@@ -1149,10 +1426,11 @@
                             }
                         else
                             {
-                            pc.printf("%02X\033[0m ", messageIn.data[7]);
+                            pc.printf("\033[1;32m%02X\033[0m ", messageIn.data[7]);
                             }
-                        if (aspamisgoing == 0)
+                        if (messageinisneeded == 1)
                             {
+                            //pc.printf("\r\n(Aftersentoutmessage)");
                             pc.printf("\r\n");//Add a return and a new line after the 'Sent out' message is finished if it's not spam mode.
                             }
                         }
@@ -1161,12 +1439,20 @@
                         mismatchfailsthistest++;
                         if (aspamisgoing == 1)
                             {
-                            pc.printf("\r\n"); //Having a new line here separated 'message received was:...' from 'Does NOT match...' too much.
+                            //pc.printf("\r\n(ToseparateMRWfromDNM)"); //Having a new line here separated 'message received was:...' from 'Does NOT match...' too much.
                             }
-                        pc.printf("Does NOT match      : %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\r\n\n", expected1, expected2, expected3, expected4, expected5, expected6, expected7, expected8, expected9, expected10);
-                        if (aspamisgoing == 0)
+                        if (messageinisneeded == 1)
                             {
-                            //pc.printf("\r\n");
+                            pc.printf("Does NOT match      : %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\r", expected1, expected2, expected3, expected4, expected5, expected6, expected7, expected8, expected9, expected10);
+                            //pc.printf("Check later bytes is %d.\r\n", checklaterbytes);
+                            if (messageinisneeded == 1 and aspamisgoing == 0)
+                                {
+                                pc.printf("\n\n");
+                                }
+                            if (messageinisneeded == 1 and aspamisgoing == 1)
+                                {
+                                pc.printf("\n\n");
+                                }
                             }
                         failsthistest++; //Add 1 to failsthistest to mark the fail
                         expectationwasfulfilled = 0;
@@ -1178,9 +1464,13 @@
                         expectationresolved = 1;
                         matchesthistest++;
                         //If it's a match, write out a 'Matches expectation...' message
-                        if (CANpassthrough == 0 and aspamisgoing == 0)
+                        if (messageinisneeded == 1)
                             {
-                            pc.printf("Matches expectation : %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\r\n\n", expected1, expected2, expected3, expected4, expected5, expected6, expected7, expected8, expected9, expected10);
+                            pc.printf("Matches expectation : %03X %01X %02X %02X %02X %02X %02X %02X %02X %02X\r", expected1, expected2, expected3, expected4, expected5, expected6, expected7, expected8, expected9, expected10);
+                            if (aspamisgoing == 0)
+                                {
+                                pc.printf("\n\n");
+                                }
                             }
                         }
                     }
@@ -1189,6 +1479,10 @@
                     idscheckedcount++;
                     idlistincrementer++; //Only add 1 to the idlist incrementer at the end so the first ID it sends is '000'.
                     }
+                if (customentry == 1)
+                    {
+                    pc.printf("Enter CAN ID to send: ");
+                    }
                 }
             //If speed-spam is on, spam a CAN message as fast as possible.
             }
@@ -1198,8 +1492,8 @@
             CanBus.write(messageOut1);
             spamcount++;
             //pc.printf("\rSent %d '%03X %01X %02X %02X %02X %02X %02X %02X %02X %02X' messages...", spamcount, messageOut1.id, messageOut1.len, messageOut1.data[0], messageOut1.data[1], messageOut1.data[2], messageOut1.data[3], messageOut1.data[4], messageOut1.data[5], messageOut1.data[6], messageOut1.data[7]);
-            //Pressing 'x' switches off speed spam mode
-            //wait(0.001);
+            //Pressing 'Esc' switches off speed spam mode
+            wait(0.00001);
             }
         }
     }
\ No newline at end of file