Advertisement
skizziks_53

serial_message_spy_v1.0

Jan 27th, 2018
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 14.39 KB | None | 0 0
  1. /*
  2.   Serial Message Spy ver. 1.0 -------- 26 January 2018
  3.   Arduino Uno sketch for 16x2 LCD shield with keypad
  4.  
  5.   This sketch is for capturing and displaying inbound and outbound serial messages from another Arduino board.
  6.  
  7.   Based on example sketch provided at:
  8.   https://www.dfrobot.com/wiki/index.php/Arduino_LCD_KeyPad_Shield_(SKU:_DFR0009)#Example_use_of_LiquidCrystal_library
  9.  
  10.   Notes:
  11.   1. I used a generic 16x2 LCD button keypad shield I bought online, manufacturer unknown.
  12.      These use the normal Arduino 16x2 LCD library and five resistive buttons monitored by one analog input pin.
  13.      Other LCD+keypad boards that use I2C may require code editing.
  14.   2. Note that I had to use the second set of button (adc_key) values provided, not the first set.
  15.   3. The sketch at the link above should be loaded and run first, to make sure the button adc levels are set correctly.
  16.  
  17. */
  18.  
  19. /*
  20.   INSTRUCTIONS FOR USE
  21.   This sketch is for monitoring incoming and outgoing serial messages.
  22.   The incoming messages can be received from the normal USB port.
  23.   This allows partial testing directly on the connected computer, as you are loading the sketch.
  24.  
  25.   If you want to monitor USB messages of another Arduino board:
  26.   While the boards are unpowered,
  27.    1. connect the grounds of both boards together.
  28.    2. connect the pins D0 on both boards together, and
  29.    3. connect pin D2 of this board to D1 of the other board.
  30.    Use short wires if possible.
  31.   This will allow the Arduino that this sketch is running on, to monitor the messages that the other Arduino sends and receives.
  32.  
  33.   If the arduino that is monitoring is connected to a PC while it is used for monitoring another board,
  34.   do not send any USB messages to it because there is no way to discriminate between the source of the message.
  35.  
  36.   There are four different screens. The UP and DOWN buttons scroll through the separate screens.
  37.  
  38.   The first screen allows you to set the baud rate to any of the standard Arduino rates. LEFT and RIGHT changes the baud rate.
  39.   The serial ports reset to the selected speed whenever you change the speed.
  40.  
  41.   The message storage capacity for incoming and outgoing messages is 128 characters for each.
  42.   If a message goes past the 128-character limit, the sketch will automatically stop detecting additional characters
  43.   and change to the associated message display screen.
  44.  
  45.   The second screen shows the characters from any incoming message that are received. At the top is the total count of the characters received.
  46.   The message array index number and character ASCII code is displayed on the left, and the character is visually displayed on the right inside brackets.
  47.   Note that many ASCII characters are non-printing and may not be recognizable visually.
  48.   The LEFT and RIGHT buttons scroll backward and forward through the 128-character storage array.
  49.   The SELECT button will erase the storage array (set all the values back to zero).
  50.  
  51.   The third screen is for displaying the outgoing messages. It works just like the second screen.
  52.  
  53.   The fourth screen is for enabling and disabling monitoring. LEFT and RIGHT disables and enables the serial monitoring function.
  54.   By default the monitoring begins disabled when the sketch starts.
  55.  
  56.  
  57. */
  58.  
  59. //Sample using LiquidCrystal library ------------ (Note: this is the standard Arduino liquidcrystal library)
  60. #include <LiquidCrystal.h>
  61. #include <SoftwareSerial.h>
  62.  
  63. // The hardware Serial communicates on digital pins 0 (RX) and 1 (TX).
  64. // We are using the normal serial input pin 0 [digital zero] to catch outgoing messages from the normal USB-connected computer.
  65. SoftwareSerial mySerial(2, 3); // RX, TX -->pin D2 is for messages sent from the other Arduino board.
  66. // To use this to monitor the hardware serial connection of another Arduino board:
  67. // The pin D0 of this board should be connected to the pin D0 of the other Arduino board.
  68. // The pin D2 of this board should be connected to the pin D1 of the other Arduino board.
  69.  
  70.  
  71. // select the pins used on the LCD panel
  72. LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
  73.  
  74. // define some values used by the panel and buttons
  75. int lcd_key     = 0;
  76. int adc_key_in  = 0;
  77. #define btnRIGHT  0
  78. #define btnUP     1
  79. #define btnDOWN   2
  80. #define btnLEFT   3
  81. #define btnSELECT 4
  82. #define btnNONE   5
  83.  
  84. long baud_rates[] = {300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200};
  85. int selected_baud_rate = 5; // default = 5 (9600), maximum = 11
  86.  
  87. byte incoming_charCodes[128]; // This is an array for storing up to 128 incoming message characters.
  88. int incoming_index = 0; // the index into the above array (also indicates how many bytes have been received)
  89. int incoming_index_display = 0; // the index that is being displayed on screen #2
  90. bool incoming_limit_reached = false;
  91.  
  92. byte outgoing_charCodes[128]; // This is an array for storing up to 128 outgoing message characters.
  93. int outgoing_index = 0; // the index into the above array (also indicates how many bytes have been received)
  94. int outgoing_index_display = 0; // the index that is being displayed on screen #3
  95. bool outgoing_limit_reached = false;
  96.  
  97. bool monitor_enabled = false; // This is a switch to allow turning the monitoring functions on and off.
  98.  
  99. int screen_ID = 1; // the selected screen to view
  100. // 1 = set baud rate, 2 = view incoming messages, 3 = view outgoing messages
  101.  
  102. int button_debounce = 500; // the time in milliseconds to debounce the buttons
  103. unsigned long buttonPress_beginTime = 0;
  104. unsigned long buttonPress_currentTime = 0;
  105. bool buttons_enabled = true;
  106.  
  107. // function declarations
  108. void screen_draw();
  109. void start_button_debouncer();
  110. void reset_serialPort_speeds();
  111. void clear_LCD();
  112. int read_LCD_buttons();
  113. void screen1_buttonPressed();
  114. void screen1_draw();
  115. void screen2_buttonPressed();
  116. void screen2_draw();
  117. void screen3_buttonPressed();
  118. void screen3_draw();
  119. void screen4_buttonPressed();
  120. void screen4_draw();
  121.  
  122. void setup()
  123. {
  124.   lcd.begin(16, 2);              // start the library
  125.   Serial.begin(baud_rates[selected_baud_rate]);
  126.   mySerial.begin(baud_rates[selected_baud_rate]);
  127.  
  128.   // reset message
  129.   clear_LCD();
  130.   lcd.setCursor(0, 0);
  131.   lcd.print("Resetting...");
  132.   delay(1000);
  133.   // set menu on #1 and draw
  134.   screen_ID = 1;
  135.   screen1_draw();
  136. }
  137.  
  138.  
  139.  
  140. void loop() {
  141.   if (monitor_enabled == true) {
  142.     if (incoming_limit_reached == false) {
  143.       if (Serial.available()) {
  144.         // This is to catch incoming messages to the other Arduino board.
  145.         incoming_charCodes[incoming_index] = Serial.read();
  146.         incoming_index = incoming_index + 1;
  147.         if (incoming_index > 127) {
  148.           incoming_limit_reached = true;
  149.           // change to the screen to read incoming messages.
  150.           screen_ID = 2;
  151.           screen_draw();
  152.         }
  153.       }
  154.     }
  155.     if (outgoing_limit_reached == false) {
  156.       if (mySerial.available()) {
  157.         // This is to catch outgoing messages from the other Arduino board.
  158.         outgoing_charCodes[outgoing_index] = mySerial.read();
  159.         outgoing_index = outgoing_index + 1;
  160.         if (outgoing_index > 127) {
  161.           outgoing_limit_reached = true;
  162.           // change to the screen to read outgoing messages.
  163.           screen_ID = 3;
  164.           screen_draw();
  165.         }
  166.       }
  167.     }
  168.   }
  169.  
  170.   if (buttons_enabled == true) {
  171.     lcd_key = read_LCD_buttons();
  172.     if (lcd_key != btnNONE) {
  173.       switch (screen_ID) {
  174.         case 1:
  175.           screen1_buttonPressed();
  176.           break;
  177.         case 2:
  178.           screen2_buttonPressed();
  179.           break;
  180.         case 3:
  181.           screen3_buttonPressed();
  182.           break;
  183.         case 4:
  184.           screen4_buttonPressed();
  185.           break;
  186.       }
  187.       start_button_debouncer();
  188.     }
  189.   }
  190.   else {
  191.     buttonPress_currentTime = millis();
  192.     if (buttonPress_currentTime > buttonPress_beginTime) {
  193.       if (buttonPress_currentTime >= (buttonPress_beginTime + button_debounce)) {
  194.         buttons_enabled = true;
  195.       }
  196.     }
  197.     else {
  198.       buttonPress_beginTime = millis(); // rollover condition
  199.     }
  200.   }
  201. } // end of main loop
  202.  
  203. void screen_draw() {
  204.   switch (screen_ID) {
  205.     case 1:
  206.       screen1_draw();
  207.       break;
  208.     case 2:
  209.       screen2_draw();
  210.       break;
  211.     case 3:
  212.       screen3_draw();
  213.       break;
  214.     case 4:
  215.       screen4_draw();
  216.       break;
  217.   }
  218. }
  219.  
  220. void start_button_debouncer() {
  221.   buttonPress_beginTime = millis();
  222.   buttons_enabled = false;
  223. }
  224.  
  225. void reset_serialPort_speeds() {
  226.   Serial.end();
  227.   mySerial.end();
  228.   Serial.begin(baud_rates[selected_baud_rate]);
  229.   mySerial.begin(baud_rates[selected_baud_rate]);
  230. }
  231.  
  232. void clear_LCD() {
  233.   lcd.setCursor(0, 0);
  234.   lcd.print("                ");
  235.   lcd.setCursor(0, 1);
  236.   lcd.print("                ");
  237. }
  238.  
  239. // read the buttons
  240. int read_LCD_buttons()
  241. {
  242.   adc_key_in = analogRead(0);      // read the value from the sensor
  243.   // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  244.   // we add approx 50 to those values and check to see if we are close
  245.   if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  246.   // For V1.1 us this threshold
  247.   /*
  248.     if (adc_key_in < 50)   return btnRIGHT;
  249.     if (adc_key_in < 250)  return btnUP;
  250.     if (adc_key_in < 450)  return btnDOWN;
  251.     if (adc_key_in < 650)  return btnLEFT;
  252.     if (adc_key_in < 850)  return btnSELECT;
  253.   */
  254.   // For V1.0 comment the other threshold and use the one below:
  255.  
  256.   if (adc_key_in < 50)   return btnRIGHT;
  257.   if (adc_key_in < 195)  return btnUP;
  258.   if (adc_key_in < 380)  return btnDOWN;
  259.   if (adc_key_in < 555)  return btnLEFT;
  260.   if (adc_key_in < 790)  return btnSELECT;
  261.  
  262.   return btnNONE;  // when all others fail, return this...
  263. }
  264.  
  265. void screen1_buttonPressed() {
  266.   switch (lcd_key)
  267.   {
  268.     case btnUP:
  269.       // No function on screen #1.
  270.       break;
  271.     case btnDOWN:
  272.       // change to screen #2.
  273.       screen_ID = 2;
  274.       screen_draw();
  275.       break;
  276.     case btnRIGHT:
  277.       // set the baud rate one speed higher.
  278.       if (selected_baud_rate < 11) {
  279.         selected_baud_rate++;
  280.         reset_serialPort_speeds();
  281.         screen_draw();
  282.       }
  283.       break;
  284.     case btnLEFT:
  285.       // set the baud rate one speed lower.
  286.       if (selected_baud_rate > 0) {
  287.         selected_baud_rate--;
  288.         reset_serialPort_speeds();
  289.         screen_draw();
  290.       }
  291.       break;
  292.     case btnSELECT:
  293.       // no function on screen #1.
  294.       break;
  295.   }
  296. }
  297.  
  298. void screen1_draw() {
  299.   clear_LCD();
  300.   lcd.setCursor(0, 0);
  301.   lcd.print("Baud rate:");
  302.   lcd.setCursor(0, 1);
  303.   lcd.print(baud_rates[selected_baud_rate]);
  304. }
  305.  
  306. void screen2_buttonPressed() {
  307.   switch (lcd_key)
  308.   {
  309.     case btnUP:
  310.       // change to screen #1.
  311.       screen_ID = 1;
  312.       screen_draw();
  313.       break;
  314.     case btnDOWN:
  315.       // change to screen #3.
  316.       screen_ID = 3;
  317.       screen_draw();
  318.       break;
  319.     case btnRIGHT:
  320.       // set the incoming message character display one place higher.
  321.       if (incoming_index_display < 127) {
  322.         incoming_index_display++;
  323.         screen_draw();
  324.       }
  325.       break;
  326.     case btnLEFT:
  327.       // set the incoming message character display one place lower.
  328.       if (incoming_index_display > 0) {
  329.         incoming_index_display--;
  330.         screen_draw();
  331.       }
  332.       break;
  333.     case btnSELECT:
  334.       // clear out the incoming message display array.
  335.       for (int x = 0; x < 128; x++) {
  336.         incoming_charCodes[x] = 0;
  337.       }
  338.       incoming_limit_reached = false;
  339.       incoming_index = 0;
  340.       incoming_index_display = 0;
  341.       clear_LCD();
  342.       lcd.setCursor(0, 0);
  343.       lcd.print("inc message:");
  344.       lcd.setCursor(0, 1);
  345.       lcd.print("erasing");
  346.       delay(500);
  347.       screen_draw();
  348.  
  349.       break;
  350.   }
  351. }
  352.  
  353. void screen2_draw() {
  354.   clear_LCD();
  355.   lcd.setCursor(0, 0);
  356.   lcd.print("inc mess= ");
  357.   lcd.print(incoming_index);
  358.  
  359.   lcd.setCursor(0, 1);
  360.   lcd.print("#");
  361.   lcd.print(incoming_index_display);
  362.   lcd.print("=");
  363.   lcd.print(incoming_charCodes[incoming_index_display]);
  364.  
  365.   lcd.setCursor(8, 1);
  366.   lcd.print("[");
  367.   char myChar = incoming_charCodes[incoming_index_display];
  368.   lcd.print(myChar);
  369.   lcd.print("]");
  370. }
  371.  
  372. void screen3_buttonPressed() {
  373.   switch (lcd_key) {
  374.     case btnUP:
  375.       // change to screen #2.
  376.       screen_ID = 2;
  377.       screen_draw();
  378.       break;
  379.     case btnDOWN:
  380.       // change to screen #4.
  381.       screen_ID = 4;
  382.       screen_draw();
  383.       break;
  384.     case btnRIGHT:
  385.       // set the incoming message character display one place higher.
  386.       if (outgoing_index_display < 127) {
  387.         outgoing_index_display++;
  388.         screen_draw();
  389.       }
  390.       break;
  391.     case btnLEFT:
  392.       // set the incoming message character display one place lower.
  393.       if (outgoing_index_display > 0) {
  394.         outgoing_index_display--;
  395.         screen_draw();
  396.       }
  397.       break;
  398.     case btnSELECT:
  399.       // clear out the incoming message display array.
  400.       for (int x = 0; x < 128; x++) {
  401.         outgoing_charCodes[x] = 0;
  402.       }
  403.       outgoing_limit_reached = false;
  404.       outgoing_index = 0;
  405.       outgoing_index_display = 0;
  406.       clear_LCD();
  407.       lcd.setCursor(0, 0);
  408.       lcd.print("inc message:");
  409.       lcd.setCursor(0, 1);
  410.       lcd.print("erasing");
  411.       delay(500);
  412.       screen_draw();
  413.       break;
  414.   }
  415. }
  416.  
  417. void screen3_draw() {
  418.   clear_LCD();
  419.   lcd.setCursor(0, 0);
  420.   lcd.print("out mess= ");
  421.   lcd.print(outgoing_index);
  422.  
  423.   lcd.setCursor(0, 1);
  424.   lcd.print("#");
  425.   lcd.print(outgoing_index_display);
  426.   lcd.print("=");
  427.   lcd.print(outgoing_charCodes[outgoing_index_display]);
  428.  
  429.   lcd.setCursor(8, 1);
  430.   lcd.print("[");
  431.   char myChar = outgoing_charCodes[outgoing_index_display];
  432.   lcd.print(myChar);
  433.   lcd.print("]");
  434. }
  435.  
  436. void screen4_buttonPressed() {
  437.   switch (lcd_key) {
  438.     case btnUP:
  439.       // change to screen #3.
  440.       screen_ID = 3;
  441.       screen_draw();
  442.       break;
  443.     case btnDOWN:
  444.       // no function.
  445.       break;
  446.     case btnRIGHT:
  447.       // enable the message monitor.
  448.       monitor_enabled = true;
  449.       screen_draw();
  450.       break;
  451.     case btnLEFT:
  452.       // disable the message monitor.
  453.       monitor_enabled = false;
  454.       screen_draw();
  455.       break;
  456.     case btnSELECT:
  457.       // no function.
  458.       break;
  459.   }
  460. }
  461.  
  462. void screen4_draw() {
  463.   clear_LCD();
  464.   lcd.setCursor(0, 0);
  465.   lcd.print("monitor:");
  466.   lcd.setCursor(0, 1);
  467.   if (monitor_enabled == false) {
  468.     lcd.print("disabled");
  469.   }
  470.   else {
  471.     lcd.print("enabled");
  472.   }
  473. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement