This is ment to be a toy for cats and dogs, where the closer they are to the toy, the brighter the LED is going to be. And when they put their paws on th button (it’s a photoresistor), the LED with stop for however long they leave their paws in place.
Material:
- 1x IR distance sensor
- 1x photoresistor
- 1x 3.3v LED
- 1x 10k potentiometer
- 1x 220 resistor
- Adafruit Metro M0 Express
Setup:
Code:
/*
Jean Zhang
This is a sketch about a toy for pets (hopefully).
This is Ver 1.0 which is a easy prototype, a proof of
concept that the code/board/sensors works properly.
This code is modified from the class 2 note from
Prof. J. Eric Townsend.The lisence is as the following:
The MIT License (MIT)
Copyright (c) 2014 J. Eric Townsend
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
This code is modified from the original code by Jean Zhang.
Lots of thanks to Robert Zacharias and Professor Garth Zeglin for helping out with debugging and making the code to properly compile.
*/
const int irPin = 0;
const int photoPin = 1;
const int ledPin = 8;
const int sampleSize = 16;
int irIndex = 0;
int irReadings[sampleSize];
int photoIndex = 0;
int photoReadings[sampleSize];
int distVal, photoVal, ledVal;
const int ambientPhoto = 600;
const int tolerance = 200;
void setup() {
Serial.begin(115200);
pinMode(irPin, INPUT);
pinMode(photoPin, INPUT);
pinMode(ledPin, OUTPUT);
// put your setup code here, to run once:
}
void loop() {
//Reading the values from ir and photoResistor
int photo = analogRead(photoPin);
photoReadings[photoIndex] = photo;
photoIndex = (photoIndex + 1) % sampleSize;
int irDist = analogRead(irPin);
irReadings[irIndex] = irDist;
irIndex = (irIndex + 1) % sampleSize;
//Get readings for irSensors
int *pirReadings = irReadings;
distVal = getVal(pirReadings); // feed the pointer of the array (array location)
// photoVal = getVal(*photoReadings);
// console
#if 0
Serial.print("low ");
Serial.print(low);
Serial.print(" high ");
Serial.print(high);
Serial.print(" mean ");
Serial.println(mean);
Serial.print(" median ");
Serial.println(median);
delay(500);
digitalWrite(photoPin, LOW);
delay(500);
#endif
int ledVal = map(distVal, 0, 1023, 0, 255);
//0 (min) is based on the ambient setting
if (abs(ambientPhoto - photoVal) > tolerance) {
ledVal = 0;
}
analogWrite(ledPin, ledVal);
}
//Modified from class note:
int getVal(int *readings) { //return mean for now
int median = 0;
int low = 1024;
int high = 0;
int mean = 0;
for (int i = 0; i < sampleSize; i++) {
mean += readings[i];
if (readings[i] < low) { low = readings[i]; } if (readings[i] > high) {
high = readings[i];
}
}
mean = mean / sampleSize;
bubbleSort(readings);
median = readings[sampleSize / 2];
return mean;
//return median
}
//In C, a function cannot return an array
// tigoe's sort for an array
// since bubbleSort changes the array locally, the function doesn't
// need to return any value
void bubbleSort(int *readings) {
int out, in, swapper;
for (out = 0 ; out < sampleSize; out++) { // outer loop
for (in = out; in < (sampleSize - 1); in++) { // inner loop if ( readings[in] > readings[in + 1] ) { // out of order?
// swap them:
swapper = readings[in];
readings [in] = readings[in + 1];
readings [(in + 1)] = swapper;
}
}
}
}
Reflection:
I haven’t been able to get my hardware to work at the moment (just started testing like 10min ago). I spent a lot of time trying to debug the program. I had lots of issue with C++ since I didn’t really learn how to program in C besides reading codes for reference in my Python Projects (so much less work…).
My biggest issue is with the syntax of functions and the “pointer” in C. I wanted to make the return median/mean part into a function and use bubbleSort multiple times on different sensor values, where instead of changing the global, it takes in an array and sort that array. The problem being when defining function, it is defining certain type of data/value. And the take-in value need to be defined for their data type . However, when the take in value is an array, the pointer concept comes into play, and I keep getting the error like this
invalid types 'int[int]' for array subscript
After lots of Google-ing and reading comments I start to understand the concept of pointers and modify my code accordingly. (It is actually a really simple solution, kinda like the x.^x – the dot syntax in MATLAB). Instead of using :
void bubbleSort(int readings) { ........
Simply change the expression into:
void bubbleSort(int *readings) { ........
Note the different between “int readings” and “int *readings“. Where *readings is a pointer and readings is not really a valid input.
I also tried to return an array for bubbleSort, which I don’t have to do that (bad habit writing python programs, it does so much for you). In C, a function cannot return an array, instead, the way to return arraies is to use pointers, which also gave me a lot of problems when compiling.
Lots of thanks to Robert Zacharias and Professor Garth Zeglin for helping with the bug in the code (mainly for the pointer spaghetti) and making the code compile properly.