Serial-a-Sketch
A downloadable tool for Windows and Linux
Powered by Python 3.10.5, pygame-ce 2.3.0.dev1, tkinter (Tk interface) and pySerial (Windows) / Python 3.8.10, pygame-ce 2.2.1, tkinter (Tk interface) and pySerial (Linux)
Code (Python script, procedural) by Kyuchumimo
There will be a Web version once pySerial will be compatible with pygbag.
"Serial-a-Sketch: A virtual mechanical drawing sketch pad.
Virtually compatible with any microcontroller. Just program your microcontroller, plug and play."
Tested on the following devices:
• USB Serial Device
• Prolific USB-to-Serial Comm Port
• USB-SERIAL CH340
• Arduino Uno
CHANGELOG 230506
A Linux version of the program has been added. This version should work perfectly on the oldest version of Ubuntu with long term support and higher, i.e. Ubuntu 20.04 LTS and higher.
This project uses real electronic components to make this project work. The materials are as follows:
Any microcontroller that can communicate to your computer via SERIAL/TTL/UART protocol, that has at least 2 internal analog-to-digital converters (or externally using some ADC IC like MCP3002/3004/3008/3202/3204/3208/3302/3304, ADS1015/1115/7830, PCF8591) and can provide a string containing a Python-like list of the values of 2 10-bit (0-1023 levels) analog signals. |
x2 10k ohms rotary potentiometers |
Breadboard |
DuPont cables |
CONTROLS
LEFT POTENTIOMETER (ANALOG-TO-DIGITAL CONVERTER, CHANNEL 0) | Stylus X-axis position |
RIGHT POTENTIOMETER (ANALOG-TO-DIGITAL CONVERTER, CHANNEL 1) | Stylus Y-axis position |
SPACEBAR (KEYBOARD) | Clear |
ESCAPE | Close software |
Code for run on any Arduino compatible board:void setup() {
Serial.begin(9600);
}
void loop() {
int adc0 = analogRead(0); // 26 for Pico board
int adc1 = analogRead(1); // 27 for Pico board
Serial.println("[" + String(adc0) + ", " + String(adc1) + "]");
delay(50);
}
Note: Even if you don't have an Arduino development board, the same code (using MiniCore Arduino core or equivalent) is compatible for a variety of 8-bit ATmega family microcontrollers such as ATmega8/48/88/168/328, just make sure you have a USB to SERIAL/TTL/UART converter
For 8-bit ATtiny family microcontrollers such as the ATtiny25/45/85 (using ATTinyCore Arduino core or equivalent), you will need to implement serial communication by software with the SoftwareSerial library.
See: https://docs.arduino.cc/learn/built-in-libraries/software-serial
Code for run only on 8-bit ATmega8/48/88/168/328 microcontrollers (main.c GCC C Executable for Atmel Studio / Microchip Studio):
#define BAUD 9600
#define F_CPU 8000000UL
#define BAUD_PRESCALLER ((F_CPU / (BAUD * 16UL)) - 1)
#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
void USART_init(void)
{
UBRR0H = (uint8_t)(BAUD_PRESCALLER >> 8);
UBRR0L = (uint8_t)(BAUD_PRESCALLER);
UCSR0B = (1 << TXEN0);
UCSR0C = (3 << UCSZ00);
}
void USART_send_char(char data)
{
while (!(UCSR0A & (1 << UDRE0)));
UDR0 = data;
}
void USART_send_string(char *str)
{
while (*str)
{
USART_send_char(*str++);
}
}
void ADC_init(void)
{
ADCSRA |= (1 << ADEN);
ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
}
uint16_t ADC_read(uint8_t channel)
{
ADMUX = (1 << REFS0) | channel;
ADCSRA |= (1 << ADSC);
while (ADCSRA & (1 << ADSC));
return ADC;
}
int main(void)
{
USART_init();
ADC_init();
while (1)
{
uint16_t adc_value_0 = ADC_read(0);
uint16_t adc_value_1 = ADC_read(1);
char adc_string[20];
sprintf(adc_string, "[%d, %d]", adc_value_0, adc_value_1);
USART_send_string(adc_string);
USART_send_string("\r\n");
_delay_ms(50);
}
}
Code for run on PIC microcontrollers with ADC (PIC C Compiler):#include <16f877a.h>
Code for run on Micropython v1.17 or higher compatible boards (save as main.py):
#device ADC = 10
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOLVP,BROWNOUT
#use delay(clock=20M)
#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7) // TX = PIN_C6, RX = PIN_C7
#include <stdio.h>
long adc0;
long adc1;
void main()
{
setup_adc(adc_clock_internal);
setup_adc_ports(ALL_ANALOG);
while(true)
{
set_adc_channel(0);
delay_us(20);
adc0 = read_adc();
set_adc_channel(1);
delay_us(20);
adc1 = read_adc();
printf("[%Lu, %Lu]\r\n", adc0, adc1);
delay_ms(50);
}
}import machine
import utime
adc0 = machine.ADC(26)
adc1 = machine.ADC(27)
while True:
print(f"[{adc0.read_u16()//64}, {adc1.read_u16()//64}]")
utime.sleep_ms(50)
Code for run on any CircuitPython v5.1.0-rc.0 o higher compatible board (save as code.py):
import time
import board
import analogio
adc0 = analogio.AnalogIn(board.GP26)
adc1 = analogio.AnalogIn(board.GP27)
while True:
print(f"[{adc0.value//64}, {adc1.value//64}]")
time.sleep(0.05)
TROUBLESHOOTING
GNU/Linux:• Cannot open /dev/ttyUSB0: Permission denied
This error is caused by the user not having access to the serial ports. More specifically, the user is not in the dialout
group.
Open a terminal and enter the following command: sudo usermod -a -G dialout $USER
Make sure you log out for the changes to take effect.• version 'GLIBC_2.31' not found
This program requires glibc 2.31 or higher, in other words, it is only compatible with Ubuntu 20.04 LTS or higher.
Status | Released |
Category | Tool |
Platforms | Windows, Linux |
Author | Kyuchumimo |
Tags | arduino, electronics, pygame |
Development log
- -CHANGELOG-Apr 19, 2023
Leave a comment
Log in with itch.io to leave a comment.