Update and Code Dump

 I spent a little bit of time today trying new versions of the shapes on fusion / illustrator and still haven't gotten it quite right. Tomorrow, I'm going to spend as long as it takes until its correct. Woohoo! 

It has been really frustrating so I took a break from measuring over the course of the week and researched some code that I will need to move forward once I have the correct circuit board. Most of it is a collaboration of chatgpt and my edits, and it will require more edits once I have all the parts and it is working for real, but I'm going to dump my drafts here. 


This is the hypothetical sequence to turn the connection signals into the actual characters with 5 shift registers. I know I found some code online for this before, but that was designed for switches and this involves pull-up resistors so it should be debounced: 

// Pin configuration for the shift registers
const int latchPin = 9;  // Latch pin connected to Arduino pin 9
const int clockPin = 10; // Clock pin connected to Arduino pin 10
const int dataPin = 8;   // Data pin connected to Arduino pin 8

// Array to store the values from the shift registers (5 registers, 8 bits each)
byte keyValues[5];  // 5 shift registers, each with 8 keys (total of 40 keys)

// Key characters corresponding to the keys (A-Z, 1-9)
const char keyCharacters[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
                              'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7',
                              '8', '9'};

// Buffer to store pressed keys in order
String pressedKeys = "";  

// Setup function to initialize the serial communication and pins
void setup() {
  Serial.begin(9600);  // Start serial communication at 9600 baud rate
  
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, INPUT_PULLUP);  // Enable internal pull-up resistor for the data pin
  
}

// Main loop
void loop() {
  // Read the keys from the shift registers
  readShiftRegisters();
  
  // Check each bit in the shift registers to see if it's pressed
  for (int i = 0; i < 5; i++) {  // Loop through the shift registers (5 in total)
    for (int bit = 0; bit < 8; bit++) {  // Loop through each bit in the shift register (8 bits per register)
      if (bitRead(keyValues[i], bit) == LOW) {  // If the key is pressed (active LOW)
        // Add the corresponding character to the buffer in order
        pressedKeys += keyCharacters[i * 8 + bit];  
      }
    }
  }

  // If we have any keys in the buffer, print them in order and reset the buffer
  if (pressedKeys.length() > 0) {
    Serial.println(pressedKeys);  // Print the pressed keys in order
    pressedKeys = "";  // Clear the buffer
  }
  
  delay(100);  // Small delay to avoid too many serial prints
}

// Function to read data from the shift registers
void readShiftRegisters() {
  // Pulse the latch pin to store the current state of the shift registers
  digitalWrite(latchPin, LOW);  // Begin latching
  delayMicroseconds(5);
  digitalWrite(latchPin, HIGH); // End latching
  
  // Read the values from all 5 shift registers (one byte per register)
  keyValues[0] = shiftIn(dataPin, clockPin, MSBFIRST);  // Read first shift register (8 keys)
  keyValues[1] = shiftIn(dataPin, clockPin, MSBFIRST);  // Read second shift register (8 keys)
  keyValues[2] = shiftIn(dataPin, clockPin, MSBFIRST);  // Read third shift register (8 keys)
  keyValues[3] = shiftIn(dataPin, clockPin, MSBFIRST);  // Read fourth shift register (8 keys)
  keyValues[4] = shiftIn(dataPin, clockPin, MSBFIRST);  // Read fifth shift register (8 keys)
}


This is how I could get the interpreted text into touch designer (using textblob):

 import time
from textblob import TextBlob
from pythonosc import udp_client

# Set up the OSC client to send messages to TouchDesigner
osc_client = udp_client.SimpleUDPClient("127.0.0.1", 8000)  # TouchDesigner listens on this port

def analyze_sentiment(text):
    # Use TextBlob to perform sentiment analysis
    blob = TextBlob(text)
    
    # Get the polarity and subjectivity from TextBlob
    polarity = blob.sentiment.polarity  # Polarity ranges from -1 (negative) to +1 (positive)
    subjectivity = blob.sentiment.subjectivity  # Subjectivity ranges from 0 (objective) to 1 (subjective)
    
    print(f"Text: {text}")
    print(f"Polarity: {polarity}, Subjectivity: {subjectivity}")
    
    # Send the polarity score to TouchDesigner (for light control, etc.)
    osc_client.send_message("/sentiment", polarity)

def get_text_from_arduino():
    # Placeholder: Replace this with actual serial code to read from Arduino
    # For now, just using some example text
    text = "I love this project!"  # Example text, replace with actual Arduino input
    return text

if __name__ == "__main__":
    while True:
        # Get the text from Arduino
        text = get_text_from_arduino()
        
        # Analyze the sentiment of the text using TextBlob
        analyze_sentiment(text)
        
        # Wait a short while before reading the next text
        time.sleep(1)  # Adjust time as needed

And here's the chatgpt suggestions on what to do inside of touch designer: 

3.1: Creating a Basic TouchDesigner Project

  1. Open TouchDesigner and create a new project.
  2. Add an OSC In DAT:
    • In the Network editor, right-click and add an OSC In DAT.
    • In the Parameters panel of the OSC In DAT, set the Network Port to 8000 (or the port you've chosen in the Python script).
  3. The OSC In DAT will receive the sentiment polarity values from Python.

3.2: Control Lights with Sentiment Data

  1. The OSC In DAT will contain the OSC messages being sent from Python (like /sentiment).
  2. You can use this polarity value to control the color, intensity, or other properties of lights in TouchDesigner.
    • Example: If the polarity score is positive (greater than 0), you can make the light green; if it's negative (less than 0), you can make it red.

3.3: Create a Light and Control Its Color

  1. Add a Point Light to your TouchDesigner scene.
  2. Add a Math CHOP to scale the polarity score:
    • Connect the OSC In DAT to the Math CHOP to normalize the sentiment values (e.g., mapping the -1 to 1 range of polarity to a 0-1 range for color).
  3. Connect the Math CHOP output to the color parameter of the Point Light.

Example: Simple Light Control Based on Polarity:

  1. Add a Point Light in the scene.
  2. Add an Import CHOP to import the OSC data from the OSC In DAT.
  3. Use a Math CHOP to scale the polarity score to control the light’s RGB color:
    • Positive polarity: set light to green.
    • Negative polarity: set light to red.

You could also modify the brightness or intensity of the light based on the subjectivity value (higher subjectivity could increase brightness, for example).

I am planning on ordering LED strips, so I'd have to go more specifically in that direction in touch designer. 


There's also a completely different avenue that doesn't involve touch designer at all. This is much simpler, and wouldn't produce the smooth end result that I want, but might be better if I am approaching this is a "first iteration." This is a simple example that just provides three solid color options for three different moods (obviously I want more, but this is a start): 

#include <Adafruit_NeoPixel.h>

#define PIN            6    // Pin connected to the data input of the LED strip
#define NUMPIXELS      60   // Number of LEDs in the strip

Adafruit_NeoPixel strip(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(9600);  // Initialize serial communication at 9600 baud rate
  strip.begin();       // Initialize the strip
  strip.show();        // Initialize all pixels to 'off'
}

void loop() {
  if (Serial.available() > 0) {
    float polarity = Serial.parseFloat();  // Read the polarity value from Python (sent via serial)

    // Map the polarity to color:
    // Polarity ranges from -1 (negative) to 1 (positive)
    // Neutral = 0, Negative = -1, Positive = 1
    if (polarity > 0) {
      // Positive sentiment: Green
      setColor(0, polarity * 255, 0); // Increase green intensity as polarity increases
    }
    else if (polarity < 0) {
      // Negative sentiment: Red
      setColor(-polarity * 255, 0, 0); // Increase red intensity as polarity decreases
    }
    else {
      // Neutral sentiment: Blue
      setColor(0, 0, 255);  // Use blue for neutral sentiment
    }

    strip.show();  // Update the strip with the new color
  }
}

void setColor(int red, int green, int blue) {
  // Loop through each pixel and set the color
  for (int i = 0; i < NUMPIXELS; i++) {
    strip.setPixelColor(i, strip.Color(red, green, blue));
  }
}




Comments

Popular posts from this blog

Week 6 Update

Week 4 Update