├── Learning_Color_NN ├── Learning_Color_NN.ino └── Perceptron.h ├── README.md ├── playground_learn ├── Perceptron.h └── playground_learn.ino └── playground_learn_color ├── Perceptron.h └── playground_learn_color.ino /Learning_Color_NN/Learning_Color_NN.ino: -------------------------------------------------------------------------------- 1 | //Tomas de camino Beck 2 | // Released under MIT License 3 | //Copyright (c) 2016 Tomas de-Camino-Beck 4 | 5 | #include "Perceptron.h" 6 | #include 7 | #include "Adafruit_TCS34725.h" 8 | 9 | Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X); 10 | 11 | uint16_t clear, red, green, blue ; 12 | 13 | //we will use one perceptron with 3 inputs (Red, green, blue) 14 | perceptron colorPerceptron(4);//fourth is for bias 15 | 16 | void setup() { 17 | 18 | tcs.begin(); 19 | 20 | randomSeed(A0); 21 | colorPerceptron.randomize();//weight initialization 22 | 23 | pinMode(12, OUTPUT);//TCS LED 24 | digitalWrite(12, HIGH); 25 | //Leds red and green 26 | //They are not necesary if you are using serial 27 | pinMode(6, OUTPUT); 28 | pinMode(7, OUTPUT); 29 | digitalWrite(6, LOW); 30 | digitalWrite(7, LOW); 31 | 32 | 33 | pinMode(10, INPUT_PULLUP); 34 | pinMode(9, INPUT_PULLUP); 35 | Serial.begin(9600); 36 | } 37 | 38 | void loop() { 39 | /*** read from the sensor**/ 40 | tcs.setInterrupt(false); 41 | delay(60); 42 | tcs.getRawData(&red, &green, &blue, &clear); 43 | tcs.setInterrupt(true); 44 | 45 | //convert then in values from 0 to 255 46 | uint32_t sum = clear; 47 | float r, g, b; 48 | r = red; r /= sum; 49 | g = green; g /= sum; 50 | b = blue; b /= sum; 51 | r *= 256; g *= 256; b *= 256; 52 | 53 | /*** store in perceptron inputs ***/ 54 | colorPerceptron.inputs[0] = r; 55 | colorPerceptron.inputs[1] = g; 56 | colorPerceptron.inputs[2] = b; 57 | 58 | float guess = colorPerceptron.feedForward(); 59 | 60 | if (digitalRead(10) == 0) { 61 | digitalWrite(12, LOW); 62 | colorPerceptron.train(1, guess); 63 | delay(1000); 64 | digitalWrite(12, HIGH); 65 | } 66 | 67 | if (digitalRead(9) == 0) { 68 | digitalWrite(12, LOW); 69 | colorPerceptron.train(-1, guess); 70 | delay(1000); 71 | digitalWrite(12, HIGH); 72 | } 73 | 74 | // Serial.print(colorPerceptron.inputs[0]); Serial.print(","); 75 | // Serial.print(colorPerceptron.inputs[1]); Serial.print(","); 76 | // Serial.print(colorPerceptron.inputs[2]); Serial.print(","); 77 | // Serial.println(guess); 78 | 79 | if (guess == 1) { 80 | Serial.println("Match"); 81 | digitalWrite(6, HIGH); 82 | digitalWrite(7, LOW); 83 | } 84 | else { 85 | Serial.println("No Match"); 86 | digitalWrite(6, LOW); 87 | digitalWrite(7, HIGH); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Learning_Color_NN/Perceptron.h: -------------------------------------------------------------------------------- 1 | /*Tomas de Camino Beck 2 | Class Perceptron for machine learning 3 | 4 | Ussage: 5 | 1.Create object class perceptron, e.g. perceptron p1(number of inputs) 6 | 2. Randomize weights, p1.randomize(); 7 | 3. In loop update inputs e.g. p1.inputs[0] = analogRead...; p1.inputs[2] = analogRead... 8 | 4. Make a guess store in variable e.g. float guess = p1.feedForward(); 9 | 5. Train compared obtained with some desired e.g. p1.train(desired, obtained); 10 | 11 | Made for teaching poruposes www.funcostarica.org 12 | Released under MIT License 13 | Copyright (c) 2016 Tomas de-Camino-Beck 14 | */ 15 | //**************Class perceptron************* 16 | class perceptron 17 | { 18 | 19 | const float c = 0.008;//constante de aprendizaje 20 | 21 | public: 22 | //arrays that hold inputs and weights 23 | float* inputs; 24 | float* weights; 25 | int n; //numero de entradas 26 | 27 | perceptron(int ninputs) { 28 | n = ninputs; 29 | inputs = new float[n]; 30 | weights = new float[n]; 31 | inputs[n - 1] = 1;//bias 32 | for (int i = 0; i < n; i++) { 33 | // The weights are picked randomly to start. 34 | //a trick to get values from -1 to 1 35 | weights[i] = (float)random(-1000, 1000) / 1000; 36 | } 37 | } 38 | 39 | //reset weights to random values 40 | void randomize() { 41 | for (int i = 0; i < n; i++) { 42 | // The weights are picked randomly to start. 43 | weights[i] = (float)random(-1000, 1000) / 1000; 44 | } 45 | } 46 | 47 | //training function 48 | void train(int desired, float guess) { 49 | float error = desired - guess; 50 | for (int i = 0; i < n; i++) { 51 | weights[i] += c * error * inputs[i]; 52 | } 53 | } 54 | 55 | //forward function 56 | float feedForward() { 57 | float sum = 0; 58 | for (int i = 0; i < n; i++) { 59 | sum += inputs[i] * weights[i]; 60 | } 61 | 62 | return activate(sum); 63 | } 64 | 65 | 66 | float weightedSum() { 67 | float sum = 0; 68 | for (int i = 0; i < n; i++) { 69 | sum += inputs[i] * weights[i]; 70 | } 71 | 72 | return sum; 73 | } 74 | 75 | 76 | private: 77 | //activation function 78 | int activate(float sum) { 79 | //regresa 1 si es positivo, -1 si negativo. 80 | if (sum > 0) { 81 | return 1; 82 | } 83 | else { 84 | return -1; 85 | } 86 | } 87 | 88 | 89 | 90 | }; 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino_Perceptron 2 | Un perceptrón programado para aprendiaje mecánico en Arduino 3 | 4 | ##Ussage 5 | 6 | 1. Create object class perceptron, e.g. perceptron p1(number of inputs); 7 | 2. Randomize weights, p1.randomize(); 8 | 3. In loop update inputs e.g. p1.inputs[0] = analogRead...; p1.inputs[2] = analogRead... 9 | 4. Make a guess store in a variable e.g. float guess = p1.feedForward(); 10 | 5. Train: compared obtained (guess) with some desired e.g. p1.train(desired, obtained); 11 | 12 | 13 | ##Examples 14 | 15 | 1. *Learning_Color_NN* teaching an Arduino color using a color sensor 16 | 2. *playground_learn* teaching an [Adafruit Circuit Playgound](https://www.adafruit.com/product/3000) how to get the right position using accelerometer. 17 | 3. *playground_learn_color* Adafruit Circuit Playground learning colors. 18 | 19 | ##License 20 | 21 | MIT License 22 | 23 | Copyright (c) 2016 Tomas de-Camino-Beck 24 | 25 | Permission is hereby granted, free of charge, to any person obtaining a copy 26 | of this software and associated documentation files (the "Software"), to deal 27 | in the Software without restriction, including without limitation the rights 28 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 29 | copies of the Software, and to permit persons to whom the Software is 30 | furnished to do so, subject to the following conditions: 31 | 32 | The above copyright notice and this permission notice shall be included in all 33 | copies or substantial portions of the Software. 34 | 35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 37 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 38 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 39 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 40 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 41 | SOFTWARE. 42 | -------------------------------------------------------------------------------- /playground_learn/Perceptron.h: -------------------------------------------------------------------------------- 1 | /*Tomas de Camino Beck 2 | Class Perceptron for machine learning 3 | 4 | Ussage: 5 | 1.Create object class perceptron, e.g. perceptron p1(number of inputs) 6 | 2. Randomize weights, p1.randomize(); 7 | 3. In loop update inputs e.g. p1.inputs[0] = analogRead...; p1.inputs[2] = analogRead... 8 | 4. Make a guess store in variable e.g. float guess = p1.feedForward(); 9 | 5. Train compared obtained with some desired e.g. p1.train(desired, obtained); 10 | 11 | Made for teaching poruposes www.funcostarica.org 12 | Released under MIT License 13 | Copyright (c) 2016 Tomas de-Camino-Beck 14 | */ 15 | //**************Class perceptron************* 16 | class perceptron 17 | { 18 | 19 | const float c = 0.008;//constante de aprendizaje 20 | 21 | public: 22 | //arrays that hold inputs and weights 23 | float* inputs; 24 | float* weights; 25 | int n; //numero de entradas 26 | 27 | perceptron(int ninputs) { 28 | n = ninputs; 29 | inputs = new float[n]; 30 | weights = new float[n]; 31 | inputs[n - 1] = 1;//bias 32 | for (int i = 0; i < n; i++) { 33 | // The weights are picked randomly to start. 34 | //a trick to get values from -1 to 1 35 | weights[i] = (float)random(-1000, 1000) / 1000; 36 | } 37 | } 38 | 39 | //reset weights to random values 40 | void randomize() { 41 | for (int i = 0; i < n; i++) { 42 | // The weights are picked randomly to start. 43 | weights[i] = (float)random(-1000, 1000) / 1000; 44 | } 45 | } 46 | 47 | //training function 48 | void train(int desired, float guess) { 49 | float error = desired - guess; 50 | for (int i = 0; i < n; i++) { 51 | weights[i] += c * error * inputs[i]; 52 | } 53 | } 54 | 55 | //forward function 56 | float feedForward() { 57 | float sum = 0; 58 | for (int i = 0; i < n; i++) { 59 | sum += inputs[i] * weights[i]; 60 | } 61 | 62 | return activate(sum); 63 | } 64 | 65 | 66 | float weightedSum() { 67 | float sum = 0; 68 | for (int i = 0; i < n; i++) { 69 | sum += inputs[i] * weights[i]; 70 | } 71 | 72 | return sum; 73 | } 74 | 75 | 76 | private: 77 | //activation function 78 | int activate(float sum) { 79 | //regresa 1 si es positivo, -1 si negativo. 80 | if (sum > 0) { 81 | return 1; 82 | } 83 | else { 84 | return -1; 85 | } 86 | } 87 | 88 | 89 | 90 | }; 91 | -------------------------------------------------------------------------------- /playground_learn/playground_learn.ino: -------------------------------------------------------------------------------- 1 | //Tomas de camino Beck 2 | //www.funcostarica.org 3 | //Released under MIT License 4 | //Copyright (c) 2016 Tomas de-Camino-Beck 5 | 6 | 7 | #include "Perceptron.h" 8 | #include 9 | #include 10 | 11 | 12 | //we will use one perceptron with 3 inputs (Red, green, blue) 13 | perceptron colorPerceptron(4);//fourth is for bias 14 | 15 | void setup() { 16 | 17 | randomSeed(CircuitPlayground.readCap(3)); 18 | colorPerceptron.randomize();//weight initialization 19 | CircuitPlayground.begin(); 20 | 21 | 22 | CircuitPlayground.clearPixels(); 23 | 24 | Serial.begin(9600); 25 | } 26 | 27 | void loop() { 28 | float accX, accY, accZ; 29 | /*** read from the sensor**/ 30 | accX = CircuitPlayground.motionZ(); 31 | accY = CircuitPlayground.motionZ(); 32 | accZ = CircuitPlayground.motionZ(); 33 | 34 | /*** store in perceptron inputs ***/ 35 | colorPerceptron.inputs[0] = accX; 36 | colorPerceptron.inputs[1] = accY; 37 | colorPerceptron.inputs[2] = accZ; 38 | 39 | //make a guess 40 | float guess = colorPerceptron.feedForward(); 41 | 42 | //press button if guess incorrect 43 | if (CircuitPlayground.leftButton()) { 44 | digitalWrite(12, LOW); 45 | colorPerceptron.train(-guess, guess); 46 | delay(1000); 47 | digitalWrite(12, HIGH); 48 | } 49 | 50 | // Serial.print(colorPerceptron.inputs[0]); Serial.print(","); 51 | // Serial.print(colorPerceptron.inputs[1]); Serial.print(","); 52 | // Serial.print(colorPerceptron.inputs[2]); Serial.print(","); 53 | // Serial.println(guess); 54 | 55 | //change color 56 | uint32_t c; 57 | if (guess == 1) { 58 | c = CircuitPlayground.strip.Color(0, 255, 0); 59 | Serial.println("Match"); 60 | } 61 | else { 62 | c = CircuitPlayground.strip.Color(255, 0, 0); 63 | Serial.println("No Match"); 64 | 65 | } 66 | 67 | //update pixels 68 | for (int i = 0; i <= 9; i++) { 69 | CircuitPlayground.setPixelColor(i, c); 70 | } 71 | 72 | 73 | 74 | // CircuitPlayground.clearPixels(); 75 | } 76 | -------------------------------------------------------------------------------- /playground_learn_color/Perceptron.h: -------------------------------------------------------------------------------- 1 | /*Tomas de Camino Beck 2 | Class Perceptron for machine learning 3 | 4 | Ussage: 5 | 1.Create object class perceptron, e.g. perceptron p1(number of inputs) 6 | 2. Randomize weights, p1.randomize(); 7 | 3. In loop update inputs e.g. p1.inputs[0] = analogRead...; p1.inputs[2] = analogRead... 8 | 4. Make a guess store in variable e.g. float guess = p1.feedForward(); 9 | 5. Train compared obtained with some desired e.g. p1.train(desired, obtained); 10 | 11 | Made for teaching poruposes www.funcostarica.org 12 | */ 13 | //**************Class perceptron************* 14 | class perceptron 15 | { 16 | 17 | const float c = 0.008;//constante de aprendizaje 18 | 19 | public: 20 | //arrays that hold inputs and weights 21 | float* inputs; 22 | float* weights; 23 | int n; //numero de entradas 24 | 25 | perceptron(int ninputs) { 26 | n = ninputs; 27 | inputs = new float[n]; 28 | weights = new float[n]; 29 | inputs[n - 1] = 1;//bias 30 | for (int i = 0; i < n; i++) { 31 | // The weights are picked randomly to start. 32 | //a trick to get values from -1 to 1 33 | weights[i] = (float)random(-1000, 1000) / 1000; 34 | } 35 | } 36 | 37 | //reset weights to random values 38 | void randomize() { 39 | for (int i = 0; i < n; i++) { 40 | // The weights are picked randomly to start. 41 | weights[i] = (float)random(-1000, 1000) / 1000; 42 | } 43 | } 44 | 45 | //training function 46 | void train(int desired, float guess) { 47 | float error = desired - guess; 48 | for (int i = 0; i < n; i++) { 49 | weights[i] += c * error * inputs[i]; 50 | } 51 | } 52 | 53 | //forward function 54 | float feedForward() { 55 | float sum = 0; 56 | for (int i = 0; i < n; i++) { 57 | sum += inputs[i] * weights[i]; 58 | } 59 | 60 | return activate(sum); 61 | } 62 | 63 | 64 | float weightedSum() { 65 | float sum = 0; 66 | for (int i = 0; i < n; i++) { 67 | sum += inputs[i] * weights[i]; 68 | } 69 | 70 | return sum; 71 | } 72 | 73 | 74 | private: 75 | //activation function 76 | int activate(float sum) { 77 | //regresa 1 si es positivo, -1 si negativo. 78 | if (sum > 0) { 79 | return 1; 80 | } 81 | else { 82 | return -1; 83 | } 84 | } 85 | 86 | 87 | 88 | }; 89 | -------------------------------------------------------------------------------- /playground_learn_color/playground_learn_color.ino: -------------------------------------------------------------------------------- 1 | //Tomas de camino Beck 2 | //www.funcostarica.org 3 | 4 | 5 | #include "Perceptron.h" 6 | #include 7 | #include 8 | 9 | 10 | //we will use one perceptron with 3 inputs (Red, green, blue) 11 | perceptron colorPerceptron(4);//fourth is for bias 12 | 13 | void setup() { 14 | 15 | randomSeed(CircuitPlayground.readCap(3)); 16 | colorPerceptron.randomize();//weight initialization 17 | CircuitPlayground.begin(); 18 | 19 | 20 | CircuitPlayground.clearPixels(); 21 | 22 | Serial.begin(9600); 23 | } 24 | 25 | void loop() { 26 | //Read color 27 | 28 | if (CircuitPlayground.lightSensor() <10) { 29 | CircuitPlayground.clearPixels(); 30 | uint8_t red, green, blue; 31 | CircuitPlayground.senseColor(red, green, blue); 32 | 33 | /*** store in perceptron inputs ***/ 34 | colorPerceptron.inputs[0] = red; 35 | colorPerceptron.inputs[1] = green; 36 | colorPerceptron.inputs[2] = blue; 37 | } 38 | //make a guess 39 | float guess = colorPerceptron.feedForward(); 40 | 41 | //press button if guess incorrect 42 | if (CircuitPlayground.rightButton()) { 43 | CircuitPlayground.clearPixels(); 44 | colorPerceptron.train(-guess, guess); 45 | delay(1000); 46 | } 47 | 48 | 49 | //change color 50 | uint32_t c; 51 | if (guess == 1) { 52 | c = CircuitPlayground.strip.Color(0, 255, 0); 53 | Serial.println("Match"); 54 | } 55 | else { 56 | c = CircuitPlayground.strip.Color(255, 0, 0); 57 | Serial.println("No Match"); 58 | 59 | } 60 | 61 | //update pixels 62 | for (int i = 3; i <= 9; i++) { 63 | CircuitPlayground.setPixelColor(i, c); 64 | } 65 | 66 | 67 | 68 | // CircuitPlayground.clearPixels(); 69 | } 70 | --------------------------------------------------------------------------------