viszualizers and digital output
This commit is contained in:
parent
96d23c1b59
commit
62f1861de0
|
@ -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: ");
|
||||
Serial.println(stimulationValue);
|
||||
writeOutput(stimulationValue);
|
||||
|
||||
delay(delayBetweenStimulations);
|
||||
// Print the value based on the mode
|
||||
if (USE_DIGITAL) {
|
||||
Serial.println(analogToDigital(stimulationValue) ? 255 : 0);
|
||||
} else {
|
||||
Serial.println(stimulationValue);
|
||||
}
|
||||
|
||||
delayMicroseconds(delayBetweenStimulations);
|
||||
}
|
||||
|
||||
// Add a longer delay at the end of each complete pattern
|
||||
delay(1000);
|
||||
// Remove the long delay at the end to continuously send data
|
||||
}
|
||||
|
|
102
decode_serial_digit.py
Normal file
102
decode_serial_digit.py
Normal 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
2
stimulation_pattern.h
Normal 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
23
visualize_digit.py
Normal 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))
|
Loading…
Reference in New Issue
Block a user