gnea\grbl-Mega  1.0f
Source Code Documentation ( Internal Workings )
nuts_bolts.c
Go to the documentation of this file.
1 /*
2  nuts_bolts.c - Shared functions
3  Part of Grbl
4 
5  Copyright (c) 2011-2016 Sungeun K. Jeon for Gnea Research LLC
6  Copyright (c) 2009-2011 Simen Svale Skogsrud
7 
8  Grbl is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  Grbl is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with Grbl. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 #include "grbl.h"
23 
24 
25 #define MAX_INT_DIGITS 8
26 
27 // the avr-libc strtod() function by Michael Stumpf and Dmitry Xmelkov and many freely
29 // available conversion method examples, but has been highly optimized for Grbl. For known
30 // CNC applications, the typical decimal value is expected to be in the range of E0 to E-4.
31 // Scientific notation is officially not supported by g-code, and the 'E' character may
32 // be a g-code word on some CNC systems. So, 'E' notation will not be recognized.
33 //
35 uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr)
36 {
37  char *ptr = line + *char_counter;
38  unsigned char c;
39 
40 // Grab first character and increment pointer. No spaces assumed in line.
41  c = *ptr++;
42 
43 // Capture initial positive/minus character
44  bool isnegative = false;
45  if (c == '-') {
46  isnegative = true;
47  c = *ptr++;
48  } else if (c == '+') {
49  c = *ptr++;
50  }
51 
52 // Extract number into fast integer. Track decimal in terms of exponent value.
53  uint32_t intval = 0;
54  int8_t exp = 0;
55  uint8_t ndigit = 0;
56  bool isdecimal = false;
57  while(1) {
58  c -= '0';
59  if (c <= 9) {
60  ndigit++;
61  if (ndigit <= MAX_INT_DIGITS) {
62  if (isdecimal) { exp--; }
63  intval = (((intval << 2) + intval) << 1) + c;
64  } else {
65  if (!(isdecimal)) { exp++; }
66  }
67  } else if (c == (('.'-'0') & 0xff) && !(isdecimal)) {
68  isdecimal = true;
69  } else {
70  break;
71  }
72  c = *ptr++;
73  }
74 
75 // Return if no digits have been read.
76  if (!ndigit) { return(false); };
77 
78 // Convert integer into floating point.
79  float fval;
80  fval = (float)intval;
81 
82 // Apply decimal. Should perform no more than two floating point multiplications for the
83 // expected range of E0 to E-4.
84  if (fval != 0) {
85  while (exp <= -2) {
86  fval *= 0.01;
87  exp += 2;
88  }
89  if (exp < 0) {
90  fval *= 0.1;
91  } else if (exp > 0) {
92  do {
93  fval *= 10.0;
94  } while (--exp > 0);
95  }
96  }
97 
98 // Assign floating point value with correct sign.
99  if (isnegative) {
100  *float_ptr = -fval;
101  } else {
102  *float_ptr = fval;
103  }
104 
105  *char_counter = ptr - line - 1;
106 
107  return(true);
108 }
109 
111 void delay_sec(float seconds, uint8_t mode)
112 {
113  uint16_t i = ceil(1000/DWELL_TIME_STEP*seconds);
114  while (i-- > 0) {
115  if (sys.abort) { return; }
116  if (mode == DELAY_MODE_DWELL) {
118  } else {
121  if (sys.suspend & SUSPEND_RESTART_RETRACT) { return; }
122  }
123  _delay_ms(DWELL_TIME_STEP);
124  }
125 }
126 
128 // which only accepts constants in future compiler releases.
129 void delay_ms(uint16_t ms)
130 {
131  while ( ms-- ) { _delay_ms(1); }
132 }
133 
135 // which only accepts constants in future compiler releases. Written to perform more
136 // efficiently with larger delays, as the counter adds parasitic time in each iteration.
137 void delay_us(uint32_t us)
138 {
139  while (us) {
140  if (us < 10) {
141  _delay_us(1);
142  us--;
143  } else if (us < 100) {
144  _delay_us(10);
145  us -= 10;
146  } else if (us < 1000) {
147  _delay_us(100);
148  us -= 100;
149  } else {
150  _delay_ms(1);
151  us -= 1000;
152  }
153  }
154 }
155 
157 float hypot_f(float x, float y) { return(sqrt(x*x + y*y)); }
158 
159 
161 {
162  uint8_t idx;
163  float magnitude = 0.0;
164  for (idx=0; idx<N_AXIS; idx++) {
165  if (vector[idx] != 0.0) {
166  magnitude += vector[idx]*vector[idx];
167  }
168  }
169  magnitude = sqrt(magnitude);
170  float inv_magnitude = 1.0/magnitude;
171  for (idx=0; idx<N_AXIS; idx++) { vector[idx] *= inv_magnitude; }
172  return(magnitude);
173 }
174 
175 
176 float limit_value_by_axis_maximum(float *max_value, float *unit_vec)
177 {
178  uint8_t idx;
179  float limit_value = SOME_LARGE_VALUE;
180  for (idx=0; idx<N_AXIS; idx++) {
181  if (unit_vec[idx] != 0) {
182  limit_value = min(limit_value,fabs(max_value[idx]/unit_vec[idx]));
183  }
184  }
185  return(limit_value);
186 }
#define N_AXIS
Axis array index values. Must start with 0 and be continuous.
Definition: nuts_bolts.h:30
void delay_sec(float seconds, uint8_t mode)
Non-blocking delay function used for general operation and suspend features.
Definition: nuts_bolts.c:111
uint8_t read_float(char *line, uint8_t *char_counter, float *float_ptr)
Extracts a floating point value from a string. The following code is based loosely on...
Definition: nuts_bolts.c:35
void delay_us(uint32_t us)
Delays variable defined microseconds. Compiler compatibility fix for _delay_us(),.
Definition: nuts_bolts.c:137
#define DWELL_TIME_STEP
Time delay increments performed during a dwell. The default value is set at 50ms, which provides...
Definition: config.h:352
uint8_t suspend
System suspend bitflag variable that manages holds, cancels, and safety door.
Definition: system.h:114
float convert_delta_vector_to_unit_vector(float *vector)
Definition: nuts_bolts.c:160
#define SUSPEND_RESTART_RETRACT
Flag to indicate a retract from a restore parking motion.
Definition: system.h:84
#define DELAY_MODE_DWELL
Definition: nuts_bolts.h:47
uint8_t abort
System abort flag. Forces exit back to main loop for reset.
Definition: system.h:113
float limit_value_by_axis_maximum(float *max_value, float *unit_vec)
Definition: nuts_bolts.c:176
system_t sys
Declare system global variable structure.
Definition: main.c:25
#define MAX_INT_DIGITS
Maximum number of digits in int32 (and float)
Definition: nuts_bolts.c:25
void protocol_exec_rt_system()
Executes run-time commands, when required. This function primarily operates as Grbl's state...
Definition: protocol.c:223
float hypot_f(float x, float y)
Simple hypotenuse computation function.
Definition: nuts_bolts.c:157
#define min(a, b)
Definition: nuts_bolts.h:54
void protocol_execute_realtime()
This function is the general interface to Grbl's real-time command execution system. It is called.
Definition: protocol.c:213
void delay_ms(uint16_t ms)
Delays variable defined milliseconds. Compiler compatibility fix for _delay_ms(),.
Definition: nuts_bolts.c:129
#define SOME_LARGE_VALUE
Definition: nuts_bolts.h:28