Exemplo n.º 1
0
class MyApp:
    def __init__(self):

        self.myContainer1 = tk.Tk()
        self.myContainer1.wm_attributes('-type', 'splash')
        self.myContainer1.title("Monsterrhino Printer")
        self.myContainer1.geometry("800x480")

        self.myContainer1.configure(bg="black")

        # Set up variables
        self.im_height = 1240  # Maximum step number of axis
        self.im_width = 2000  # Maximum step number of axis
        self.pix_per_step = 2

        self.pos = [0, 0, 0]
        self.ser = serial.Serial()
        self.ser.baudrate = 115200
        self.port_name = "/dev/ttyUSB0"

        self.laser_status = "off"
        self.laser_pin = 26
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(self.laser_pin, GPIO.OUT)
        self.laser(0)

        self.hight_factor = 0.66
        self.rot_count = 90
        self.homing = False
        # Show image
        self.tkpi = PhotoImage(file="images/monsterrhino.png")
        self.label = Label(self.myContainer1,
                           image=self.tkpi,
                           bg='black',
                           fg="white",
                           activebackground=HOVERCOLER,
                           borderwidth=0,
                           highlightbackground="black",
                           font="none 18")

        self.load_img = Button(self.myContainer1,
                               text="Load Image!",
                               command=self.new_img,
                               bg='black',
                               fg="white",
                               activebackground=HOVERCOLER,
                               borderwidth=2,
                               highlightbackground="black",
                               font="none 18")

        self.connect = Button(self.myContainer1,
                              text="X",
                              command=self.restart_app,
                              bg='black',
                              activebackground=HOVERCOLER,
                              borderwidth=2,
                              highlightbackground="black",
                              font="none 18",
                              fg="red")

        self.status_bar = Label(self.myContainer1, text="Status")

        self.spinnbox_label = Label(self.myContainer1,
                                    text="Image height:",
                                    bg='black',
                                    fg="white",
                                    activebackground=HOVERCOLER,
                                    borderwidth=2,
                                    highlightbackground="black",
                                    font="none 8")

        self.go_zero = Button(self.myContainer1,
                              text="Home",
                              command=self.home_xy_axis,
                              bg='black',
                              fg="white",
                              activebackground=HOVERCOLER,
                              borderwidth=2,
                              highlightbackground="black",
                              font="none 18")

        self.res_label = Label(self.myContainer1,
                               text="{}x{} px".format(self.im_height,
                                                      self.im_width),
                               bg='black',
                               fg="white",
                               activebackground=HOVERCOLER,
                               borderwidth=2,
                               highlightbackground="black",
                               font="none 8")

        self.burn = Button(self.myContainer1,
                           text="Start plotting!",
                           command=self.start_printing,
                           bg='black',
                           fg="white",
                           activebackground=HOVERCOLER,
                           borderwidth=2,
                           highlightbackground="black",
                           font="none 18")

        self.xdir_label = Label(self.myContainer1,
                                text="y_max = 1500 steps ------------> y",
                                bg='black',
                                fg="white",
                                activebackground=HOVERCOLER,
                                borderwidth=2,
                                highlightbackground="black",
                                font="none 8")
        self.rotate_img = Button(self.myContainer1,
                                 text="Rotate Image!",
                                 command=self.rotate_image)

        self.variable = StringVar(self.myContainer1)
        self.variable.set("700")  # default value
        self.drop_down = OptionMenu(self.myContainer1, self.variable, "500",
                                    "600", "700", "800", "900", "1000", "1100",
                                    "1200", "1300", "1400", "1500")
        self.drop_down.configure(bg='black',
                                 fg="white",
                                 activebackground=HOVERCOLER,
                                 borderwidth=2,
                                 highlightbackground="black",
                                 font="none 18")

        self.var1 = tk.IntVar()
        self.checkbox = tk.Checkbutton(self.myContainer1,
                                       text='Curved',
                                       variable=self.var1,
                                       onvalue=1,
                                       offvalue=0,
                                       bg='black',
                                       activebackground=HOVERCOLER,
                                       borderwidth=0,
                                       highlightbackground="black",
                                       font="none 18",
                                       fg="red")

        # Organize layout using grid
        self.label.place(x=520, y=440, anchor="s", height=430, width=500)
        self.load_img.place(x=140, y=90, anchor="s", height=80, width=240)
        self.spinnbox_label.place(x=100, y=115, anchor="s")
        self.drop_down.place(x=140, y=200, anchor="s", height=80, width=240)
        self.go_zero.place(x=140, y=285, anchor="s", height=80, width=240)
        self.burn.place(x=140, y=370, anchor="s", height=80, width=240)
        # self.checkbox.place(x=140, y=430, anchor="s")

        self.connect.place(x=770, y=50, anchor="s", height=40, width=40)

        self.xdir_label.place(x=140, y=470, anchor="s")
        # self.res_label.place(x=140, y=470, anchor="s")

        self.tc_receive_CAN_task = BackgroundTask(self.tc_receive_CAN)
        self.querry_y_pos_const_task = BackgroundTask(self.querry_y_pos_const)
        self.blink_led_task = BackgroundTask(self.blink_LED)
        self.print_task = BackgroundTask(self.draw_img_new)
        self.run = False

        if not PC:
            print("Startup CAN!")
            os.system("sudo /sbin/ip link set can0 up type can bitrate 1000000"
                      )  # brings up CAN
            self.can_bus = can.interface.Bus(bustype="socketcan",
                                             channel="can0",
                                             bitrate=1000000)
            time.sleep(0.1)

            # start receive task
            self.tc_receive_CAN_task.start()
            print("Start can querry task")

            self.led = LED()
            self.led.init_led()
            self.led.set_green()

        self.querry_y_pos_const_task.start()

    def start_printing(self):
        """Starts printing
        """
        self.print_task.start()

    def restart_app(self):
        """Restarts app, only from debugg area callable
        """
        os._exit(0)

    def tc_receive_CAN(self, par):
        """Starts receiver task to receive and set tc_status
        """
        try:
            print("-> Enter CAN receive loop!")
            while True:
                # Wait until a message is received.
                # print("----> Waiting...")
                message = self.can_bus.recv()

                # print("<---- Received...")
                # print("message length ---> " + str(len(message.data)))
                if len(message.data) > 1:
                    # print("enter if <-------<")
                    #print("ID length: ")
                    #print(message.arbitration_id.bit_length())
                    msb0 = '{0:x} '.format(message.data[0])
                    # print("id----> " + str(int(msb0, 16)))
                    id = int(msb0, 16)

                    msb1 = '{0:x} '.format(message.data[1])
                    # print("value----> " + str(int(msb1, 16)))
                    value = int(msb1, 16)

                    to_temp = int(message.arbitration_id) >> 18
                    to_can = int(to_temp & int('000001111', 2))
                    #print("To can ID: " + str(to_can))

                    s = ''
                    for i in range(message.dlc):
                        s += '{0:x} '.format(message.data[i])
                    #print('CAN receive---->  {}'.format(s))

                    # Lock status
                    if to_can == 1 and id == 35:
                        # Check if it is not the other value
                        # print("Y pos")
                        #self.pos[1] = value
                        self.y_current = value
                        #self.pos_label.configure(text="x: {}  y: {}  z: {}".format(self.pos[0], self.pos[1], self.pos[2]))

        except OSError:
            print('Cannot find PiCAN board')

    def new_img(self):
        folder_path = filedialog.askopenfilename()
        try:
            self.orig_im_cv2 = cv2.imread(folder_path)
            self.orig_im = Image.open(folder_path)
            self.orig_im = self.orig_im.convert('L')
            width, height = self.orig_im.size
            print("Original size: {} x {}".format(width, height))

            basewidth = 430
            wpercent = np.divide(basewidth, width)
            print("wpercent: " + str(wpercent))
            hsize = int(height * wpercent)

            print("basewidth {} hsize {}".format(basewidth, hsize))
            self.im = self.orig_im.resize((basewidth, hsize), Image.ANTIALIAS)

            self.spinnbox_label.configure(
                text="Orig. {}x{} px".format(width, height))
            print("Set new image as label")
            self.tkpi = ImageTk.PhotoImage(self.im)
            self.label.config(image=self.tkpi)

        except:
            self.status_bar.configure(text="No valid image selected!")

    def stripe_img(self):
        print("stripe image")

    def laser(self, state):
        if state is 1:
            print("laser on")
            GPIO.output(self.laser_pin, 0)
        else:
            print("laser off")
            GPIO.output(self.laser_pin, 1)

    def x_move_relative(self, steps=100):
        """Moves to a given target position of the given motor
        """
        _steps = steps * 1

        print("Print straight!")
        address, data = cmd_to_CAN(command="m",
                                   sub_command="mr",
                                   motor_nr=2,
                                   usr_fnct_id=1,
                                   err=0,
                                   data=_steps,
                                   toAddress=2,
                                   fromAddress=1,
                                   respondMessage=1)
        if not PC:
            # Send CAN message
            self.send_CAN(address, data)

        address, data = cmd_to_CAN(command="m",
                                   sub_command="mr",
                                   motor_nr=2,
                                   usr_fnct_id=1,
                                   err=0,
                                   data=_steps,
                                   toAddress=2,
                                   fromAddress=1,
                                   respondMessage=1)
        if not PC:
            # Send CAN message
            self.send_CAN(address, data)

    def x_move_curve(self, steps=100):
        """Moves to a given target position of the given motor
        """
        print("Print curved!")
        address, data = uf_to_CAN(fromAddress=1,
                                  toAddress=2,
                                  respondMessage=1,
                                  usr_fnct_id=1,
                                  command="f",
                                  sub_command="s",
                                  uf_nr=1,
                                  par=2)
        if not PC:
            # Send CAN message
            print("curve")
            #self.send_CAN(address, data)

    def y_move_targetposition(self, pos=700):
        """Moves to a given target position of the given motor
        """
        _steps = pos * 1
        address, data = cmd_to_CAN(command="m",
                                   sub_command="tp",
                                   motor_nr=1,
                                   usr_fnct_id=1,
                                   err=0,
                                   data=_steps,
                                   toAddress=2,
                                   fromAddress=1,
                                   respondMessage=1)
        if not PC:
            # Send CAN message
            self.send_CAN(address, data)

    def home_xy_axis(self):
        """Homes x and y axis and moves back to starting position
        """
        if self.homing == False:
            address, data = uf_to_CAN(fromAddress=1,
                                      toAddress=2,
                                      respondMessage=1,
                                      usr_fnct_id=1,
                                      command="f",
                                      sub_command="s",
                                      uf_nr=1,
                                      par=4)
            if not PC:
                # Send CAN message
                self.send_CAN(address, data)

            self.querry_y_pos()

            self.homing = True
        self.laser(0)

    def querry_y_pos_const(self, par):
        """
        Variables:
        userFunctionVariable1 = 30      158
        userFunctionVariable2 = 31      159
        userFunctionVariable3 = 32      160
        userFunctionVariable4 = 33      161
        userFunctionVariable5 = 34      162
        userFunctionVariable6 = 35      163
        """
        # Start receive task
        # self.tc_receive_CAN_tc_row_task.start()

        # Transform CAN command 163 = ID 35
        # Transform CAN command 158 = ID 30
        while True:
            address, data = uv_from_CAN(fromAddress=1,
                                        toAddress=2,
                                        respondMessage=1,
                                        get_val=163,
                                        command=3,
                                        uf_nr=2,
                                        sub_command=35,
                                        data=0)

            # print("-------> Querry!")
            # Send CAN message
            if not PC:
                # Send CAN message
                self.send_CAN(address, data)

            time.sleep(0.02)

    def querry_y_pos(self):
        """
        Variables:
        userFunctionVariable1 = 30      158
        userFunctionVariable2 = 31      159
        userFunctionVariable3 = 32      160
        userFunctionVariable4 = 33      161
        userFunctionVariable5 = 34      162
        userFunctionVariable6 = 35      163
        """
        # Start receive task
        # self.tc_receive_CAN_tc_row_task.start()

        # Transform CAN command 163 = ID 35
        # Transform CAN command 158 = ID 30
        #while True:
        address, data = uv_from_CAN(fromAddress=1,
                                    toAddress=2,
                                    respondMessage=1,
                                    get_val=163,
                                    command=3,
                                    uf_nr=2,
                                    sub_command=35,
                                    data=0)
        # Send CAN message
        if not PC:
            # Send CAN message
            self.send_CAN(address, data)

        # self.myParent.after(20, self.querry_y_pos)
        #print("Querry!")
        #time.sleep(0.5)

    def send_CAN(self, address, data):
        """Translates command to CAN frame and sends it
        :param message: command to be translated and send over CAN
        """

        # Try to write the message
        try:
            msg = can.Message(arbitration_id=address,
                              data=data,
                              is_extended_id=True)
            # print(msg)

        except AttributeError as error:
            print("error:Create message")
            print(error)
            return

        # Try to send the message
        try:
            self.can_bus.send(msg)
            # print("Message sent on {}".format(self.can_bus.channel_info))
        except can.CanError:
            print("Message could NOT be sent!")

    def serial_connect(self):
        try:
            if self.ser.is_open == False:
                self.ser.port = self.port_name
                self.ser.open()
                if self.ser.is_open == True:
                    #self.connect.configure(text="Disconnect!", foreground="green")
                    self.status_bar.configure(text="CNC found!")
            elif self.ser.is_open == True:
                self.ser.close()
                if self.ser.is_open == False:
                    #self.connect.configure(text="Connect!", foreground="black")
                    self.status_bar.configure(text="Disconnected")
        except:
            self.connect.configure(text="No Device!", foreground="red")

    def move_step(self, axis, step=1):  # int(self.step_spinnbox.get())
        try:
            if self.ser.is_open == True:
                directions = ['x', 'y', 'z', 'c', 's', 'u']
                if directions.index(axis) < 3:
                    self.pos[directions.index(axis)] += step
                if directions.index(axis) >= 3:
                    self.pos[directions.index(axis) - 3] -= step
                self.pos_label.configure(text="x: {}  y: {}  z: {}".format(
                    self.pos[0], self.pos[1], self.pos[2]))
                self.ser.write(b'{}{}\n'.format(step, axis))
            elif self.ser.is_open == False:
                self.status_bar.configure(text="Serial not open!")
        except:
            self.status_bar.configure(text="No Device connected!")

    def set_zero(self):
        for i in range(3):
            self.pos[i] = 0
        self.pos_label.configure(text="x: {}  y: {}  z: {}".format(
            self.pos[0], self.pos[1], self.pos[2]))

    def move_zero(self):
        try:
            if self.ser.is_open == True:
                if self.pos[0] < 0:
                    self.ser.write(b'{}{}\n'.format(self.pos[0] * -1, "x"))
                    self.pos[0] = 0
                    self.pos_label.configure(text="x: {}  y: {}  z: {}".format(
                        self.pos[0], self.pos[1], self.pos[2]))
                elif self.pos[0] > 0:
                    self.ser.write(b'{}{}\n'.format(self.pos[0], "c"))
                    self.pos[0] = 0
                    self.pos_label.configure(text="x: {}  y: {}  z: {}".format(
                        self.pos[0], self.pos[1], self.pos[2]))
                elif self.pos[1] < 0:
                    self.ser.write(b'{}{}\n'.format(self.pos[1] * -1, "y"))
                    self.pos[1] = 0
                    self.pos_label.configure(text="x: {}  y: {}  z: {}".format(
                        self.pos[0], self.pos[1], self.pos[2]))
                elif self.pos[1] > 0:
                    self.ser.write(b'{}{}\n'.format(self.pos[1], "s"))
                    self.pos[1] = 0
                    self.pos_label.configure(text="x: {}  y: {}  z: {}".format(
                        self.pos[0], self.pos[1], self.pos[2]))
            elif self.ser.is_open == False:
                self.status_bar.configure(text="Serial not open!")
        except:
            self.status_bar.configure(text="No Device connected!")

    def rotate_image(
        self
    ):  # rotation behavior not working properly yet, also mirror function introducing: ImageOps.rotate
        try:
            if self.rot_count == 360:
                self.rot_count = 0
            self.im = self.orig_im.rotate(self.rot_count)
            self.rot_count += 90

            width, height = self.im.size
            new_width = int(
                np.divide(width, int(self.pix_per_step_spinnbox.get())))
            new_height = int((new_width * height / width) * self.hight_factor)
            self.im = self.im.resize((new_width, new_height), Image.ANTIALIAS)

            self.tkpi = ImageTk.PhotoImage(self.im)
            self.label.config(image=self.tkpi)
            self.label.config(height=200, width=200)
        except:
            self.status_bar.configure(text="No image defined!")

    # def burn_image(self):
    #     try:
    #         if self.ser.is_open == True and self.pos[0] == 0 and self.pos[1] == 0:
    #             pix = np.array(self.im)
    #             pix = 255 - pix
    #             nrow, ncol = pix.shape
    #
    #             for r in range(nrow):
    #                 if self.pos[0] == 0:
    #                     print ("Forward x")
    #                     for c in range(ncol):
    #                         self.ser.write(
    #                             b'{}a\n'.format(int(np.multiply(pix[r, c], float(self.burn_time_factor.get())))))
    #                         time.sleep(
    #                             np.divide(np.multiply(pix[r, c], float(self.burn_time_factor.get())), 1000) + 0.15)
    #                         self.move_step("x", int(self.scale_val.get()))
    #                         time.sleep(0.1)
    #                 else:
    #                     print ("Backward x")
    #                     for c in reversed(range(ncol)):
    #                         self.ser.write(
    #                             b'{}a\n'.format(int(np.multiply(pix[r, c], float(self.burn_time_factor.get())))))
    #                         time.sleep(
    #                             np.divide(np.multiply(pix[r, c], float(self.burn_time_factor.get())), 1000) + 0.15)
    #                         self.move_step("c", int(self.scale_val.get()))
    #                         time.sleep(0.1)
    #
    #                 self.move_step("y", int(self.scale_val.get()))
    #                 time.sleep(0.10)
    #                 print ("x: {}  y: {}  z: {}".format(self.pos[0], self.pos[1], self.pos[2]))
    #
    #             self.move_zero()
    #
    #         elif self.ser.is_open == False:
    #             self.status_bar.configure(text="Serial not open!")
    #     except:
    #         self.status_bar.configure(text="No Device connected!")
    #
    # def burn_image_with_skip(self):
    #     """
    #     Function to switch laser on and off and move through each pixel. White pixel are skipped
    #     """
    #     try:
    #         if self.ser.is_open == True and self.pos[0] == 0 and self.pos[1] == 0:
    #             pix = np.array(self.im)
    #             pix = 255 - pix
    #             nrow, ncol = pix.shape
    #
    #             for r in range(nrow):
    #                 ncol_count_f = 0
    #                 ncol_count_b = 0
    #                 if self.pos[0] == 0:
    #                     print ("Forward x")
    #                     print ("Row: %d" % r)
    #                     for c in range(ncol):
    #                         if pix[r, c] > 0:
    #                             self.move_step("x", int(self.scale_val.get()) * ncol_count_f)
    #                             time.sleep(0.1 * ncol_count_f)
    #                             self.ser.write(b'{}a\n'.format(int(np.multiply(pix[r, c],
    #                                                                            float(self.burn_time_factor.get())))))
    #                             time.sleep(
    #                                 np.divide(np.multiply(pix[r, c], float(self.burn_time_factor.get())), 1000) + 0.15)
    #                             ncol_count_f = 0
    #                         if c == (ncol - 1):
    #                             self.move_step("x", (ncol_count_f + 1) * int(self.scale_val.get()))
    #                             print ("Return to zero steps forward")
    #                             time.sleep(0.02 * ncol_count_f)
    #                         ncol_count_f += 1
    #
    #                 else:
    #                     print ("Backward x")
    #                     print ("Row: %d" % r)
    #                     for c in reversed(range(ncol)):
    #                         if pix[r, c] > 0:
    #                             self.move_step("c", int(self.scale_val.get()) * ncol_count_b)
    #                             time.sleep(0.1 * ncol_count_b)
    #                             self.ser.write(b'{}a\n'.format(int(np.multiply(pix[r, c],
    #                                                                            float(self.burn_time_factor.get())))))
    #                             time.sleep(
    #                                 np.divide(np.multiply(pix[r, c], float(self.burn_time_factor.get())), 1000) + 0.15)
    #                             ncol_count_b = 0
    #                         if c == 0:
    #                             self.move_step("c", self.pos[0])
    #                             print ("Return to zero steps backward")
    #                             time.sleep(0.02 * self.pos[0])
    #                         ncol_count_b += 1
    #
    #                 self.move_step("y", int(self.scale_val.get()))
    #                 time.sleep(0.10)
    #                 print ("x: {}  y: {}  z: {}".format(self.pos[0], self.pos[1], self.pos[2]))
    #
    #             self.move_zero()
    #
    #         elif self.ser.is_open == False:
    #             self.status_bar.configure(text="Serial not open!")
    #     except:
    #         self.status_bar.configure(text="No Device connected!")
    #
    #
    # def burn_image_with_skip_jump(self):
    #     """
    #     Function to switch laser on and off and move through each pixel. White pixel are skipped
    #     """
    #     try:
    #         if self.pos[0] == 0 and self.pos[1] == 0:
    #             pix = np.array(self.im)
    #             pix = 255 - pix
    #             nrow, ncol = pix.shape
    #
    #             for c in range(ncol):
    #                 nrow_count_f = 0
    #                 nrow_count_b = 0
    #                 if self.pos[1] == 0:
    #                     print ("Forward y")
    #                     print ("Col: %d" % c)
    #                     for r in range(nrow):
    #                         if pix[r, c] > 0:
    #                             # self.move_step("y", int(self.scale_val.get()) * nrow_count_f)
    #                             #time.sleep(0.1 * nrow_count_f)
    #                             #self.ser.write(b'{}a\n'.format(int(np.multiply(pix[r, c], float(self.burn_time_factor.get())))))
    #                             #time.sleep(np.divide(np.multiply(pix[r, c], float(self.burn_time_factor.get())), 1000) + 0.15)
    #                             nrow_count_f = 0
    #                         if r == (nrow - 1):
    #                             #self.move_step("y", (nrow_count_f + 1) * int(self.scale_val.get()))
    #                             print ("Return to zero steps forward")
    #                             time.sleep(0.02 * nrow_count_f)
    #                         nrow_count_f += 1
    #
    #                 else:
    #                     print ("Backward y")
    #                     print ("Col: %d" % c)
    #                     for r in reversed(range(nrow)):
    #                         if pix[r, c] > 0:
    #                             self.move_step("s", int(self.scale_val.get()) * nrow_count_b)
    #                             time.sleep(0.1 * nrow_count_b)
    #                             self.ser.write(b'{}a\n'.format(int(np.multiply(pix[r, c],
    #                                                                            float(self.burn_time_factor.get())))))
    #                             time.sleep(
    #                                 np.divide(np.multiply(pix[r, c], float(self.burn_time_factor.get())), 1000) + 0.15)
    #                             nrow_count_b = 0
    #                         if r == 0:
    #                             self.move_step("s", self.pos[1])
    #                             print ("Return to zero steps backward")
    #                             time.sleep(0.02 * self.pos[1])
    #                         nrow_count_b += 1
    #
    #                 self.move_step("x", int(self.scale_val.get()))
    #                 time.sleep(0.10)
    #                 print ("x: {}  y: {}  z: {}".format(self.pos[0], self.pos[1], self.pos[2]))
    #
    #             self.move_zero()
    #
    #         elif self.ser.is_open == False:
    #             self.status_bar.configure(text="Serial not open!")
    #     except:
    #         self.status_bar.configure(text="No Device connected!")

    def image_resize(self,
                     image,
                     width=None,
                     height=None,
                     inter=cv2.INTER_AREA):
        # initialize the dimensions of the image to be resized and
        # grab the image size
        dim = None
        (h, w) = image.shape[:2]

        # if both the width and height are None, then return the
        # original image
        if width is None and height is None:
            return image

        # check to see if the width is None
        if width is None:
            # calculate the ratio of the height and construct the
            # dimensions
            r = height / float(h)
            dim = (int(w * r), height)

        # otherwise, the height is None
        else:
            # calculate the ratio of the width and construct the
            # dimensions
            r = width / float(w)
            dim = (width, int(h * r))

        # resize the image
        resized = cv2.resize(image, dim, interpolation=inter)

        # return the resized image
        return resized

    def wait_to_finish(self):
        self.y_current = 1
        while self.y_current != 0:
            # self.querry_y_pos()
            print("y current 1: " + str(self.y_current))
            time.sleep(0.2)

    def blink_LED(self, par):
        while True:
            if self.run == True:
                self.led.set_orange_green_mix()
                time.sleep(0.5)
                self.led.set_orange_green_mix2()
                time.sleep(0.5)

    def draw_img_new(self, par):

        if self.homing == True:

            print("Start printing ...")
            self.run = True
            if not PC:
                self.blink_led_task.start()

            wait_for_pen = 1.4

            or_nrow, or_ncol = self.orig_im_cv2.shape[:2]
            print("Original Nraws {} Original Ncols {}".format(
                or_nrow, or_ncol))

            print("Curved: " + str(self.var1.get()))
            # Get desired image height
            image_height = int(self.variable.get())

            print("image_height: " + str(image_height))
            scale_factor = np.divide(or_nrow, image_height)
            print("scale factor: " + str(scale_factor))
            image_width = int(np.divide(or_ncol, scale_factor))
            image_width = int(np.divide(image_width, 7))

            print("Image height set to: " + str(image_height) +
                  " image width set to: " + str(image_width))

            # image_height = 700
            invert = False  # draw black or white

            # self.orig_im_cv2 = self.image_resize(self.orig_im_cv2, height = image_height)

            self.orig_im_cv2 = cv2.resize(self.orig_im_cv2,
                                          (image_width, image_height))

            self.orig_im_cv2 = cv2.cvtColor(self.orig_im_cv2,
                                            cv2.COLOR_BGR2GRAY)
            __, self.orig_im_cv2 = cv2.threshold(
                self.orig_im_cv2, 128, 255,
                cv2.THRESH_BINARY + cv2.THRESH_OTSU)

            nrow, ncol = self.orig_im_cv2.shape[:2]
            c = ncol - 1
            r = nrow
            print("Nraws {} Ncols {}".format(r, c))

            if invert:
                self.orig_im_cv2 = (255 - self.orig_im_cv2)

            # print(self.orig_im_cv2)
            # cv2.imshow("im", self.orig_im_cv2)
            # cv2.waitKey()

            img = self.orig_im_cv2
            positive = True
            prev_pix = 255

            for c in range(ncol - 1, -1, -1):
                print("c: " + str(c))
                if sum(img[:, c]) == ncol * 255:
                    print("Empty line -- skip to next line!")
                    print("----")
                    prev_pix = 255

                else:
                    if positive:
                        print("Positive!")

                        for idx, pix in enumerate(reversed(img[:, c])):
                            # print(idx, pix)

                            # ----------------Plotting--------------------
                            if pix == prev_pix:
                                pass
                                # print("same color!")
                            elif pix < prev_pix:
                                # draw color is black
                                print((len(img[:, c]) - idx), pix)
                                print(
                                    "Laser off - move to idx: {}!".format(idx))
                                if not PC:
                                    self.laser(0)
                                    # time.sleep(wait_for_pen)
                                    self.wait_to_finish()

                                    self.y_move_targetposition(idx)

                                    self.wait_to_finish()

                                    # time.sleep(wait_for_pen)

                            elif pix > prev_pix:
                                # draw color is white
                                print((len(img[:, c]) - idx), pix)
                                print(
                                    "Laser on - move to idx: {}!".format(idx))
                                if not PC:
                                    self.laser(1)
                                    # time.sleep(wait_for_pen)
                                    self.wait_to_finish()

                                    self.y_move_targetposition(idx)

                                    self.wait_to_finish()

                                    # time.sleep(wait_for_pen)

                            if idx == len(img[:, c]) - 1:
                                # move to the end
                                print(
                                    "Move to the end to idx: {}!".format(idx))
                                print((len(img[:, c]) - idx), pix)
                                if pix > 0:
                                    # draw color is black
                                    print(
                                        "Laser off - move to idx: {}!".format(
                                            idx))
                                    if not PC:
                                        self.laser(0)
                                        # time.sleep(wait_for_pen)
                                        self.wait_to_finish()

                                        # self.y_move_targetposition(idx)

                                        # self.wait_to_finish()

                                elif pix == 0:
                                    # draw color is white
                                    print("Laser on - move to idx: {}!".format(
                                        idx))
                                    if not PC:
                                        self.laser(1)
                                        # time.sleep(wait_for_pen)
                                        self.wait_to_finish()

                                        self.y_move_targetposition(idx)

                                        self.wait_to_finish()

                                        # time.sleep(wait_for_pen)

                            prev_pix = pix
                            # ------------------------------------------

                        print("----")
                        positive = False
                        prev_pix = 255

                    else:
                        print("Negative!")

                        for idx, pix in enumerate(img[:, c]):
                            # print(idx, pix)

                            # ----------------Plotting--------------------
                            if pix == prev_pix:
                                pass
                                # print("same color!")
                            elif pix < prev_pix:
                                # draw color is black
                                print((len(img[:, c]) - idx), pix)
                                print("Laser off - move to idx: {}!".format(
                                    (len(img[:, c]) - idx)))
                                if not PC:
                                    self.laser(0)
                                    # time.sleep(wait_for_pen)
                                    self.wait_to_finish()

                                    self.y_move_targetposition(
                                        (len(img[:, c]) - idx))

                                    self.wait_to_finish()

                                    # time.sleep(wait_for_pen)

                            elif pix > prev_pix:
                                # draw color is white
                                print((len(img[:, c]) - idx), pix)
                                print("Laser on - move to idx: {}!".format(
                                    (len(img[:, c]) - idx)))
                                if not PC:
                                    self.laser(1)
                                    # time.sleep(wait_for_pen)
                                    self.wait_to_finish()

                                    self.y_move_targetposition(
                                        (len(img[:, c]) - idx))

                                    self.wait_to_finish()

                                    # time.sleep(wait_for_pen)

                            if idx == len(img[:, c]) - 1:
                                # move to the end
                                print((len(img[:, c]) - idx), pix)
                                print("Move to the end to idx: {}!".format(
                                    (len(img[:, c]) - idx)))
                                if pix > 0:
                                    # draw color is black
                                    print(
                                        "Laser off - move to idx: {}!".format(
                                            (len(img[:, c]) - idx)))
                                    if not PC:
                                        self.laser(0)
                                        # time.sleep(wait_for_pen)
                                        self.wait_to_finish()

                                        # self.y_move_targetposition(0)

                                        # self.wait_to_finish()

                                elif pix == 0:
                                    # draw color is white
                                    print("Laser on - move to idx: {}!".format(
                                        (len(img[:, c]) - idx)))
                                    if not PC:
                                        self.laser(1)
                                        # time.sleep(wait_for_pen)
                                        self.wait_to_finish()

                                        self.y_move_targetposition(0)

                                        self.wait_to_finish()

                                        # time.sleep(wait_for_pen)

                            prev_pix = pix
                            # ------------------------------------------

                        print("----")
                        positive = True
                        prev_pix = 255

                # X MOVE with wheels
                print("Move to next line!")
                print("Laser off!")
                self.laser(0)
                print("----> x ")
                # time.sleep(wait_for_pen)

                self.wait_to_finish()

                if not self.var1.get():
                    print("Straight print!")
                    self.x_move_relative(steps=6)
                    time.sleep(0.2)
                else:
                    print("Curve print!")
                    self.x_move_curve()
                    time.sleep(0.4)

            # Done
            # self.pos_label.configure(text="Done printing!")
            self.run = False
            time.sleep(0.5)
            self.led.set_blue()

            self.homing = False