Help please - Utilising Capacitive Sensor & Images

edited March 2017 in Arduino

Hello,

I am trying to make a capacitive sensor display a random image each time my sensor is held down.

I have added all the images I want to be included in this randomisation, however when my sensor is held down it skips constantly through all of my images when I infect just want one to be displayed at a time.

The key thing I want to keep is the fact that the sensor has to be held down and not pressed.

I'd greatly appreciate any help.

Here is my Arduino code:

#include <CapacitiveSensor.h>

CapacitiveSensor   cs_4_2 = CapacitiveSensor(4,2);             

void setup(){

  cs_4_2.set_CS_AutocaL_Millis(0xFFFFFFFF);     
  Serial.begin(9600);
}

void loop(){

  long start = millis();
  long total1 =  cs_4_2.capacitiveSensor(30);

  Serial.println(total1); 


  delay(10);                              
} 

Here is my Processing code:

import processing.serial.*;

int touch1Value = 0;

int threshold = 30;

PImage p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25;
PImage [] picArray = new PImage [26];

Serial myPort;

void setup(){

  background (255,255,255);

  size (500,500);

  myPort = new Serial(this, Serial.list()[1], 9600);

  myPort.bufferUntil('\n');

  p0 = loadImage("0.png");
  p1 = loadImage("1.png");
  p2 = loadImage("2.png");
  p3 = loadImage("3.png");
  p4 = loadImage("4.png");
  p5 = loadImage("5.png");
  p6 = loadImage("6.png");
  p7 = loadImage("7.png");
  p8 = loadImage("8.png");
  p9 = loadImage("9.png");
  p10 = loadImage("10.png");
  p11 = loadImage("11.png");
  p12 = loadImage("12.png");
  p13 = loadImage("13.png");
  p14 = loadImage("14.png");
  p15 = loadImage("15.png");
  p16 = loadImage("16.png");
  p17 = loadImage("17.png");
  p18 = loadImage("18.png");
  p19 = loadImage("19.png");
  p20 = loadImage("20.png");
  p21 = loadImage("21.png");
  p22 = loadImage("22.png");
  p23 = loadImage("23.png");
  p24 = loadImage("24.png");
  p25 = loadImage("25.png");

  picArray[0] = p0;
  picArray[1] = p1;
  picArray[2] = p2;
  picArray[3] = p3;
  picArray[4] = p4;
  picArray[5] = p5;
  picArray[6] = p6;
  picArray[7] = p7;
  picArray[8] = p8;
  picArray[9] = p9;
  picArray[10] = p10;
  picArray[11] = p11;
  picArray[12] = p12;
  picArray[13] = p13;
  picArray[14] = p14;
  picArray[15] = p15;
  picArray[16] = p16;
  picArray[17] = p17;
  picArray[18] = p18;
  picArray[19] = p19;
  picArray[20] = p20;
  picArray[21] = p21;
  picArray[22] = p22;
  picArray[23] = p23;
  picArray[24] = p24;
  picArray[25] = p25;

  imageMode(CENTER);
}

void draw(){

  background (255,255,255);

  println("touch1Value:"+touch1Value);

  if (touch1Value == 1){

  image(picArray[int(random(picArray.length))], 250, 250);
  }
}

void serialEvent(Serial myPort){

  String inString = myPort.readStringUntil('\n');

  if (inString != null){

    inString = trim (inString);

    float[] touches = float (split(inString, ","));

    if (touches.length >=1){

    touch1Value = touches[0] >= threshold ? 1: 0;
    }
  }
}

Answers

  • A quick alternative to load your images below.

    Kf

    for(int i=0;i<picArray.length;i++)
      picArray[i]=loadImage(i + ".png");
    
  • Choose your random value inside your serialEvent() function instead of draw(). Added in line 102 for example.

    Kf

  • Is it possible you could show me an example of what you mean

    Many Thanks

  • edited March 2017
    void serialEvent(Serial myPort){
    
      String inString = myPort.readStringUntil('\n');
    
      if (inString != null){
    
        inString = trim (inString);
    
        float[] touches = float (split(inString, ","));
    
        if (touches.length >=1){
    
        touch1Value = touches[0] >= threshold ? 1: 0;
        }
    
        if (touch1Value == 1){
    
        image(picArray[int(random(picArray.length))], 250, 250);
      }
      }
    }
    

    this is my outcome, however it still appears to skip through images rather than stoping on one image when the sensor is held.

    I believe I need a way from stoping "touch1Value:1" from constantly appearing.

  • Yes, using a boolean flag acting as a switch. Only switch to a new image if it resets back to zero. I am assuming ZERO is when your sensor is not active. Like this below.

    NOTE: Keep your action on the canvas inside your draw function. I suggest to use a variable to hold your current image index.

    Kf

    boolean holdImage=false;
    int imgIndex;
    
    
    void serialEvent(Serial myPort) {
    
      String inString = myPort.readStringUntil('\n');
    
      if (inString != null) {
    
        inString = trim (inString);
        float[] touches = float (split(inString, ","));
    
        if (touches.length >=1) {
          touch1Value = touches[0] >= threshold ? 1: 0;
    
          if (touch1Value == 1) {
            if (holdImage == false) {
              imgIndex=int(random(picArray.length));
              holdImage=true;
            }
          } else
            holdImage=false;  //RELEASE holder so to detect next usr press event
        }
      }
    }
    
  • Im very new to processing, could you possibly give me an example of how all the code should look.

    Could you also state what variable I should use.

    Sorry for being a noob, I've literally been using this software for less that 24hours :D

  • Answer ✓

    This next code is not tested as I do not have an arduino setup atm. Not sure if you need the comma "," when processing receiving bytes and as I mentioned in a previous post.

    Make of a habit to declare size() as the first line of setup() function.

    You might want to become familiar with the following functions:

    https://processing.org/reference/imageMode_.html
    https://processing.org/reference/PImage_resize_.html

    Kf

    import processing.serial.*;
    
    int threshold = 30; 
    PImage [] picArray = new PImage [26]; 
    Serial myPort;
    
    boolean holdImage=false;
    int imgIndex;
    
    void setup() {
      size (500, 500);
    
      for (int i=0; i<picArray.length; i++)
        picArray[i]=loadImage(i + ".png");
    
      myPort = new Serial(this, Serial.list()[1], 9600);
      myPort.bufferUntil('\n');
    }
    
    
    void draw() {
    
      background (255, 255, 255); 
      if (holdImage==true) { 
        image(picArray[imgIndex], 0,0);
      }
    }
    
    
    void serialEvent(Serial myPort) {
    
      String inString = myPort.readStringUntil('\n');
    
      if (inString != null) {
    
        inString = trim (inString);
        float[] touches = float (split(inString, ","));
    
        if (touches.length >=1) {
          int touch1Value = touches[0] >= threshold ? 1: 0;
    
          if (touch1Value == 1) {
            if (holdImage == false) {
              imgIndex=int(random(picArray.length));
              holdImage=true;
            }
          } else
            holdImage=false;  //RELEASE holder so to detect next usr press event
        }
      }
    }
    
  • Thank you, that's perfect!

  • Good example for learning! Very well done!

  • Hello,

    As it stands this code pics one randomised image from my data folder, whenever a capacitive sensor is held down.

    I am wanting to replace these images with video files however, I am not sure how to do this.

    Any help would be greatly appreciated!

    import processing.serial.*;
    
    int threshold = 30; 
    PImage [] picArray = new PImage [26]; 
    Serial myPort;
    
    boolean holdImage=false;
    int imgIndex;
    
    void setup() {
      size (500, 500);
    
      for (int i=0; i<picArray.length; i++)
        picArray[i]=loadImage(i + ".png");
    
      myPort = new Serial(this, Serial.list()[1], 9600);
      myPort.bufferUntil('\n');
    }
    
    
    void draw() {
    
      background (255, 255, 255); 
      if (holdImage==true) { 
        image(picArray[imgIndex], 0,0);
      }
    }
    
    
    void serialEvent(Serial myPort) {
    
      String inString = myPort.readStringUntil('\n');
    
      if (inString != null) {
    
        inString = trim (inString);
        float[] touches = float (split(inString, ","));
    
        if (touches.length >=1) {
          int touch1Value = touches[0] >= threshold ? 1: 0;
    
          if (touch1Value == 1) {
            if (holdImage == false) {
              imgIndex=int(random(picArray.length));
              holdImage=true;
            }
          } else
            holdImage=false;  //RELEASE holder so to detect next usr press event
        }
      }
    }
    
  • and another copy, in a thread a month old.

    if you have 4 different threads people won't know where to answer. so you'll get 4 different sets of answers, all different. and won't know what to do with them. you'll also piss off the moderators who have to clean up after you.

    please stop doing this.

This discussion has been closed.