viszualizers and digital output

This commit is contained in:
unknown 2024-10-19 00:16:28 +03:00
parent 96d23c1b59
commit 62f1861de0
4 changed files with 157 additions and 10 deletions

View File

@ -1,26 +1,46 @@
#include <avr/pgmspace.h>
#include "stimulation_pattern.h"
const int stimulationPin = 5;
const int delayBetweenStimulations = 10; // milliseconds
const bool DEBUG = true; // Set to true to enable serial output
const bool USE_DIGITAL = true; // Set to false to use analog output
const int stimulationPin = 5; // PWM-capable pin
const unsigned long delayBetweenStimulations = 1000; // microseconds (1ms delay for more stable serial transmission)
const int threshold = 50; // Threshold for converting analog to digital
void setup() {
pinMode(stimulationPin, OUTPUT);
Serial.begin(9600);
Serial.begin(115200); // Increased baud rate for faster output
}
// Function to convert analog value to digital
bool analogToDigital(uint8_t analogValue) {
return analogValue >= threshold;
}
// Function to write output (digital or analog)
void writeOutput(uint8_t value) {
if (USE_DIGITAL) {
digitalWrite(stimulationPin, analogToDigital(value) ? HIGH : LOW);
} else {
analogWrite(stimulationPin, value);
}
}
void loop() {
for (uint16_t i = 0; i < PATTERN_SIZE; i++) {
uint8_t stimulationValue = pgm_read_byte(&stimulation_pattern[i]);
analogWrite(stimulationPin, stimulationValue);
// Print the current stimulation value for debugging
Serial.print("Applying stimulation: ");
writeOutput(stimulationValue);
// Print the value based on the mode
if (USE_DIGITAL) {
Serial.println(analogToDigital(stimulationValue) ? 255 : 0);
} else {
Serial.println(stimulationValue);
delay(delayBetweenStimulations);
}
// Add a longer delay at the end of each complete pattern
delay(1000);
delayMicroseconds(delayBetweenStimulations);
}
// Remove the long delay at the end to continuously send data
}

102
decode_serial_digit.py Normal file
View File

@ -0,0 +1,102 @@
import serial
import numpy as np
import matplotlib.pyplot as plt
from serial.tools import list_ports
import time
import sys
# Serial port configuration
DEFAULT_PORT = 'COM20'
BAUD_RATE = 115200
TIMEOUT = 5 # 5 seconds timeout
# MNIST digit size
DIGIT_SIZE = 28
def find_arduino_port():
ports = list_ports.comports()
for port in ports:
if 'Arduino' in port.description:
return port.device
return None
def read_serial_data(port, baud_rate, timeout):
try:
with serial.Serial(port, baud_rate, timeout=timeout) as ser:
print(f"Connected to {port}")
data = []
start_time = time.time()
while len(data) < DIGIT_SIZE * DIGIT_SIZE:
if time.time() - start_time > timeout:
print("Timeout: No data received for 5 seconds.")
break
try:
line = ser.readline().decode('ascii').strip()
if line:
value = int(line)
if 0 <= value <= 255: # Ensure value is in valid range
data.append(value)
start_time = time.time() # Reset the timeout
else:
print(f"Warning: Received out-of-range value: {value}. Skipping.")
except (UnicodeDecodeError, ValueError) as e:
print(f"Received invalid data: {e}. Skipping.")
return np.array(data)
except serial.SerialException as e:
print(f"Error opening serial port {port}: {e}")
return np.array([])
def plot_digit(data):
if len(data) < DIGIT_SIZE * DIGIT_SIZE:
print(f"Warning: Received only {len(data)} data points. Padding with zeros.")
data = np.pad(data, (0, DIGIT_SIZE * DIGIT_SIZE - len(data)), 'constant')
digit = data.reshape(DIGIT_SIZE, DIGIT_SIZE)
# Create a larger figure (doubled size)
plt.figure(figsize=(10, 10))
plt.imshow(digit, cmap='gray', interpolation='nearest')
plt.title("Decoded Digit", fontsize=24)
plt.axis('off')
# Add text annotations for each pixel value
for i in range(DIGIT_SIZE):
for j in range(DIGIT_SIZE):
value = digit[i, j]
plt.text(j, i, f'{value}', ha='center', va='center', color='red', fontsize=6)
plt.tight_layout()
plt.show()
def main():
port = DEFAULT_PORT
if not serial.tools.list_ports.comports(include_links=False):
print("No serial ports found. Please check your connections.")
return
if DEFAULT_PORT not in [p.device for p in serial.tools.list_ports.comports()]:
print(f"Warning: {DEFAULT_PORT} not found. Attempting to find Arduino port.")
port = find_arduino_port()
if not port:
print("Arduino not found. Please specify the COM port manually.")
return
print("Reading data from serial port...")
data = read_serial_data(port, BAUD_RATE, TIMEOUT)
if len(data) > 0:
print(f"Received {len(data)} data points. Plotting digit...")
plot_digit(data)
else:
print("No data received. Please check the Arduino connection and code.")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\nScript terminated by user.")
except Exception as e:
print(f"An unexpected error occurred: {e}")
finally:
print("Script execution completed.")
sys.exit(0)

2
stimulation_pattern.h Normal file
View File

@ -0,0 +1,2 @@
const PROGMEM uint8_t stimulation_pattern[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 148, 209, 253, 253, 113, 87, 148, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 232, 252, 253, 189, 209, 252, 252, 253, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 57, 242, 252, 190, 65, 5, 12, 182, 252, 253, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 252, 252, 183, 14, 0, 0, 92, 252, 252, 225, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 253, 252, 145, 14, 0, 0, 0, 215, 252, 252, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 253, 246, 176, 9, 0, 0, 8, 78, 245, 253, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 232, 252, 176, 0, 0, 0, 36, 201, 252, 252, 169, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 252, 252, 30, 22, 119, 197, 241, 253, 252, 250, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 231, 252, 253, 252, 252, 252, 226, 227, 252, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 234, 253, 217, 137, 42, 24, 192, 252, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 255, 253, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 253, 252, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 252, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 253, 252, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 253, 252, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 255, 253, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 252, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 252, 189, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 184, 252, 169, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 146, 252, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const uint16_t PATTERN_SIZE = 784;

23
visualize_digit.py Normal file
View File

@ -0,0 +1,23 @@
def visualize_digit(pattern):
# Define ASCII characters for different intensity levels
chars = ' .:-=+*#%@'
# Convert the pattern to a 28x28 grid
grid = [pattern[i:i+28] for i in range(0, len(pattern), 28)]
# Create the visualization
visualization = ''
for row in grid:
for pixel in row:
# Map the pixel value (0-255) to an ASCII character
char_index = min(int(pixel / 28), 9)
visualization += chars[char_index]
visualization += '\n'
return visualization
# The stimulation pattern from stimulation_pattern.h
stimulation_pattern = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 148, 209, 253, 253, 113, 87, 148, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, 232, 252, 253, 189, 209, 252, 252, 253, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 57, 242, 252, 190, 65, 5, 12, 182, 252, 253, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 252, 252, 183, 14, 0, 0, 92, 252, 252, 225, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 253, 252, 145, 14, 0, 0, 0, 215, 252, 252, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 253, 246, 176, 9, 0, 0, 8, 78, 245, 253, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 232, 252, 176, 0, 0, 0, 36, 201, 252, 252, 169, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 252, 252, 30, 22, 119, 197, 241, 253, 252, 250, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 231, 252, 253, 252, 252, 252, 226, 227, 252, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 234, 253, 217, 137, 42, 24, 192, 252, 143, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 255, 253, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 253, 252, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 253, 252, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 253, 252, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 253, 252, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 255, 253, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 252, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 252, 189, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 184, 252, 169, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 146, 252, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# Visualize the digit
print(visualize_digit(stimulation_pattern))