bin am basteln eines „Dotmatrixdruckers“.
https://en.wikipedia.org/wiki/Dot_matrix
Die ganze Bastelei basiert auf einem Micro:bit, Fischertechnik und dem Motordriverboar
https://www.waveshare.com/wiki/Motor_Dr ... _micro:bit
Ich verwende die normalen Motoren und an diese habe ich „Pappencoderscheiben“ gesteckt und geklebt. Die Position und Laufrichtung lese ich mit Lichtschranken aus und bringe die Werte mit einem CD4093 auf 0 oder 1.
https://strippenstrolch.de/1-2-10-der-s ... -4093.html
So richtig Ahnung habe ich davon nicht, doch habe versucht mich einzulesen, da die Beschaltung der Ein/Ausgänge des Micro:bit/Motorboards nur in bestimmten Wertebereichen möglich ist. Läuft bis jetzt stabil und noch keinen Wohnungsbrand verursacht – solche Basteleien nur unter Beobachtung laufen lassen !
Falls Interesse besteht, mache ich auch ein Video.
Das Modul für das Board habe ich umgeschrieben:
Code: Alles auswählen
import microbit as mb
import utime
class MotorDriverBoard(object):
MOTOR_A_PWM = mb.pin8
MOTOR_A_IN_1 = mb.pin13
MOTOR_A_IN_2 = mb.pin12
MOTOR_B_PWM = mb.pin16
MOTOR_B_IN_1 = mb.pin14
MOTOR_B_IN_2 = mb.pin15
#SERVO_0 = mb.pin0
#SERVO_1 = mb.pin1
SERVO_2 = mb.pin2
SERVO_PERIOD = 20
def __init__(self):
self.motors = {"MOTOR_A": {"PWM": self.MOTOR_A_PWM,
"SPEED": 0,
"DIRECTION": "",
"POSITION": 0,
"PINS": (self.MOTOR_A_IN_1,
self.MOTOR_A_IN_2)},
"MOTOR_B": {"PWM": self.MOTOR_B_PWM,
"SPEED": 0,
"DIRECTION": "",
"POSITION": 0,
"PINS": (self.MOTOR_B_IN_1,
self.MOTOR_B_IN_2)}}
self.servos = {#"SERVO_0": self.SERVO_0}
#"SERVO_1": self.SERVO_1,
"SERVO_2": self.SERVO_2}
for servo in self.servos.keys():
self.servos[servo].set_analog_period(self.SERVO_PERIOD)
def drive_position(self, motor, new_pos, pin, speed):
self.set_motor_speed(motor, speed)
self.set_motor_direction(motor, "forward") \
if self.motors[motor]["POSITION"] < new_pos \
else self.set_motor_direction(motor, "backward")
while new_pos != self.motors[motor]["POSITION"]:
last_state = pin.read_digital()
new_state = pin.read_digital()
while new_state == last_state:
new_state = pin.read_digital()
if self.motors[motor]["DIRECTION"] == "forward":
self.motors[motor]["POSITION"] += 1
else:
self.motors[motor]["POSITION"] -= 1
self.set_motor_speed(motor, 0)
def set_motor_speed(self, motor, speed):
if speed >= 1 and speed <= 16:
self.motors[motor]["PWM"].write_analog(speed * 64 - 1)
self.motors[motor]["SPEED"] = speed
elif speed == 0:
self.motors[motor]["PWM"].write_analog(speed)
self.motors[motor]["SPEED"] = speed
else:
raise RuntimeError("Error: {0} -> wrong speed -> {1}".format(
motor, speed))
def start_soft_motor(self, motor, end_speed, time_step=100):
for speed in range(0, end_speed):
self.set_motor_speed(motor, speed)
utime.sleep_ms(time_step)
def stop_soft_motor(self, motor, time_step=100):
for speed in range(self.motors[motor]["SPEED"], 0, -1):
self.set_motor_speed(motor, speed)
utime.sleep_ms(time_step)
self.motors[motor]["PWM"].write_analog(0)
self.motors[motor]["SPEED"] = 0
def set_motor_direction(self, motor, direction):
directions = {"forward": (0, 1),
"backward": (1, 0)}
if direction in list(key for key in directions):
for pin, state in zip(self.motors[motor]["PINS"],
directions[direction]):
pin.write_digital(state)
self.motors[motor]["DIRECTION"] = direction
def change_motor_direction(self, motor):
self.set_motor_direction(motor, "backward") \
if self.motors[motor]["DIRECTION"] == "forward" \
else self.set_motor_direction(motor, "forward")
def turn_servo(self, servo, angle):
if angle >= 0 and angle <= 180:
self.servos[servo].write_analog(angle / 2 + 25)
else:
raise RuntimeError("Error: {0} -> wrong angle -> {1}".format(
servo, angle))
def turn_servo_off(self, servo):
self.servos[servo].write_analog(0)
Code: Alles auswählen
import microbit as mb
import utime
from MotorDriverBoard import MotorDriverBoard
class DotMatrixPrinter(object):
ENCODER_PIN_X = mb.pin0
SPEED_X = 10
STEP_X = 7
ENCODER_PIN_Y = mb.pin1
SPEED_Y = 10
def __init__(self):
self.motor_board = MotorDriverBoard()
def print_image(self):
with open("print_job.txt") as print_job:
dot = True
while dot:
dot = print_job.readline()
x, y = dot.rstrip().split("|")
self.motor_board.drive_position("MOTOR_A", int(x) * self.STEP_X,
self.ENCODER_PIN_X,
self.SPEED_X)
self.motor_board.drive_position("MOTOR_B", int(y),
self.ENCODER_PIN_Y,
self.SPEED_Y)
self.motor_board.set_motor_speed("MOTOR_B", 0)
self.motor_board.turn_servo("SERVO_2", 30)
utime.sleep_ms(200)
self.motor_board.turn_servo("SERVO_2", 0)
utime.sleep_ms(200)
self.motor_board.turn_servo_off("SERVO_2")
printer = DotMatrixPrinter()
printer.print_image()
Code: Alles auswählen
#! /usr/bin/env python
# -*- coding: utf-8
from PIL import Image, ImageDraw
import cv2
import numpy as np
img_name = "audrey_2.png"
image = Image.open(img_name)
resolution = 170
print_width = 85
show = True
resize_factor_show_img = 5
dot_width = 4
y = 0
x = 0
new_img_width = int(image.size[0] / (image.size[1 if image.size[1]
> image.size[0] else 0] / print_width))
new_img_height = int(image.size[1] / (image.size[1 if image.size[1]
> image.size[0] else 0] / print_width))
with open("print_job.txt","w") as print_job:
for i, pix in enumerate(Image.frombytes('L',
(
image.width,
image.height
),
cv2.blur(
cv2.adaptiveThreshold(
cv2.cvtColor(
np.asarray(image), cv2.COLOR_BGR2GRAY
),
255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY,
63,
5,
),
(5,
5
)),
'raw',
).resize(
(new_img_width,
new_img_height
)).getdata()):
if pix < resolution:
print_job.write("{0}|{1}\n".format(y, x))
if i % new_img_width == new_img_width - 1:
x = 0
y += 1
else:
x += 1
print_job_img = Image.new("P", (new_img_width * resize_factor_show_img,
new_img_height * resize_factor_show_img), color="white")
draw_img = ImageDraw.Draw(print_job_img)
if show:
with open("print_job.txt") as print_job:
for dot in print_job.readlines():
y, x = dot.split("|")
draw_img.ellipse([int(x) * resize_factor_show_img,
int(y) * resize_factor_show_img,
int(x) * resize_factor_show_img + dot_width,
int(y) * resize_factor_show_img + dot_width],
fill="red")
print_job_img.show()
print_job_img.save("{0}_{1}.{2}".format(img_name.split(".")[0], "print_job", "png"))
Gruß Frank