Due to high demand expect some shipping delays at this time, orders may not ship for 1-2 business days.
0

Completed: Tickle Brain
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Completed: Tickle Brain

by zenSutherland on Tue Aug 21, 2018 8:13 pm

I'm hoping that we're allowed to post our completed project and the forum isn't just for problem-solving (though it's been a great resource). If that's the case, sorry, please delete.

So for my first project I aspired to create a piece of art for a local art show about interactivity. The Tickle Brain runs off a Feather and a Capacitive Sense module interfaced with a hacked laugh machine. You tickle it in different spots and it laughs. The 'Brain' is a jello mold with copper tape on the inside connected to the Capacitive module. Lots o fun!

In the process I learned arrays and subroutine processing and a bunch of new things (I'm a programmer, but not in C++).

Image

Image

See it in action here (almost complete): https://vimeo.com/286096953

zenSutherland
 
Posts: 39
Joined: Fri Jul 27, 2018 11:50 am

Re: Completed: Tickle Brain

by adafruit_support_bill on Wed Aug 22, 2018 6:04 am

Nice project! Thanks for posting.

adafruit_support_bill
 
Posts: 81070
Joined: Sat Feb 07, 2009 10:11 am

Re: Completed: Tickle Brain

by AnneBarela on Wed Aug 22, 2018 11:44 am

Great project! I've written an Adafruit blog post that should be out in a couple mins. https://blog.adafruit.com/2018/08/22/fr ... -adafruit/

Folks might look to see what language you did it in, where did you get the brain & laugh module, etc.

Feel free to post completed projects on the forums, we love it and feature innovate ones from time to time.

AnneBarela
 
Posts: 748
Joined: Sat Mar 24, 2012 8:56 pm
Location: Mid-Atlantic

Re: Completed: Tickle Brain

by zenSutherland on Wed Aug 22, 2018 10:41 pm

I tend to ramble, so bear with me - if you want to know more about the project, it's probably best to skim for the detail goodies.

I hadn't picked up a soldering iron in over 30 years, so my first arduino project is messy and probably poorly programmed, but at least it works. In combing the local Goodwill pay-by-the-pound, I found this funny laugh toy, part medical therapy toy called Laffy Laffalot, intended to give to kids to help them through recovery or pain.
Image

I cracked it open, poked around and found i could trigger the laughs with a wire, so conceived of the project and ordered an Adafruit Feather 328p, the Capacitive Sense module and their Lithium-Ion battery. Since Laffy's circuitry ran off 3v, I thought that was the perfect match. When I breadboarded the project for proof of concept, the Laffy circuit was button driven in some way I could only get 7 laughs out of it and considered using small voltage relays to do the triggering of the 20 different laughs, but that just seemed too bulky, So I settled down to the 7 I could get to work with a digital pinout going HIGH.
Image
Image

I also bought a Jello 'brain mold' on eBay and a roll of copper peel-n-stick from a local gardening shop (used to keep slugs away).
Image

After soldering them I stuck them to the inside of the brain and wanted to get them as close to the insides as possible and found that a pencil eraser worked well for this. Synchronistically, it just so happened to be '#2 Pencil Day,' - not a well-known holiday.
Image

Looking for a suitable housing, I found the perfect solution from a plastic trash can with a swinging lid that could be removed and starting mounting things inside there. My soldering technique was ghastly and I had even mounted the pins on the wrong side of the Feather board and found later i couldn't get easily to the reset button. I had to use a micro-switch to RST to do the job for that and it worked out better because I could mount it where one could hit reset without taking off the brain-top. I upgraded the speaker for better sound. I lightly spray painted the inside of the brain to help hide some of the wiring, though it makes it a weird golden color instead of the flesh color i was aiming for. I also got creative with a lot of hot-glue to hold things in place and some white electrical tape to neaten it all up.
Image

Now came the programming, and i found that the while the capacitive touch doesn't require an actual touch, the margin of "almost touching" was pretty slim (measurement of 10-30 units). That was fine except it varied according to temperature and humidity somewhat and how the wires connecting them were arranged. So i finally hit on the idea of first measuring the initial values and plopping those values into an Array in the Setup Loop so that wherever i hit Reset, the relative difference would work fine and wouldn't require any "on site" adjustment.
Image

Here's the code, sloppy as it is and i left the diagnostic Serial.print code in there because it didn't take up much room. Hopefully, I've commented it well enough to get the idea. I set up timing delay Array and other arrays for pins and descriptions.

Code: Select all | TOGGLE FULL SIZE
/*********************************************************
  BRAIN LAFF
  This Sketch uses these boards:
    AdaFruit's Feather 328P
    MRP121 12-channel Capacative touch sensor (via I2C)
    The circuit board from Laffy Laffalot

  Purpose is to use the capacitive touch sensors attached to
  the inside of jello mold of a brain to detect human touch.
  When touch is detected, the controller sends a signal to the LAFFY
  circuit to generate a specific laugh. The Duration of the laugh
  a random pattern of LEDs flash in the brain.

  Pin Set
     Feather

     MRP121

     Laffy Laffalot Circuit board

**********************************************************/

#include <Wire.h>
#include "Adafruit_MPR121.h"
#include <Time.h>
#include <TimeLib.h>

// You can have up to 4 MRP121 boards on one i2c bus but one is enough for testing!
Adafruit_MPR121 cap = Adafruit_MPR121();

// ARRAYS FOR INPUT ---------------
//   DEFAULT Array for the sense threshhold for each capacative sensor
int TouchTrigger[12] = {144, 160, 148, 144, 148, 158, 148, 155, 100, 100, 100, 100};

//   Array to define pin position
int TouchPin[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};


//   Array to determine wait time for each laff so polling doesn't start until done
//    and display lasts same amount of time
//
// Change this to read several times, average and then subtract 15 from those values
//
int TouchWait[12] = {135, 150, 140, 150, 170, 140, 135, 150, 8000, 8000, 8000, 8000};


//  Array for display pins - Cribbed from Joshua Hrisko from engineersportal.com/blog/2018/2/2/arduino-randomly-blinking-multiple-leds-with-only-9-lines-of-code
int leds[6] = {A1, A2, A3, SCK, MOSI, 7};

// ARRAYS FOR OUTPUT (LED & Laughs)
char* LaffDesc[8] = {"Wheeze", "Fliss", "And so he", "High Woman", "Snort", "Child Giggle", "Multi-Children", "Random"};
int  Pin2Laff[8] = {4, 3, 2, 10, 9, 6, 5, 5};


void setup() {  // ------------------------------------ start SETUP  ----------------------------------
  Serial.begin(9600);
  // - Define Yellow signal pins (LEDs and On/Off) Relay to Laffy Circuit
  pinMode(A0, OUTPUT);
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(A3, OUTPUT);
  pinMode(A4, OUTPUT);
  pinMode(A5, OUTPUT);
  pinMode(A6, OUTPUT);
  pinMode(A7, OUTPUT);
  pinMode(7,  OUTPUT);
  pinMode(13,  OUTPUT);

  //   TURN OFF LAFFY FIRST!
  digitalWrite(A0, HIGH); // turn the Laffy circuit off by making the voltage HIGH

  // - Define Green Signal Pins to LAFFY
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  digitalWrite(4, LOW);    // turns the 4 LED/Signal LOW
  digitalWrite(3, LOW);    // turns the 3 LED/Signal LOW
  digitalWrite(2, LOW);    // turns the 2 LED/Signal LOWW
  digitalWrite(10, LOW);   // turns the 10 LED/Signal LOW
  digitalWrite(9, LOW);    // turns the 9 LED/Signal LOW
  digitalWrite(6, LOW);    // turns the 6 LED/Signal LOW
  digitalWrite(5, LOW);    // turns the 5 LED/Signal LOW


  // Define Display LED pins

  for (int jj; jj < sizeof(leds) / sizeof(int); jj++) {
    pinMode(leds[jj], OUTPUT);
    delay(10);
  }

  // Startup Sequence - FIRST TURN ON LAFFY

  delay(50);
  digitalWrite(A0, LOW);  // turn the Laffy circuit on by making the voltage LOW (Default)

  // PROGRAM Random LED flashes? Sequence
  LEDsequence ();

//  int TimerCount = 1;

  while (!Serial) { // needed to keep leonardo/micro from starting too fast!
    delay(10);
  }

  Serial.println("Adafruit MPR121 Capacitive Touch sensor test");

  // Default address is 0x5A, if tied to 3.3V its 0x5B
  // If tied to SDA its 0x5C and if SCL then 0x5D
  if (!cap.begin(0x5A)) {
    Serial.println("MPR121 not found, check wiring?");
    while (1);
  }
  Serial.println("MPR121 found!");

// SET touch sensitivity once to get an average for sensitivity
  LEDflash ();
delay(300);
  for (int i = 0; i < 8; i++) {
int j = cap.filteredData(i) - 13;
TouchTrigger[i] = j;
  }


 
}

void loop() {  // ------------------------------------------------------------------- start MAIN loop  --------------------------------------

  // Use the Timer and it's remainder to perform a POWER RESET on the Laffy to prevent timing out
  int TimerCount = now();
  int TimerReset = now() % 360; // Every 360 seconds

  // If the remainder hits zero, Reset the the power to the Laff Circuit
  if (TimerReset == 0) {
    Serial.println("-------------------- POWER RESET -----------------");
    delay(250);
    digitalWrite(A0, HIGH);  // turn the Laffy circuit on by making the voltage LOW (Default)
    delay(700);

    LEDsequence (); // Perform a light display to give it time to acknowledge off/on
    LEDsoff ();    // Make sure all LEDs are off
    digitalWrite(A0, LOW);  // turn the Laffy circuit on by making the voltage LOW (Default)
  }

  // Display for testing

  Serial.print("Seconds: ");
  Serial.print(TimerCount);
  Serial.print(":");
  Serial.print(TimerReset);
  for (int i = 0; i < 8; i++) {
    Serial.print("   ");
        Serial.print("(");
    Serial.print(i);
    Serial.print(")");
    Serial.print(cap.filteredData(i));
    Serial.print("-");
    Serial.print(TouchTrigger[i]);
  }


  // -------- MAIN sensing loop ----- also, trigger testing display to show data when triggered
 
  for (int i = 0; i < 8; i++) {
    if (cap.filteredData(i) < TouchTrigger[i]  && cap.filteredData(i) != 0) {
      Serial.println();
      Serial.println("-------------------------------------- BEGIN SIGNAL --------------------");
      Serial.println(LaffDesc[i]);
      Serial.print("* TouchPin = "); Serial.println(TouchPin[i]);
      Serial.print("filteredData = "); Serial.println(cap.filteredData(i));
      Serial.print("Signal sent to "); Serial.println(Pin2Laff[i]);
      Serial.print("Wait time: "); Serial.println(TouchWait[i]);
      // Actually signal the pin

      // --------------- Pad 7 is a random laugh of one of the other laughs
      if (i == 7) {
        int x = random(0, 5);
        digitalWrite(Pin2Laff[x], HIGH);    // turn the LED on by making the voltage HIGH
        delay(800);
        digitalWrite(Pin2Laff[x], LOW);    // turn the LED on by making the voltage OFFa
      }
      else {
        digitalWrite(Pin2Laff[i], HIGH);    // turn the LED on by making the voltage HIGH
        delay(600);
        digitalWrite(Pin2Laff[i], LOW);    // turn the LED on by making the voltage OFF
        //    delay(60);
        //        digitalWrite(Pin2Laff[i], HIGH);    // turn the LED on by making the voltage HIGH
      }

      Serial.print("-------------------------------------- END SIGNAL --------------------");

      // Random Light Display with wait time
      LEDrandom ();

      // Reset the Laffy Circuit?

//  digitalWrite(A0, HIGH);  // turn the Laffy circuit on by making the voltage LOW (Default)
//        delay(50);
//  digitalWrite(A0, LOW);  // turn the Laffy circuit on by making the voltage LOW (Default)

      // Turn off all the LEDs

LEDsoff ();
    }
  }

//  delay(200);
  Serial.println();


}
// ------------------------------------------------- SUBROUTINES - FUNCTIONS ----------------------

// LED FLASH Function - On/Off one at a time
void LEDflash () {
  for (int i = 0; i < 6; i++) {
    for (int ii = 0; ii < 5; ii++) {
      digitalWrite(leds[i], HIGH);    //
      delay(100);
      digitalWrite(leds[i], LOW);    //
      delay(100);
    }
  }
}

// LED SEQUENCE Function -  off and on in sequence
void LEDsequence () {
  for (int ii = 0; ii < 4; ii++) {
    for (int i = 0; i < 6; i++) {
      digitalWrite(leds[i], HIGH);    //
      delay(100);
    }
    delay(100);
    for (int i = 0; i < 6; i++) {
      digitalWrite(leds[i], LOW);    //
      delay(100);
    }
  }
}

// LED RANDOM Function - turn off and on (mostly off) of random LEDs
void LEDrandom () {
  for (int x = 0; x < TouchWait[5]; x++) {
    digitalWrite(leds[random(0, sizeof(leds) / sizeof(int))], HIGH);
    delay(random(5, 40));
    for (int xx = 0; xx < 2; xx++) {
      digitalWrite(leds[random(0, sizeof(leds) / sizeof(int))], LOW);
      delay(random(5, 30));
    }
  }
}
// LED LEDOFF Function - turn all LEDs Off
void LEDsoff () {      // Turn off all the LEDs
      for (int x = 0; x < 6; x++) {
        digitalWrite(leds[x], LOW);
      }
}


So, that's pretty much it, and now it sits at the Transylvania Arts Council gallery in their Interactive Arts Exhibit, which opens this upcoming Friday. I honestly wonder how people will react to it. Friends i've shown it to (to also test their capacitive differences) seem to vary in their reactions from "not comfortable tickling a brain" to "you're a madman!" (Which i take as a compliment). We'll see how the opening goes!
Image
Image

Closer action video: https://www.flickr.com/photos/zen/30340492568/

Feel free to ask any questions about the construction or code, I'll gladly share my errors and successes! And a big thanks to MikeBarela https://forums.adafruit.com/memberlist.php?mode=viewprofile&u=46706 for posting this elsewhere!

-z

zenSutherland
 
Posts: 39
Joined: Fri Jul 27, 2018 11:50 am

Please be positive and constructive with your questions and comments.