# K-Tape Cutter ![IMG_2100](https://hackmd.io/_uploads/rJMk1MYda.jpg) ## Overview   This is a **Laser Cutter Machine for Kinesiology Tape**.   Physical health is a big issue for every athlete, they have always to take care of their body. It is quite important to have a good connection with their trainers to protect themselves, especially during the competition period. Sometimes athletes have to apply kinesiology tapes before the game so that they can have better performance.   However, the tape-cutting work is very time consumed may delay their preparation state. In addition, trainers would not be by their sides 24/7…… So if an athlete wants to apply the tape, they have to cut it by themselves (or the trainers) beforehand and bring the tape somewhere for application by trainers, the tape may be damaged while stored in a bag, which will reduce the effectiveness :(   The Best helper for Athletes and Athletic Trainers! Using Telegram, we can communicate with the K-Tape Cutter Genie to ask for the ideal length and style of cutting Kinesiology Tape, after receiving the QR code generated by the K-Tape genie, athletes only have to scan the image by the K-Tape Cutter machine that can get the tape which they requested!!! ## What it is ### The Apperance ![S__3751944](https://hackmd.io/_uploads/BkBVTlFO6.jpg) ### Demo Video [![video](https://hackmd.io/_uploads/S1IRTYK_a.png) ](https://www.youtube.com/watch?v=M4aRxDg3Xf8) ## Component ![S__180936712](https://hackmd.io/_uploads/r1Csled_T.jpg) ### Hardware |Name |Quantity| |-----|--------| |Raspiberry Pi 4|1 | |12V 2.5 W Laser Head |1 | |28BYJ-48 5VDC stepper motor|3| |ULN2003 stepper motor driver|3| |360° Rotary Encoder|1|| |Logitech Webcam|1|| |Sliding tracks for 28BYJ-48 stepper motor|2|| |Power Supplier for Raspiberry Pi|1|| |1.5V AA battery|8|| |4x 1.5V AA batteries holder|2|| |Breadboard|1|| |GPIO pin extender|1|| |40 pins Rainbow GPIO cable|1|| |Jumper wires|many many|| ### Software | Icon | Name | Download here! | | --------------------------------------------------- | ------------------- | ---------------------------------------------------------- | |![python](https://hackmd.io/_uploads/BkldGguOT.png) | Python | https://www.python.org/downloads/release/python-3717/ | |![bot](https://hackmd.io/_uploads/SyjbmxOOa.jpg) | Python Telegram Bot | https://github.com/python-telegram-bot/python-telegram-bot | ### Others |Name |Quantity| |-----|--------| |Encoder Wheel|1 | |Roller Tube|1 | |cotton thread|1|| |15mm binder clip|1| |Kinsiology Tape|1| |Tape Holder|1| |Wood Squares|10|| |Thick cardboard|2|| |Clipboard|1|| |Instant glue|1|| ## Let's make it ### System Logic ![sysDiagram](https://hackmd.io/_uploads/H1GZrwFdp.jpg) ### Circuit Diagram ![Circuit](https://hackmd.io/_uploads/Hk4eWPFdT.jpg) ## Before Getting Start ### 1. Set up [Raspberry Pi OS](https://www.raspberrypi.com/software/) ### ### 2. Build the environment for this project ### ##### **Basic enviornments** ##### Go yor Raspberry Pi terminal and enter: sudo apt-get install libzbar0 pip install RPi.GPIO pip install pyzbar pip install opencv-python ##### **OpenCV** ##### Follow below link to **Install CMake 3.14.4** and **Install OpenCV**: (p.s. In this project, u don't need to install OpenVINO!!) https://hackmd.io/HV6hQ2PHSiWlrRsfxC10SA ##### **Telegram bot** ##### Go to your local computer terminal and enter: pip install python-telegram-bot --upgrade pip install qrcode ### 3. 3D print to make Wheel & Tube ### * My 3D print file: [tubeNwheels.gcode](https://github.com/Chienyuuu6/K-Tape-Cutter/blob/main/3D%20print/tubeNwheels.gcode) * Or you can find lots of 3D models on [PrintTables](https://www.printables.com/) * You can design your own 3D print file on [Tinkercad](https://www.tinkercad.com/) ##### Encoder & Wheel ##### The purpose of having a wheel is to calculate the actual length of the pulled-out tape. Since I use a 360 ° rotary encoder to obtain the goal, I need an encoder “wheel-like” knob. ##### Motor & Tube ##### The tube is for collecting the pulled-out tape. I’d like to roll out the tape by sticking the motor with the tape roll, but I found that the tape won’t roll out, it’s become loose… So I adapted plan B: set the motor away from the tape and use blind clips to pull it out. ## Build up your own Chatting Genie ## I use **Python Telegram bot v20.7** to make my own chatting bot. Follow the steps to get your own bot! ### **STEP1** [Download](https://desktop.telegram.org/) Telegram ### ![tele](https://hackmd.io/_uploads/r1EYPRdda.png) ### **STEP2** Use [@BotFather](https://t.me/BotFather) to create new bot ### ![fa](https://hackmd.io/_uploads/SkfhD0O_6.png) ### **STEP3** Follow these link to learn how to setting your bot ### * Build Bot: https://tcsky.cc/tips-01-telegram-chatbot/ * Instructions & Examples (v13): https://hackmd.io/@truckski/HkgaMUc24?type=view * Offical document: https://docs.python-telegram-bot.org/en/v20.7/ ### **STEP4** Edit your bot in python ### * Import the libraraies from telegram.ext import ( ContextTypes, ApplicationBuilder, CommandHandler, MessageHandler, filters, ConversationHandler, CallbackQueryHandler, ) from io import BytesIO import json import logging from telegram import Update,InlineKeyboardButton,InlineKeyboardMarkup import qrcode * Setting token on the script "YOUR TOKEN HERE". <font color=#930000>**Notice**: MUST keep your token private & safe.</font> application = ApplicationBuilder().token("YOUR TOKEN HERE").build() * Examples for designing the bot * Reference code: https://github.com/Amir-AJ-PRO/Bot-projects-PythonTelegramBot-V20/blob/main/ChatBot.py * Conversation bot example: https://docs.python-telegram-bot.org/en/v20.7/examples.conversationbot.html * My KTapeGenieBot: [KTapeGenie.py](https://github.com/Chienyuuu6/K-Tape-Cutter/blob/main/telegramBot/KTapeGenieBot.py) ## Build up the K-Tape Cutter ## * My Cutter: [cutter.py](https://github.com/Chienyuuu6/K-Tape-Cutter/blob/main/cutter.py) ### **STEP1** Motor ### ![S__3751942](https://hackmd.io/_uploads/r1i86ltOp.jpg) I use 28BYJ-48 5vDC stepper motors as my XY axis and tape-roller controller. You Need a ULN2003 stepper motor driver to drive each motor. * Motor setup 1. For scripting the motor, you need these libraries: import RPi.GPIO as GPIO import time from threading import Thread 1. Set up the GPIO pins Here I used **GPIO.setmode(GPIO.BCM)** Replace the number of "pins" list as the pins you used for in1, in2, in3, and in4! # Define the GPIO pins for the stepper motor # pins = [in1, in2, in3, in4] GPIO.setmode(GPIO.BCM) motor_pins = [18,23,24,25] for i in motor_pins: GPIO.setup(i, GPIO.OUT) * Make it Move! Here is the moving sequence of the motor: # Define the sequence of steps for the stepper motor seq = [ [1, 0, 0, 1], [1, 0, 0, 0], [1, 1, 0, 0], [0, 1, 0, 0], [0, 1, 1, 0], [0, 0, 1, 0], [0, 0, 1, 1], [0, 0, 0, 1] ] An Example to move the motor in two direction: # move one motor # the arg "pins" is the "pins list" of your motor def move_single(pins, steps, speed, direction): # move forward if direction == 0: for _ in range(steps): print(_) for i in range(8): for y in range(4): GPIO.output(pins[y], seq[i][y]) time.sleep(speed) # move backward else: for _ in range(steps): print(_) for i in range(8): for y in range(4): pin=abs(y-(3)) GPIO.output(pins[pin], seq[i][y]) time.sleep(speed) * How it work: **28BYJ-48 stepper motor** (source: [ChatGPT](https://chat.openai.com/)) Accroding above example, here's sth you need to know: * The **seq** variable defines the sequence of steps for the stepper motor. Adjusting this sequence can change the motor direction and stepping behavior. * The **for _ in range(steps) loop** moves the stepper motor by a specified number of steps with a specified delay between steps. * The **for y in range(4) loop** sets the motor coils based on the current step. * Move both motor in the same time I defined motor_x and motor_y beforehand, and using **Thread** to make both motors move together! # move a slope def move_both( speed, direction_x, direction_y): thread_x = Thread(target=motor_x, args=(slope, speed, direction_x)) thread_y = Thread(target=motor_y, args=(slope, speed, direction_y)) thread_x.start() thread_y.start() thread_x.join() thread_y.join() ### **STEP2** Rotary Encoder ### ![S__3751940](https://hackmd.io/_uploads/B1sP6gtuT.jpg) I use rotary encoder to calculate the actual length of the pulled-out tape. * My Encoder: [encoder.py](https://github.com/Chienyuuu6/K-Tape-Cutter/blob/main/encoder.py) * Encoder setup # Define GPIO pins for the rotary encoder CLK = 22 # Rotary encoder CLK pin DT = 27 # Rotary encoder DT pin SW = 17 # Rotary encoder SW (push button) pin # Setup GPIO mode and pins GPIO.setmode(GPIO.BCM) GPIO.setup(CLK, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(DT, GPIO.IN, pull_up_down=GPIO.PUD_UP) GPIO.setup(SW, GPIO.IN, pull_up_down=GPIO.PUD_UP) * How it work: **Incremental Rotary Encoder** (source: [ChatGPT](https://chat.openai.com/)) * Mechanical Structure: An incremental rotary encoder consists of a rotating disk with evenly spaced slots or markings, and a stationary sensor (optical or magnetic) that reads these markings as the disk rotates. * Working Principle: As the encoder shaft turns, the sensor detects changes in position by counting the number of slots that pass by or changes in the magnetic field. Each slot or marking represents a discrete "step" or "pulse." * Output: The output of an incremental encoder is a series of pulses. The direction of rotation can be determined by the order in which these pulses occur (increasing or decreasing). However, an incremental encoder does not provide information about the absolute position; it only indicates the relative change in position. # Initialize variables counter = 0 clk_last_state = GPIO.input(CLK) dt_last_state = GPIO.input(DT) # Callback function for the rotary encoder def rotary_encoder_callback(channel): global counter, clk_last_state, dt_last_state clk_state = GPIO.input(CLK) dt_state = GPIO.input(DT) if clk_state != clk_last_state: if dt_state != clk_state: counter += 1 else: counter -= 1 clk_last_state = clk_state dt_last_state = dt_state ### **STEP3** Laser Head ### ![S__3751943](https://hackmd.io/_uploads/SJsdpgY_T.jpg) :::danger MUST be Carefully while testing the laser!!! ::: The most important Role in this project: **Laser Head**. For cutting the Kinesiology tape we'd lke! * Laser setup Use the pin with PWM control! 1. GPIO12 & GPIO18 (PWM0) 2. GPIO13 & GPIO19 (PWM1) GPIO.setmode(GPIO.BCM) def laser(status): laser_pin = 12 GPIO.setup(laser_pin, GPIO.OUT) GPIO.output(laser_pin, status) * How it work: [**Laser Head**](https://www.ruten.com.tw/item/show?22330312878964&_gl=1*17h5nd8*_ga*MzE0NTMwNzU1LjE2OTg4NDUwMjY.*_ga_2VP4WXLL56*MTcwNDY4NTcyMi4yOC4xLjE3MDQ2ODU3MzUuNDcuMC4w) Control the laser by these commands: laser(GPIO.LOW) # close the laser laser(GPIO.HIGH) # open the laser ### **STEP4** Design the cutting Route ### I found that every 660 steps, the motor move 5cm which is one grid of the Kinesiology tape. Base on this, we can design the moving route by different x or y motors, steps, and direction. Here's some example: # tape cutting format # move steps grid = 692 half = 346 halfhalf = 173 slope = 60 cut1 = 632 cut2 = 590 cutY = 226 cutF = 53 # speed laser_speed = 0.025 move_speed = 0.001 # onclose def onclose_u(): laser(GPIO.LOW) motor_y(cut1, move_speed, 0) laser(GPIO.HIGH) move_both(laser_speed, 0,0) laser(GPIO.LOW) motor_x(cut2, move_speed, 0) laser(GPIO.HIGH) move_both(laser_speed, 0,1) laser(GPIO.LOW) motor_y(cut1, move_speed, 1) motor_x(grid, move_speed, 1) ### **STEP5** Web cam & Decoding QRcode ### By scaning the QR code generated from K-Tape Genie, the program can get the arguments it needs and start the laser cutting work!! * My qrCode detector: [qrCode.py](https://github.com/Chienyuuu6/K-Tape-Cutter/blob/main/qrCode.py) * OpenCV Most importantly for this code to run is to import OpenCV & the libraries we needed: import cv2 import pyzbar.pyzbar as pyzbar import json * set up web cam # set up camera object called Cap which we will use to find OpenCV cap = cv2.VideoCapture(0) font = cv2.FONT_HERSHEY_PLAIN * Decoding the img def run(): try: while True: _, img = cap.read() decodedObjects = pyzbar.decode(img) # Check if any QR code is detected if decodedObjects: for obj in decodedObjects: try: decoded_data = str(obj.data, 'utf-8') print(decoded_data) # Replace single quotes with double quotes decoded_data = decoded_data.replace("'", "\"") data = json.loads(decoded_data) format = data['format'] length = data['length'] inner = data['inner'] print('json data detected in QR code:\n' + format + '\n' + str(length) + '\n' + str(inner) + '\n') cv2.putText(img, str(obj.data), (50, 50), font, 2, (255, 0, 0), 3) cap.release() cv2.destroyAllWindows() return format, length, inner except json.JSONDecodeError as e: print("Error decoding JSON:", e) continue except Exception as e: print("Error processing QR code data:", e) continue cv2.imshow("code detector", img) if cv2.waitKey(1) == ord("q"): break cap.release() cv2.destroyAllWindows() except KeyboardInterrupt: key = cv2.waitKey(1) if key == 27: cap.release() cv2.destroyAllWindows() return **Look Deeper into the above code** for obj in decodedObjects: try: decoded_data = str(obj.data, 'utf-8') print(decoded_data) # Replace single quotes with double quotes decoded_data = decoded_data.replace("'", "\"") data = json.loads(decoded_data) format = data['format'] length = data['length'] inner = data['inner'] print('json data detected in QR code:\n' + format + '\n' + str(length) + '\n' + str(inner) + '\n') cv2.putText(img, str(obj.data), (50, 50), font, 2, (255, 0, 0), 3) cap.release() cv2.destroyAllWindows() return format, length, inner These scripts help us to get the important argments and retuen to the main program that make the cutter start running!!! ## Let's Coding ## Here is my code for the whole project Link here: https://github.com/Chienyuuu6/K-Tape-Cutter ## Reference #### Laser Engraver * Mini CNC plotter: https://www.hackster.io/embeddedlab786/mini-cnc-plotter-machine-at-home-6cddbf * How to Make Powerfull Laser Engraver: https://www.hackster.io/diyprojectslab/how-to-make-powerfull-laser-engraver-d7b675 #### QR code detector * How To Scan QR Codes With A Raspberry Pi + OpenCV + Python: https://www.youtube.com/watch?v=Qf55aUgfLfQ * iot-bartender for **qrcode detecting**: https://github.com/chung-coder/Iot-bartender/blob/main/Iot-bartender/camera.py #### Telegram bot * iot-bartender for **telegram bot api**: https://github.com/chung-coder/Iot-bartender/ #### 3D print * **Encoder wheels** that I modified from: https://www.printables.com/model/646906-encoder-wheel-for-seeder/files * **Tape roller** tube that I modified from: https://www.printables.com/model/583211-50mm-tape-roller #### Others * Green house for **motor moving tracks**: https://hackmd.io/@fGmzd-CTSGSBPbmj6Sr-nw/BJ06WFw0P#Green-House