[Solved] Skinner box project

Hello everyone,

I’m trying to make a skinner box variant for cats. The goal is for them to push a button and then food is delivered.

There are several schemes according to which I want them to press the button before they get food.

One of them is a random scheme. So a random number is set, the cat has to press the button that many times, it gets food and then the whole loop starts again with a different random number.

I have tried to configure that with the randomSeed() function… but I don’t know how to get a single random number per loop. It just keeps on spewing out random numbers.

So basically, what I want to know, is how to make the random() function just give me one random number.

Thank you

This is the code, I’ve highlighted the problem part

/*
This code requires a random amount of button presses before activating a servo sweep

*/

// this constant won’t change:
const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPin = 13; // the pin that the LED is attached to
#include <Servo.h>
Servo myservo; // create servo object to control a servo
// a maximum of eight servo objects can be created

int pos = 0; // variable to store the servo position

// Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int currentTrial = 0;
int lastTrial = 0;
boolean currentButton = LOW; // current state of the button
boolean lastButton = LOW; // previous state of the button
boolean ledState = LOW; // initial led state
long randNumber; // random number

void setup() {

pinMode(buttonPin, INPUT); // initialize the button pin as a input:
pinMode(ledPin, OUTPUT); // initialize the LED as an output:
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo.write(0); // brings servo to begin position
Serial.begin(9600); // initialize serial communication:
digitalWrite(ledState, LOW); // turn led of at beginning
randomSeed(analogRead(0)); //random input from analog noise

}

boolean debounce(boolean last)
{
boolean current = digitalRead(buttonPin);
if (last != current)
{
delay(5);
current = digitalRead(buttonPin);
}
return current;

}

void loop() {
currentTrial = lastTrial + 1;
if (currentTrial != lastTrial)
{
Serial.print("Trial: ");
Serial.println(currentTrial);
Serial.end();
}

do
{

currentButton = debounce(lastButton);

if (currentButton != lastButton) // compare the buttonState to its previous state
{
if (currentButton == HIGH) // if the state has changed, increment the counter
{
buttonPushCounter++; // if the current state is HIGH then the button went from off to on:
Serial.begin(9600);
Serial.print("Number of button pushes: ");
Serial.println(buttonPushCounter);
}

}
lastButton = currentButton; // save the current state as the last state, for next time through the loop

if (currentButton == HIGH){
digitalWrite(ledPin, HIGH);}
else {
digitalWrite(ledPin, LOW);

{
randNumber = random(1, 20);
delay(150);
}
Serial.println(randNumber);
if (buttonPushCounter == randNumber) {
Serial.println(“food delivery”);
Serial.println(" “);
Serial.println(” ");
delay(100);
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(4); // waits 4ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(6); // waits 6ms for the servo to reach the position
}
delay(50);
buttonPushCounter = 0;
} else {
digitalWrite(ledPin, LOW);
}

}
}
while(currentTrial != lastTrial);
}

Get rid of the excessive white space. Use Tools + Auto Format to properly indent your code. Add some comments to explain what each block of code is doing.

  currentTrial = lastTrial + 1;
 if (currentTrial != lastTrial)

After assigning a value to currentTrial that is not equal to lastTrial, there isn't a snowball's chance in hell that the if text will not be true.

      Serial.begin(9600);

Every time you need to print? NO!

        if (currentButton == HIGH)    // if the state has changed, increment the counter
        {
           buttonPushCounter++;        // if the current state is HIGH then the button went from off to on:
      Serial.begin(9600);
      Serial.print("Number of button pushes:  ");
      Serial.println(buttonPushCounter);
    } 
    
  }
    lastButton = currentButton;          // save the current state as the last state, for next time through the loop

  if (currentButton == HIGH){

Why are there two blocks comparing currentButton to HIGH? If the current state of the switch matters, put all the code together.

  {
   randNumber = random(1, 20);
     delay(150);
  }

Useless curly braces. Every time the switch is released, generate a new random number.

The cats are going to piss all over your carpets and shred your furniture!

Thank you for your reply.

I’m sorry for the messy code.
I just found out about the arduino world two days ago, so I’m not familiar with writing code in a neat way.
What I have is just a result from combining several different codes together.
I have incorporated some of your comments, thank you

Any way, posting this problem here kind of helped me in the sense that all of a sudden I knew how to solve the problem.

So no help needed anymore, sorry for wasting your time.

I will put the new code here as the forum rules suggested.

The part that I changed is highlighted.
I put the random() function before the do, while loop
Very simple, but it worked.

Apparently I had the random funtion just in the wrong part of the code

/*
This code requires a random amount of button presses before activating a servo sweep
*/

// this constant won’t change:
const int buttonPin = 2; // the pin that the pushbutton is attached to
const int ledPin = 13; // the pin that the LED is attached to
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position

// Variables will change:
int buttonPushCounter = 0; // counter for the number of button presses
int currentTrial = 0;
int lastTrial = 0;
boolean currentButton = LOW; // current state of the button
boolean lastButton = LOW; // previous state of the button
boolean ledState = LOW; // initial led state
long randNumber; // random number

void setup() {
pinMode(buttonPin, INPUT); // initialize the button pin as a input:
pinMode(ledPin, OUTPUT); // initialize the LED as an output:
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo.write(0); // brings servo to begin position
Serial.begin(9600); // initialize serial communication:
digitalWrite(ledState, LOW); // turn led of at beginning
randomSeed(analogRead(0)); //random input from analog noise
}

boolean debounce(boolean last)
{
boolean current = digitalRead(buttonPin);
if (last != current)
{
delay(5);
current = digitalRead(buttonPin);
}
return current;
}

void loop() {
currentTrial = lastTrial + 1;
Serial.print("Trial: ");
Serial.println(currentTrial);
randNumber = random(1, 30);
delay(5);
Serial.print("Required amount of pushes: “);
Serial.println(randNumber);
Serial.println(” ");
do
{
currentButton = debounce(lastButton);
if (currentButton != lastButton) // compare the buttonState to its previous state
{
if (currentButton == HIGH) // if the state has changed, increment the counter
{
buttonPushCounter++; // if the current state is HIGH then the button went from off to on:
Serial.print("Number of button pushes: “);
Serial.println(buttonPushCounter);
digitalWrite(ledPin, HIGH);
}
lastButton = currentButton; // save the current state as the last state, for next time through the loop
}
else {
digitalWrite(ledPin, LOW);
if (buttonPushCounter == randNumber) {
Serial.println(“food delivery”);
Serial.println(” “);
Serial.println(” ");
delay(100);
for(pos = 0; pos < 180; pos += 1) // goes from 0 degrees to 180 degrees
{ // in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(4); // waits 4ms for the servo to reach the position
}
for(pos = 180; pos>=1; pos-=1) // goes from 180 degrees to 0 degrees
{
myservo.write(pos); // tell servo to go to position in variable ‘pos’
delay(6); // waits 6ms for the servo to reach the position
}
delay(50);
buttonPushCounter = 0;
lastTrial = currentTrial;
}
else {
digitalWrite(ledPin, LOW);
}
}
}
while(currentTrial != lastTrial);
}