Advertisement
ripred

IDE_Plotter.ino

Sep 19th, 2023 (edited)
927
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.17 KB | Source Code | 0 0
  1. /*
  2.  * IDE_Plotter_v2.ino
  3.  *
  4.  * library of functions to make displaying multiple data in the Arduino IDE Plotter easier
  5.  *
  6.  * version 1.0 - September 2023 - Trent M. Wyatt
  7.  *
  8.  */
  9. #include <Stream.h>
  10. #include <String.h>
  11.  
  12. #define   NUM_GROUPS   3
  13. #define   NUM_VALUES   3
  14. #define   MAX_TITLE    16
  15.  
  16. #define   ARRAYSZ(A)   (sizeof(A) / sizeof(*(A)))
  17.  
  18. typedef int type_t;
  19.  
  20. struct group_t {
  21.     type_t    values[NUM_VALUES];
  22.     char      titles[NUM_VALUES][MAX_TITLE];
  23.     int       max_val;
  24.     uint8_t   count;
  25.     uint8_t   overlay : 1,
  26.                unused : 7;
  27.  
  28.     group_t() :
  29.         max_val(256),
  30.         count(0),
  31.         overlay(true)
  32.     {
  33.         for (type_t &t : values) {
  34.             t = 0;
  35.         }
  36.     }
  37.  
  38.     group_t(uint16_t max) :
  39.         max_val(max),
  40.         count(0),
  41.         overlay(true)
  42.     {
  43.         for (type_t &t : values) {
  44.             t = 0;
  45.         }
  46.     }
  47.  
  48.     bool create(char const * const names[], int const num) {
  49.         if (num > NUM_VALUES) { return false; }
  50.  
  51.         for (int index=0; index < num; index++) {
  52.             strncpy(titles[index], names[index], MAX_TITLE);
  53.         }
  54.         count = num;
  55.         return true;
  56.     }
  57.  
  58.     void set(uint8_t const index, type_t const value) {
  59.         values[index] = value;
  60.     }
  61.  
  62.     type_t get(uint8_t const index) const {
  63.         return values[index];
  64.     }
  65.  
  66. };  // struct group_t
  67.  
  68.  
  69. struct plotter_t {
  70.     Stream *stream;
  71.     group_t  groups[NUM_GROUPS];
  72.     uint8_t  count;
  73.  
  74.     plotter_t(Stream &serial) : stream(&serial), count(0)
  75.     {
  76.     }
  77.  
  78.     void set_groups(int const size, group_t *init=nullptr) {
  79.         count = size;
  80.  
  81.         if (init) {
  82.             for (int i=0; i < size; i++) {
  83.                 groups[i] = init[i];
  84.             }
  85.         }
  86.     }
  87.  
  88.     bool create(int const group, char const *names[], int const num) {
  89.         if (num > NUM_VALUES) { return false; }
  90.  
  91.         groups[group].create(names, num);
  92.  
  93.         return true;
  94.     }
  95.  
  96.     void set(int const group, uint8_t const index, type_t const value) {
  97.         groups[group].set(index, value);
  98.     }
  99.  
  100.     type_t get(int const group, uint8_t const index) const {
  101.         return groups[group].get(index);
  102.     }
  103.  
  104.     void begin() const
  105.     {
  106.         if (nullptr == stream) { return; }
  107.         Stream &out = *stream;
  108.         while (out.available()) { out.read(); }
  109.         out.write('\n');
  110.         for (int group=0; group < count; group++) {
  111.             for (int which=0; which < groups[group].count; which++) {
  112.                 out.print(groups[group].titles[which]);
  113.                 out.write(',');
  114.             }
  115.         }
  116.         out.write('\n');
  117.     }
  118.  
  119.     void update() const
  120.     {
  121.         if (nullptr == stream) { return; }
  122.        
  123.         Stream &out = *stream;
  124.         long top = 0;
  125.        
  126.         int min_vres = 256;
  127.  
  128.         top += min_vres / 2;    // bottom band
  129.        
  130.         // inter-group vertical separation
  131.         int const vsep = min_vres + (min_vres / 8);
  132.  
  133.         for (int group=0; group < count; group++) {
  134.             for (int which=0; which < groups[group].count; which++) {
  135.                 out.print(groups[group].values[which] + top, DEC);
  136.                 out.write(',');
  137.                
  138.                 if (!groups[group].overlay && (which < (groups[group].count - 1))) {
  139.                     // inter-group vertical separation
  140.                     top += vsep;
  141.                 }
  142.             }
  143.            
  144.             int const gvsep = min_vres + min_vres / 2;
  145.             top += gvsep;
  146.         }
  147.        
  148.         out.write('\n');
  149.     }
  150.  
  151. }; // struct plotter_t
  152.  
  153.  
  154. static double const pi = 3.1415927;
  155. static double const rad = pi / 2.0;
  156. static double const inc1 = 0.075;
  157. static double const inc2 = 0.1;
  158.  
  159. double f1 = 0.0;
  160. double f2 = 0.0;
  161. bool count_up1 = true;
  162. bool count_up2 = true;
  163.  
  164. int values[NUM_GROUPS][NUM_VALUES];
  165.  
  166. plotter_t plotter(Serial);
  167.  
  168. void setup() {
  169.     Serial.begin(115200);
  170.     while (!Serial);
  171.  
  172.     delay(1500);
  173.  
  174.     plotter.set_groups(NUM_GROUPS);
  175.  
  176.     char const *names1[] = { "analog1", "analog2" };
  177.     plotter.create(0, names1, ARRAYSZ(names1));
  178.  
  179.     char const *names2[] = { "digital1", "digital2", "clock" };
  180.     plotter.create(1, names2, ARRAYSZ(names2));
  181.     plotter.groups[1].overlay = false;
  182.  
  183.     char const *names3[] = { "signal1" };
  184.     plotter.create(2, names3, ARRAYSZ(names3));
  185.  
  186.     plotter.begin();
  187.  
  188.     randomSeed(analogRead(A0) + analogRead(A2));
  189. }
  190.  
  191.  
  192. void loop() {
  193.     static uint8_t digitalPass = 0;
  194.     static bool climb = true;
  195.  
  196.     for (int group=0; group < NUM_GROUPS; group++) {
  197.         switch (group) {
  198.             default:
  199.             break;
  200.  
  201.             // some analog values
  202.             case 0:
  203.             for (int which=0; which < plotter.groups[group].count; which++) {
  204.                 switch (which) {
  205.                     case 0:
  206.                     {
  207.                         type_t &value = values[group][which];
  208.                         int const inc_amt = plotter.groups[group].max_val / 32;
  209.  
  210.                         plotter.set(group, which, value);
  211.  
  212.                         if (climb) {
  213.                             if (value + inc_amt >= plotter.groups[group].max_val) {
  214.                                 climb = !climb;
  215.                             }
  216.                         } else {
  217.                             if (value - inc_amt <= 0) {
  218.                                 climb = !climb;
  219.                             }
  220.                         }
  221.  
  222.                         value += climb ? +inc_amt : -inc_amt;
  223.                     }
  224.                     break;
  225.    
  226.                     case 1:
  227.                     values[group][which] = (plotter.groups[group].max_val - 1) - values[group][0];
  228.                     plotter.set(group, which, values[group][which]);
  229.                     break;
  230.  
  231.                     case 2:
  232.                     if (((f1 + inc1) >= rad) || ((f1 - inc1) < -rad)) {
  233.                         count_up1 = !count_up1;
  234.                     }
  235.                     f1 += count_up1 ? +inc1 : -inc1;
  236. //                    f1 = -rad + ((pi / (plotter.min_vres / 2)) * values[group][0]);
  237.                     values[group][which] = (1.0 + sin(f1)) * (plotter.groups[group].max_val / 2);
  238.                     plotter.set(group, which, values[group][which]);
  239.                     break;
  240.                 }
  241.             }
  242.             break;
  243.  
  244.             // some digital values
  245.             case 1:
  246.             if (digitalPass == 0) {
  247.                 for (int which=0; which < plotter.groups[group].count - 1; which++) {
  248.                     values[group][which] = random(0, 2) ? plotter.groups[group].max_val : 0;
  249.                     plotter.set(group, which, values[group][which]);
  250.                 }
  251.                
  252.                 // make the last one (first displayed) a clock that just toggles back and forth:
  253.                 if (values[group][plotter.groups[group].count - 1] == 0) {
  254.                   values[group][plotter.groups[group].count - 1] = plotter.groups[group].max_val;
  255.                   plotter.set(group, plotter.groups[group].count - 1, values[group][plotter.groups[group].count - 1]);
  256.                 }
  257.                 else {
  258.                   values[group][plotter.groups[group].count - 1] = 0;
  259.                   plotter.set(group, plotter.groups[group].count - 1, values[group][plotter.groups[group].count - 1]);
  260.                 }
  261.             }
  262.             ++digitalPass %= 8;
  263.             break;
  264.  
  265.             case 2:
  266.             for (int which=0; which < plotter.groups[group].count; which++) {
  267.                 switch (which) {
  268.                     case 0:
  269.                     if (((f2 + inc2) >= rad) || ((f2 - inc2) < -rad)) {
  270.                         count_up2 = !count_up2;
  271.                     }
  272.                     f2 += count_up2 ? +inc2 : -inc2;
  273. //                    f2 = -rad + ((pi / (plotter.min_vres / 2)) * values[group][1]);
  274.                     values[group][which] = (1.0 + sin(f2)) * (plotter.groups[group].max_val / 2);
  275.                     plotter.set(group, which, values[group][which]);
  276.                     break;
  277.  
  278.                     case 1:
  279.                     {
  280.                         type_t &value = values[group][which];
  281.                         int const inc_amt = plotter.groups[group].max_val / 16;
  282.  
  283.                         plotter.set(group, which, value);
  284.  
  285.                         if (climb) {
  286.                             if (value + inc_amt >= plotter.groups[group].max_val) {
  287.                                 climb = !climb;
  288.                             }
  289.                         } else {
  290.                             if (value - inc_amt <= 0) {
  291.                                 climb = !climb;
  292.                             }
  293.                         }
  294.  
  295.                         value += climb ? +inc_amt : -inc_amt;
  296.                     }
  297.                     break;
  298.    
  299.                     case 2:
  300.                     values[group][which] = (plotter.groups[group].max_val - 1) - values[group][1];
  301.                     plotter.set(group, which, values[group][which]);
  302.                     break;
  303.                 }
  304.             }
  305.             break;
  306.         }
  307.     }
  308.  
  309.     plotter.update();
  310.  
  311.     delay(20);
  312. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement