Sergey Pastor / grbl1
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers print.c Source File

print.c

00001 /*
00002   print.c - Functions for formatting output strings
00003   Part of Grbl
00004 
00005   Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
00006   Copyright (c) 2009-2011 Simen Svale Skogsrud
00007 
00008   Grbl is free software: you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation, either version 3 of the License, or
00011   (at your option) any later version.
00012 
00013   Grbl is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016   GNU General Public License for more details.
00017 
00018   You should have received a copy of the GNU General Public License
00019   along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
00020 */
00021 
00022 #include "grbl.h"
00023 
00024 
00025 void printString(const char *s)
00026 {
00027   while (*s)
00028     serial_write(*s++);
00029 }
00030 
00031 #ifdef AVRTARGET
00032 // Print a string stored in PGM-memory
00033 void printPgmString(const char *s)
00034 {
00035   char c;
00036   while ((c = pgm_read_byte_near(s++)))
00037     serial_write(c);
00038 }
00039 #endif
00040 
00041 // void printIntegerInBase(unsigned long n, unsigned long base)
00042 // {
00043 //  unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
00044 //  unsigned long i = 0;
00045 //
00046 //  if (n == 0) {
00047 //      serial_write('0');
00048 //      return;
00049 //  }
00050 //
00051 //  while (n > 0) {
00052 //      buf[i++] = n % base;
00053 //      n /= base;
00054 //  }
00055 //
00056 //  for (; i > 0; i--)
00057 //      serial_write(buf[i - 1] < 10 ?
00058 //          '0' + buf[i - 1] :
00059 //          'A' + buf[i - 1] - 10);
00060 // }
00061 
00062 
00063 // Prints an uint8 variable in base 10.
00064 void print_uint8_base10(uint8_t n)
00065 {
00066   uint8_t digit_a = 0;
00067   uint8_t digit_b = 0;
00068   if (n >= 100) { // 100-255
00069     digit_a = '0' + n % 10;
00070     n /= 10;
00071   }
00072   if (n >= 10) { // 10-99
00073     digit_b = '0' + n % 10;
00074     n /= 10;
00075   }
00076   serial_write('0' + n);
00077   if (digit_b) { serial_write(digit_b); }
00078   if (digit_a) { serial_write(digit_a); }
00079 }
00080 
00081 
00082 // Prints an uint8 variable in base 2 with desired number of desired digits.
00083 void print_uint8_base2_ndigit(uint8_t n, uint8_t digits) {
00084 #if defined(AVRTARGET) || defined(STM32F103C8)
00085     unsigned char buf[digits];
00086 #endif
00087 #ifdef WIN32
00088     unsigned char buf[20];
00089 #endif
00090   uint8_t i = 0;
00091 
00092   for (; i < digits; i++) {
00093       buf[i] = n % 2 ;
00094       n /= 2;
00095   }
00096 
00097   for (; i > 0; i--)
00098       serial_write('0' + buf[i - 1]);
00099 }
00100 
00101 
00102 void print_uint32_base10(uint32_t n)
00103 {
00104   if (n == 0) {
00105     serial_write('0');
00106     return;
00107   }
00108 
00109   unsigned char buf[10];
00110   uint8_t i = 0;
00111 
00112   while (n > 0) {
00113     buf[i++] = n % 10;
00114     n /= 10;
00115   }
00116 
00117   for (; i > 0; i--)
00118     serial_write('0' + buf[i-1]);
00119 }
00120 
00121 
00122 void printInteger(long n)
00123 {
00124   if (n < 0) {
00125     serial_write('-');
00126     print_uint32_base10(-n);
00127   } else {
00128     print_uint32_base10(n);
00129   }
00130 }
00131 
00132 
00133 // Convert float to string by immediately converting to a long integer, which contains
00134 // more digits than a float. Number of decimal places, which are tracked by a counter,
00135 // may be set by the user. The integer is then efficiently converted to a string.
00136 // NOTE: AVR '%' and '/' integer operations are very efficient. Bitshifting speed-up
00137 // techniques are actually just slightly slower. Found this out the hard way.
00138 void printFloat(float n, uint8_t decimal_places)
00139 {
00140   if (n < 0) {
00141     serial_write('-');
00142     n = -n;
00143   }
00144 
00145   uint8_t decimals = decimal_places;
00146   while (decimals >= 2) { // Quickly convert values expected to be E0 to E-4.
00147     n *= 100;
00148     decimals -= 2;
00149   }
00150   if (decimals) { n *= 10; }
00151   n += 0.5; // Add rounding factor. Ensures carryover through entire value.
00152 
00153   // Generate digits backwards and store in string.
00154   unsigned char buf[13];
00155   uint8_t i = 0;
00156   uint32_t a = (long)n;
00157   while(a > 0) {
00158     buf[i++] = (a % 10) + '0'; // Get digit
00159     a /= 10;
00160   }
00161   while (i < decimal_places) {
00162      buf[i++] = '0'; // Fill in zeros to decimal point for (n < 1)
00163   }
00164   if (i == decimal_places) { // Fill in leading zero, if needed.
00165     buf[i++] = '0';
00166   }
00167 
00168   // Print the generated string.
00169   for (; i > 0; i--) {
00170     if (i == decimal_places) { serial_write('.'); } // Insert decimal point in right place.
00171     serial_write(buf[i-1]);
00172   }
00173 }
00174 
00175 
00176 // Floating value printing handlers for special variables types used in Grbl and are defined
00177 // in the config.h.
00178 //  - CoordValue: Handles all position or coordinate values in inches or mm reporting.
00179 //  - RateValue: Handles feed rate and current velocity in inches or mm reporting.
00180 void printFloat_CoordValue(float n) {
00181   if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
00182     printFloat(n*INCH_PER_MM,N_DECIMAL_COORDVALUE_INCH);
00183   } else {
00184     printFloat(n,N_DECIMAL_COORDVALUE_MM);
00185   }
00186 }
00187 
00188 void printFloat_RateValue(float n) {
00189   if (bit_istrue(settings.flags,BITFLAG_REPORT_INCHES)) {
00190     printFloat(n*INCH_PER_MM,N_DECIMAL_RATEVALUE_INCH);
00191   } else {
00192     printFloat(n,N_DECIMAL_RATEVALUE_MM);
00193   }
00194 }
00195 
00196 // Debug tool to print free memory in bytes at the called point.
00197 // NOTE: Keep commented unless using. Part of this function always gets compiled in.
00198 // void printFreeMemory()
00199 // {
00200 //   extern int __heap_start, *__brkval;
00201 //   uint16_t free;  // Up to 64k values.
00202 //   free = (int) &free - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
00203 //   printInteger((int32_t)free);
00204 //   printString(" ");
00205 // }