1#!/usr/local/bin/python3.8
2'''
3This script reads/writes egv format
4
5Copyright (C) 2017-2020 Scorch www.scorchworks.com
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20'''
21
22import sys
23import struct
24import os
25from shutil import copyfile
26from math import *
27from interpolate import interpolate
28from time import time
29from LaserSpeed import LaserSpeed
30
31##############################################################################
32class egv:
33    def __init__(self, target=lambda s: sys.stdout.write(s)):
34        self.write = target
35        self.Modal_dir  = 0
36        self.Modal_dist = 0
37        self.Modal_on   = False
38        self.Modal_AX   = 0
39        self.Modal_AY   = 0
40
41        self.RIGHT = 66 #ord("B")=66
42        self.LEFT  = 84 #ord("T")=84
43        self.UP    = 76 #ord("L")=76
44        self.DOWN  = 82 #ord("R")=82
45        self.ANGLE = 77 #ord("M")=77
46        self.ON    = 68 #ord("D")=68
47        self.OFF   = 85 #ord("U")=85
48
49        # % Yxtart % Xstart % Yend % Xend % I % C VXXXXXXX CUT_TYPE
50        #
51        # %Ystart_pos %Xstart_pos %Yend_pos %Xend_pos  (start pos is the location of the head before the code is run)
52        # I is always I ?
53        # C is C for cutting or Marking otherwise it is omitted
54        # V is the start of 7 digits indicating the feed rate 255 255 1
55        # CUT_TYPE cutting/marking, Engraving=G followed by the raster step in thousandths of an inch
56
57    def move(self,direction,distance,laser_on=False,angle_dirs=None):
58
59        if angle_dirs==None:
60            angle_dirs = [self.Modal_AX,self.Modal_AY]
61
62        if direction == self.Modal_dir         \
63            and laser_on == self.Modal_on      \
64            and angle_dirs[0] == self.Modal_AX \
65            and angle_dirs[1] == self.Modal_AY:
66            self.Modal_dist = self.Modal_dist + distance
67
68        else:
69            self.flush()
70            if laser_on != self.Modal_on:
71                if laser_on:
72                    self.write(self.ON)
73                else:
74                    self.write(self.OFF)
75                self.Modal_on = laser_on
76
77            if direction == self.ANGLE:
78                if angle_dirs[0]!=self.Modal_AX:
79                    self.write(angle_dirs[0])
80                    self.Modal_AX = angle_dirs[0]
81                if angle_dirs[1]!=self.Modal_AY:
82                    self.write(angle_dirs[1])
83                    self.Modal_AY = angle_dirs[1]
84
85            self.Modal_dir  = direction
86            self.Modal_dist = distance
87
88            if direction == self.RIGHT or direction == self.LEFT:
89                self.Modal_AX = direction
90            if direction == self.UP or direction == self.DOWN:
91                self.Modal_AY = direction
92
93
94    def flush(self,laser_on=None):
95        if self.Modal_dist > 0:
96            self.write(self.Modal_dir)
97            for code in self.make_distance(self.Modal_dist):
98                self.write(code)
99        if (laser_on!=None) and (laser_on!=self.Modal_on):
100            if laser_on:
101                self.write(self.ON)
102            else:
103                self.write(self.OFF)
104            self.Modal_on   = laser_on
105        self.Modal_dist = 0
106
107
108    #  The one wire CRC algorithm is derived from the OneWire.cpp Library
109    #  The library location: http://www.pjrc.com/teensy/td_libs_OneWire.html
110    def OneWireCRC(self,line):
111        crc=0
112        for i in range(len(line)):
113            inbyte=line[i]
114            for j in range(8):
115                mix = (crc ^ inbyte) & 0x01
116                crc >>= 1
117                if (mix):
118                    crc ^= 0x8C
119                inbyte >>= 1
120        return crcS
121
122
123    def make_distance(self,dist_mils):
124        dist_mils=float(dist_mils)
125        if abs(dist_mils-round(dist_mils,0)) > 0.000001:
126            raise Exception('Distance values should be integer value (inches*1000)')
127        DIST=0.0
128        code = []
129        v122 = 255
130        dist_milsA = int(dist_mils)
131
132        for i in range(0,int(floor(dist_mils/v122))):
133            code.append(122)
134            dist_milsA = dist_milsA-v122
135            DIST = DIST+v122
136        if dist_milsA==0:
137            pass
138        elif dist_milsA < 26:  # codes  "a" through  "y"
139            code.append(96+dist_milsA)
140        elif dist_milsA < 52:  # codes "|a" through "|z"
141            code.append(124)
142            code.append(96+dist_milsA-25)
143        elif dist_milsA < 255:
144            num_str =  "%03d" %(int(round(dist_milsA)))
145            code.append(ord(num_str[0]))
146            code.append(ord(num_str[1]))
147            code.append(ord(num_str[2]))
148        else:
149            raise Exception("Error in EGV make_distance_in(): dist_milsA=",dist_milsA)
150        return code
151
152    def make_dir_dist(self,dxmils,dymils,laser_on=False):
153        adx = abs(dxmils)
154        ady = abs(dymils)
155        if adx > 0 or ady > 0:
156            if ady > 0:
157                if dymils > 0:
158                    self.move(self.UP  ,ady,laser_on)
159                else:
160                    self.move(self.DOWN,ady,laser_on)
161            if adx > 0:
162                if dxmils > 0:
163                    self.move(self.RIGHT,adx,laser_on)
164                else:
165                    self.move(self.LEFT ,adx,laser_on)
166
167    def make_cut_line(self,dxmils,dymils,Spindle):
168        XCODE = self.RIGHT
169        if dxmils < 0.0:
170            XCODE = self.LEFT
171        YCODE = self.UP
172        if dymils < 0.0:
173            YCODE = self.DOWN
174
175        if abs(dxmils-round(dxmils,0)) > 0.0 or abs(dymils-round(dymils,0)) > 0.0:
176            raise Exception('Distance values should be integer value (inches*1000)')
177
178        adx = abs(dxmils/1000.0)
179        ady = abs(dymils/1000.0)
180
181        if dxmils == 0:
182            self.move(YCODE,abs(dymils),laser_on=Spindle)
183        elif dymils == 0:
184            self.move(XCODE,abs(dxmils),laser_on=Spindle)
185        elif dxmils==dymils:
186            self.move(self.ANGLE,abs(dxmils),laser_on=Spindle,angle_dirs=[XCODE,YCODE])
187        else:
188            h=[]
189            if adx > ady:
190                slope = ady/adx
191                n = int(abs(dxmils))
192                CODE  = XCODE
193                CODE1 = YCODE
194            else:
195                slope = adx/ady
196                n = int(abs(dymils))
197                CODE  = YCODE
198                CODE1 = XCODE
199
200            for i in range(1,n+1):
201                h.append(round(i*slope,0))
202
203            Lh=0.0
204            d1=0.0
205            d2=0.0
206            d1cnt=0.0
207            d2cnt=0.0
208            for i in range(len(h)):
209                if h[i]==Lh:
210                    d1=d1+1
211                    if d2>0.0:
212                        self.move(self.ANGLE,d2,laser_on=Spindle,angle_dirs=[XCODE,YCODE])
213                        d2cnt=d2cnt+d2
214                        d2=0.0
215                else:
216                    d2=d2+1
217                    if d1>0.0:
218                        self.move(CODE,d1,laser_on=Spindle)
219                        d1cnt=d1cnt+d1
220                        d1=0.0
221                Lh=h[i]
222
223            if d1>0.0:
224                self.move(CODE,d1,laser_on=Spindle)
225                d1cnt=d1cnt+d1
226                d1=0.0
227            if d2>0.0:
228                self.move(self.ANGLE,d2,laser_on=Spindle,angle_dirs=[XCODE,YCODE])
229                d2cnt=d2cnt+d2
230                d2=0.0
231
232
233            DX = d2cnt
234            DY = (d1cnt+d2cnt)
235            if adx < ady:
236                error = max(DX-abs(dxmils),DY-abs(dymils))
237            else:
238                error = max(DY-abs(dxmils),DX-abs(dymils))
239            if error > 0:
240                raise Exception("egv.py: Error delta =%f" %(error))
241
242
243    def make_speed(self,Feed=None,board_name="LASER-M2",Raster_step=0):
244        board_code = board_name.split('-')[1]
245        speed_text = LaserSpeed.get_code_from_speed(Feed, abs(Raster_step), board=board_code)
246
247        speed=[]
248        for c in speed_text:
249            speed.append(ord(c))
250        return speed
251
252
253    def make_move_data(self,dxmils,dymils):
254        if (abs(dxmils)+abs(dymils)) > 0:
255            self.write(73) # I
256            self.make_dir_dist(dxmils,dymils)
257            self.flush()
258            self.write(83) #S
259            self.write(49) #1 (one)
260            self.write(80) #P
261
262    #######################################################################
263    def none_function(self,dummy=None):
264        #Don't delete this function (used in make_egv_data)
265        pass
266
267    def ecoord_adj(self,ecoords_adj_in,scale,FlipXoffset):
268        if FlipXoffset > 0:
269            e0 = int(round((FlipXoffset-ecoords_adj_in[0])*scale,0))
270        else:
271            e0 = int(round(ecoords_adj_in[0]*scale,0))
272        e1 = int(round(ecoords_adj_in[1]*scale,0))
273        e2 = ecoords_adj_in[2]
274        return e0,e1,e2
275
276
277    def make_egv_data(self, ecoords_in,
278                            startX=0,
279                            startY=0,
280                            units = 'in',
281                            Feed = None,
282                            board_name="LASER-M2",
283                            Raster_step=0,
284                            update_gui=None,
285                            stop_calc=None,
286                            FlipXoffset=0,
287                            Rapid_Feed_Rate=0,
288                            use_laser=True):
289
290        #print("make_egv_data",Rapid_Feed_Rate,len(ecoords_in))
291        #print("Rapid_Feed_Rate=",Rapid_Feed_Rate)
292        ########################################################
293        if stop_calc == None:
294            stop_calc=[]
295            stop_calc.append(0)
296        if update_gui == None:
297            update_gui = self.none_function
298        ########################################################
299        if units == 'in':
300            scale      = 1000.0
301        if units == 'mm':
302            scale = 1000.0/25.4;
303
304        startX = int(round(startX*scale,0))
305        startY = int(round(startY*scale,0))
306
307        ########################################################
308        variable_feed_scale=None
309        Spindle = True and use_laser
310        if Feed==None:
311            variable_feed_scale = 25.4/60.0
312            Feed = round(ecoords_in[0][3]*variable_feed_scale,2)
313            Spindle = False
314
315        speed = self.make_speed(Feed,board_name=board_name,Raster_step=Raster_step)
316
317        ##self.write(ord("I"))
318        #for code in speed:
319        #    self.write(code)
320
321        if Raster_step==0:
322            #self.write(ord("I"))
323            for code in speed:
324                self.write(code)
325
326            lastx,lasty,last_loop = self.ecoord_adj(ecoords_in[0],scale,FlipXoffset)
327            if not Rapid_Feed_Rate:
328                self.make_dir_dist(lastx-startX,lasty-startY)
329
330            self.flush(laser_on=False)
331            self.write(ord("N"))
332            if lasty-startY <= 0:
333                self.write(self.DOWN)
334            else:
335                self.write(self.UP)
336
337            if lastx-startX >= 0:
338                self.write(self.RIGHT)
339            else:
340                self.write(self.LEFT)
341
342            # Insert "S1E"
343            self.write(ord("S"))
344            self.write(ord("1"))
345            self.write(ord("E"))
346            ###########################################################
347            laser   = False
348
349            if Rapid_Feed_Rate:
350                self.rapid_move_slow(lastx-startX,lasty-startY,Rapid_Feed_Rate,Feed,board_name)
351            timestamp=0
352            for i in range(1,len(ecoords_in)):
353                e0,e1,e2                = self.ecoord_adj(ecoords_in[i]  ,scale,FlipXoffset)
354                stamp=int(3*time()) #update every 1/3 of a second
355                if (stamp != timestamp):
356                    timestamp=stamp #interlock
357                    update_gui("Generating EGV Data: %.1f%%" %(100.0*float(i)/float(len(ecoords_in))))
358                    if stop_calc[0]==True:
359                        raise Exception("Action Stopped by User.")
360
361                if ( e2  == last_loop) and (not laser):
362                    laser = True
363                elif ( e2  != last_loop) and (laser):
364                    laser = False
365                dx = e0 - lastx
366                dy = e1 - lasty
367
368                min_rapid = 5
369                if (abs(dx)+abs(dy))>0:
370                    if laser:
371                        if variable_feed_scale!=None:
372                            Feed_current    = round(ecoords_in[i][3]*variable_feed_scale,2)
373                            Spindle = ecoords_in[i][4] > 0 and use_laser
374                            if Feed != Feed_current:
375                                Feed = Feed_current
376                                self.flush()
377                                self.change_speed(Feed,board_name,laser_on=Spindle)
378                        self.make_cut_line(dx,dy,Spindle)
379                    else:
380                        if ((abs(dx) < min_rapid) and (abs(dy) < min_rapid)) or Rapid_Feed_Rate:
381                            self.rapid_move_slow(dx,dy,Rapid_Feed_Rate,Feed,board_name)
382                        else:
383                            self.rapid_move_fast(dx,dy)
384
385                lastx     = e0
386                lasty     = e1
387                last_loop = e2
388
389            if laser:
390                laser = False
391
392            dx = startX-lastx
393            dy = startY-lasty
394            if ((abs(dx) < min_rapid) and (abs(dy) < min_rapid)) or Rapid_Feed_Rate:
395                self.rapid_move_slow(dx,dy,Rapid_Feed_Rate,Feed,board_name)
396            else:
397                self.rapid_move_fast(dx,dy)
398
399              ###########################################################
400        else: # Raster
401              ###########################################################
402            Rapid_flag=True
403            ###################################################
404            scanline = []
405            scanline_y = None
406            if Raster_step < 0.0:
407                irange = range(len(ecoords_in))
408            else:
409                irange = range(len(ecoords_in)-1,-1,-1)
410            timestamp=0
411            for i in irange:
412                #if i%1000 == 0:
413                stamp=int(3*time()) #update every 1/3 of a second
414                if (stamp != timestamp):
415                    timestamp=stamp #interlock
416                    update_gui("Preprocessing Raster Data: %.1f%%" %(100.0*float(i)/float(len(ecoords_in))))
417                y    = ecoords_in[i][1]
418                if y != scanline_y:
419                    scanline.append([ecoords_in[i]])
420                    scanline_y = y
421                else:
422                    if bool(FlipXoffset) ^ bool(Raster_step > 0.0): # ^ is bitwise XOR
423                        scanline[-1].insert(0,ecoords_in[i])
424                    else:
425                        scanline[-1].append(ecoords_in[i])
426            update_gui("Raster Data Ready")
427            ###################################################
428            lastx,lasty,last_loop = self.ecoord_adj(scanline[0][0],scale,FlipXoffset)
429
430            DXstart = lastx-startX
431            DYstart = lasty-startY
432
433            if Rapid_Feed_Rate:
434                self.make_egv_rapid(DXstart,DYstart,Rapid_Feed_Rate,board_name,finish=False)
435
436            ##self.write(ord("I"))
437            for code in speed:
438                self.write(code)
439
440            if not Rapid_Feed_Rate:
441                self.make_dir_dist(DXstart,DYstart)
442
443            #insert "NRB"
444            self.flush(laser_on=False)
445            self.write(ord("N"))
446            if (Raster_step < 0.0):
447                self.write(ord("R"))
448            else:
449                self.write(ord("L"))
450            self.write(ord("B"))
451            # Insert "S1E"
452            self.write(ord("S"))
453            self.write(ord("1"))
454            self.write(ord("E"))
455            dx_last   = 0
456
457            sign = -1
458            cnt = 1
459            timestamp=0
460            for scan_raw in scanline:
461                scan = []
462                for point in scan_raw:
463                    e0,e1,e2 = self.ecoord_adj(point,scale,FlipXoffset)
464                    scan.append([e0,e1,e2])
465                stamp=int(3*time()) #update every 1/3 of a second
466                if (stamp != timestamp):
467                    timestamp=stamp #interlock
468                    update_gui("Generating EGV Data: %.1f%%" %(100.0*float(cnt)/float(len(scanline))))
469                    if stop_calc[0]==True:
470                        raise Exception("Action Stopped by User.")
471                cnt = cnt+1
472                ######################################
473                ## Flip direction and reset loop    ##
474                ######################################
475                sign      = -sign
476                last_loop =  None
477                y         =  scan[0][1]
478                dy        =  y-lasty
479                if sign == 1:
480                    xr = scan[0][0]
481                else:
482                    xr = scan[-1][0]
483                dxr = xr - lastx
484                ######################################
485                ## Make Rapid move if needed        ##
486                ######################################
487                if abs(dy-Raster_step) != 0 and not Rapid_flag:
488
489                    if dxr*sign < 0:
490                        yoffset = -Raster_step*3
491                    else:
492                        yoffset = -Raster_step
493
494                    if (dy+yoffset)*(abs(yoffset)/yoffset) < 0:
495                        self.flush(laser_on=False)
496
497                        if not Rapid_Feed_Rate:
498                            self.write(ord("N"))
499                            self.make_dir_dist(0,dy+yoffset)
500                            self.flush(laser_on=False)
501                            self.write(ord("S"))
502                            self.write(ord("E"))
503                        else:
504                            DX=0
505                            DY=dy+yoffset
506                            self.raster_rapid_move_slow(DX,DY,Raster_step,Rapid_Feed_Rate,Feed,board_name)
507
508                        Rapid_flag=True
509                    else:
510                        adj_steps = int(dy/Raster_step)
511                        for stp in range(1,adj_steps):
512
513                            adj_dist=5
514                            self.make_dir_dist(sign*adj_dist,0)
515                            lastx = lastx + sign*adj_dist
516
517                            sign  = -sign
518                            if sign == 1:
519                                xr = scan[0][0]
520                            else:
521                                xr = scan[-1][0]
522                            dxr = xr - lastx
523                    lasty = y
524
525
526                ######################################
527                if sign == 1:
528                    rng = range(0,len(scan),1)
529                else:
530                    rng = range(len(scan)-1,-1,-1)
531                ######################################
532                ## Pad row end if needed ##
533                ###########################
534                pad = 2
535                if (dxr*sign <= 0.0):
536                    if (Rapid_flag == False):
537                        self.make_dir_dist(-sign*pad,0)
538                        self.make_dir_dist( dxr,0)
539                        self.make_dir_dist( sign*pad,0)
540                    else:
541                        self.make_dir_dist( dxr,0)
542                    lastx = lastx+dxr
543
544                Rapid_flag=False
545                ######################################
546                for j in rng:
547                    x  = scan[j][0]
548                    dx = x - lastx
549                    ##################################
550                    loop = scan[j][2]
551                    if loop==last_loop:
552                        self.make_cut_line(dx,0,True)
553                    else:
554                        if dx*sign > 0.0:
555                            self.make_dir_dist(dx,0)
556                    lastx     = x
557                    last_loop = loop
558                lasty = y
559
560            # Make final move to ensure last move is to the right
561            self.make_dir_dist(pad,0)
562            lastx = lastx + pad
563            # If sign is negative the final move will have incremented the
564            # "y" position so adjust the lasty to acoomodate
565            if sign < 0:
566                lasty = lasty + Raster_step
567
568            self.flush(laser_on=False)
569
570
571            dx_final = (startX - lastx)
572            if Raster_step < 0:
573                dy_final = (startY - lasty) + Raster_step
574            else:
575                dy_final = (startY - lasty) - Raster_step
576
577            ##############################################################
578            max_return_feed = 50.0
579            final_feed = 0
580            if Rapid_Feed_Rate:
581                final_feed = Rapid_Feed_Rate
582            elif Feed > max_return_feed:
583                final_feed = max_return_feed
584
585            if final_feed:
586                self.change_speed(final_feed,board_name,laser_on=False,pad=False)
587                dy_final = dy_final + abs(Raster_step)
588                self.make_dir_dist(dx_final,dy_final)
589            else:
590                self.write(ord("N"))
591                self.make_dir_dist(dx_final,dy_final)
592                self.flush(laser_on=False)
593                self.write(ord("S"))
594                self.write(ord("E"))
595            ##############################################################
596
597
598        # Append Footer
599        self.flush(laser_on=False)
600        self.write(ord("F"))
601        self.write(ord("N"))
602        self.write(ord("S"))
603        self.write(ord("E"))
604        update_gui("EGV Data Complete")
605        return
606
607    def make_egv_rapid(self, DX,DY,Feed = None,board_name="LASER-M2",finish=True):
608        speed = self.make_speed(Feed,board_name=board_name,Raster_step=0)
609        if finish:
610            self.write(ord("I"))
611        for code in speed:
612            self.write(code)
613        self.flush(laser_on=False)
614        self.write(ord("N"))
615        self.write(ord("R"))
616        self.write(ord("B"))
617        # Insert "S1E"
618        self.write(ord("S"))
619        self.write(ord("1"))
620        self.write(ord("E"))
621        ###########################################################
622        # Move Distance
623        self.make_cut_line(DX,DY,Spindle=0)
624        ###########################################################
625        # Append Footer
626        self.flush(laser_on=False)
627        if finish:
628            self.write(ord("F"))
629        else:
630            self.write(ord("@"))
631        self.write(ord("N"))
632        self.write(ord("S"))
633        self.write(ord("E"))
634        return
635
636    def rapid_move_slow(self,dx,dy,Rapid_Feed_Rate,Feed,board_name):
637        if Rapid_Feed_Rate:
638            self.change_speed(Rapid_Feed_Rate,board_name,laser_on=False)
639            self.make_dir_dist(dx,dy)
640            self.change_speed(Feed,board_name,laser_on=False)
641        else:
642            self.make_dir_dist(dx,dy)
643
644    def raster_rapid_move_slow(self,DX,DY,Raster_step,Rapid_Feed_Rate,Feed,board_name):
645        tiny_step = Raster_step/abs(Raster_step)
646        self.change_speed(Rapid_Feed_Rate,board_name,laser_on=False,pad=False)
647        self.make_dir_dist(DX,DY-tiny_step)
648        self.flush(laser_on=False)
649        self.change_speed(Feed,board_name,laser_on=False,Raster_step=Raster_step,pad=False)
650        #Tiny Rapid
651        self.write(ord("N"))
652        self.make_dir_dist(0,tiny_step)
653        self.flush(laser_on=False)
654        self.write(ord("S"))
655        self.write(ord("E"))
656
657
658    def rapid_move_fast(self,dx,dy):
659        pad = 3
660        if pad == -dx:
661            pad = pad+3
662        self.make_dir_dist(-pad, 0  ) #add "T" move
663        self.make_dir_dist(   0, pad) #add "L" move
664        self.flush(laser_on=False)
665
666        if dx+pad < 0.0:
667            self.write(ord("B"))
668        else:
669            self.write(ord("T"))
670        self.write(ord("N"))
671        self.make_dir_dist(dx+pad,dy-pad)
672        self.flush(laser_on=False)
673        self.write(ord("S"))
674        self.write(ord("E"))
675
676
677    def change_speed(self,Feed,board_name,laser_on=False,Raster_step=0,pad=True):
678        cspad = 5
679        if laser_on:
680            self.write(self.OFF)
681
682        if pad:
683            self.make_dir_dist(-cspad,-cspad)
684        self.flush(laser_on=False)
685
686        self.write(ord("@"))
687        self.write(ord("N"))
688        self.write(ord("S"))
689        self.write(ord("E"))
690        speed = self.make_speed(Feed,board_name,Raster_step=Raster_step)
691        #print Feed,speed
692        for code in speed:
693            self.write(code)
694        self.write(ord("N"))
695        self.write(ord("R"))
696        self.write(ord("B"))
697        ## Insert "SIE"
698        self.write(ord("S"))
699        self.write(ord("1"))
700        self.write(ord("E"))
701
702        if pad:
703            self.make_dir_dist(cspad,cspad)
704        self.flush(laser_on=False)
705
706        if laser_on:
707            self.write(self.ON)
708
709
710if __name__ == "__main__":
711    EGV=egv()
712    bname = "LASER-M2"
713    values  = [.1,.2,.3,.4,.5,.6,.7,.8,.9,1,2,3,4,5,6,7,8,9,10,20,30,40,50,70,90,100]
714    step=0
715    for value_in in values:
716        #print ("% 8.2f" %(value_in),": ",end='')
717        val=EGV.make_speed(value_in,board_name=bname,Raster_step=step)
718        txt=""
719        for c in val:
720            txt=txt+chr(c)
721        print(txt)
722    print("DONE")
723
724
725
726
727
728
729