viszualizers and digital output
This commit is contained in:
parent
96d23c1b59
commit
62f1861de0
|
@ -1,26 +1,46 @@
|
||||||
#include <avr/pgmspace.h>
|
#include <avr/pgmspace.h>
|
||||||
#include "stimulation_pattern.h"
|
#include "stimulation_pattern.h"
|
||||||
|
|
||||||
const int stimulationPin = 5;
|
const bool DEBUG = true; // Set to true to enable serial output
|
||||||
const int delayBetweenStimulations = 10; // milliseconds
|
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() {
|
void setup() {
|
||||||
pinMode(stimulationPin, OUTPUT);
|
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() {
|
void loop() {
|
||||||
for (uint16_t i = 0; i < PATTERN_SIZE; i++) {
|
for (uint16_t i = 0; i < PATTERN_SIZE; i++) {
|
||||||
uint8_t stimulationValue = pgm_read_byte(&stimulation_pattern[i]);
|
uint8_t stimulationValue = pgm_read_byte(&stimulation_pattern[i]);
|
||||||
analogWrite(stimulationPin, stimulationValue);
|
|
||||||
|
|
||||||
// Print the current stimulation value for debugging
|
writeOutput(stimulationValue);
|
||||||
Serial.print("Applying stimulation: ");
|
|
||||||
|
// Print the value based on the mode
|
||||||
|
if (USE_DIGITAL) {
|
||||||
|
Serial.println(analogToDigital(stimulationValue) ? 255 : 0);
|
||||||
|
} else {
|
||||||
Serial.println(stimulationValue);
|
Serial.println(stimulationValue);
|
||||||
|
|
||||||
delay(delayBetweenStimulations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a longer delay at the end of each complete pattern
|
delayMicroseconds(delayBetweenStimulations);
|
||||||
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