Communication and Servo for a two-unit dog feed device?

Hello. This is my first time doing any kind of Arduino project. But I’m doing this for a brother. This project entails two devices. The first unit, which should be as small as possible, uses a Teensy, a breadboard, a motion detector, and a transmitter. It’s attached to the door frame of the door to his apartment. It will also have an installed “power pack” adaptor, to allow for charging via USB, since it has to be able to run wirelessly.

Here’s the code I have for it…

// Include VirtualWire library
#include <VirtualWire.h>
 
// Define pins
const int led_pin = 13;
const int transmit_pin = 12;
const int sensor_pin = 7;
 
int sensor_value;
 
void setup()
{
   // Init
   vw_set_tx_pin(transmit_pin);
   vw_setup(2000); // Transmission rate
   pinMode(led_pin, OUTPUT);
   pinMode(sensor_pin,INPUT);
}
 
void loop()
{
   // Get sensor value
   sensor_value = digitalRead(sensor_pin);
 
   // Init message
   char msg[1] = {'0'};
 
   // Change message if motion is detected
   if (sensor_value == 1){
      msg[0] = '1';
   }
 
   // Transmit data every second
   digitalWrite(led_pin, HIGH); // Flash a light to show transmitting
   vw_send((uint8_t *)msg, 3);
   vw_wait_tx(); // Wait until the whole message is gone
   digitalWrite(led_pin, LOW);
   delay(1000);
}

Ok, so then there’s the second unit. I just can’t figure out it yet…

It includes an Arduino Uno, a receiver, a breadboard, a connection via USB (from a USB-charging device plugged into a wall), and more importanlty, a servo.

The way it’s supposed to work, when it picks up a signal, the servo turns. Because the servo will be attached to a disk with a hole in it in that’s blocking kibbles that will go down a chute. The idea is when someone walks past the door, this easily excitable dog gets some food, so she doesn’t bark.

Here’s what I have so far for this code…it’s definitely incomplete. Any ideeas? Anyone know Servos or Virtual Wire?

// Include VirtualWire library
#include <VirtualWire.h>
//And don't forget the Servo
#include <SoftwareServo.h>
 
SoftwearServo thisservo; //Servo object

// Pins definition
const int led_pin = 13;
const int transmit_pin = 12;
const int receive_pin = 11;
const int servo_pin = ??; //will have to get the pin number
 
void setup()
{
   // Init
   delay(1000);
   Serial.begin(9600); // Debugging only
   Serial.println("setup");
 
   // Initialise the IO and ISR
   vw_set_rx_pin(receive_pin);
   vw_setup(2000); // Transmission rate
 
   // Start the receiver PLL
   vw_rx_start();
 
   // Set LED pin
   pinMode(led_pin, OUTPUT);

   // set Servo pin
   thisservo.attach(servo_pin);

      // Init
   delay(1000);
   Serial.begin(9600); // Debugging only
   Serial.println("setup");
 
   // Initialise the IO and ISR
   vw_set_rx_pin(receive_pin);
   vw_setup(2000); // Transmission rate
 
   // Start the receiver PLL
   vw_rx_start();
}

void loop()
{
//sorry, how do you make a servo work? Still trying to figure what's the basic way to dictate its "forms"?
//if "1" is received, the servo turns a bit then turns back (dog food dispenser)
for(pos = 0; pos < 90; pos += 1)  // goes from 0 degrees to 90 degrees
  {                                  // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for(pos = 90; pos>=1; pos-=1)     // goes from 90 degrees to 0 degrees
  {                                
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  } 
//if "0" is received, nothing happens
}

Any ideas how to make this work? I mean codewise?

Thank you so much in advance!

Re: the servo code … you’re on the right track but there are a few mistakes, and perhaps some other things I’d do differently. First why are you using the SoftwareServo library ? For what you’re doing the normal (already included) Servo library is sufficient. Second you created an instance of a servo and called it thisservo but later on you write commands to myservo. They need to be the same name. Then, apparently to give the door a “slow” opening, you have a 15 msec delay in between each incremental 1 deg servo command. Is that long enough ? I also note that a servo is generally commanded on a 20 msec basis. Perhaps instead of a 15 msec delay, you should have a constant declared and use it instead. Then adjust the constant’s value until the door opening and closing rates are to your desire.

Should the door remain fully open for some length of time ? Or is the “slow” opening and closing enough to dispatch the desired quantity of food ?

I would create 2 new constants, posOpen and posClose and use those in place of the 0 and 90 degrees you now have. The door travel for open and closed might not exactly correspond to the servo’s 0 and 90 deg positions. Using constants will allow you to easily tweak the values.

if(personDetected){
  if(millis() - lastFeeding > lockOutTime){
    lastFeeding = millis();
    for(pos = posClose; pos < posOpen; pos += 1)   // goes from closed to open
    {                                              // in steps of 1 degree
      thisservo.write(pos);                        // tell servo to go to  'pos'
      delay(degDelay);                             // wait some msec for the servo to go 1 deg
    }
    delay(doorOpenDelay);                          // leave door open for some time ??
    for(pos = posOpen; pos > posClose; pos -=1)   // goes from open to closed
    {                               
      thisservo.write(pos);                        // tell servo to go to  'pos'
      delay(degDelay);                             // wait some msec for the servo to go 1 deg
    } 
  }
}

The whole servo opening and closing routine needs to be in an if() statement. If a “1” is received then the routine runs. But I would also ask how long it’ll take to open and close the door. If the “1” lasts longer than that, won’t you double feed the dog ? Should there be some time based lockout, no feeding within X mins of the last one ?

Sorry for the late reply.

So, does the Servo library have the same general functions?

Yes, I’ll have to rename “myservo” to “thisservo.” Yes, I’ll have to change things, I don’t need a slow opening/closing, I want it to just open quickly enough for a few kibbles to go down, should I set it down to 1? The door will not remain “open” for any length of time, thus.

I’ll make some changes, and then post this here again, thank you so much.

And maybe there should also be some kind of lockout, rather than being time-based, being instance based, that it’s “locked” when the first 1 is received, and “unlocked” when a 0 is received, in case motion detection is to much. So just a simple countdown loop for the “time” part? (in case of rapid 0 and 1 fluctuation)