Your brain is made of about 86 billion nerve cells called neurons. Each one adds up the signals it gets and decides whether to "fire". Artificial intelligence copies that idea with numbers. In this lesson the UNO runs one artificial neuron that looks at the light sensor. At first it knows nothing and guesses badly. Then you teach it: hold the sensor in the light and press "light", cover it and press "dark". After a few examples the neuron lights the right LED by itself. You'll see the two numbers it learns, its weight and its bias, change with every lesson you give it.
What you'll learn
- What an artificial neuron is: inputs, a weight, a bias and an output
- How a neuron learns from examples with the perceptron rule
- What training, an epoch and an error are
- Why the same neuron can learn the opposite if you teach it differently
What you need
- UNO R3 board and USB cable (UNO R3 Starter Kit)
- Photoresistor module (45-in-1 Sensor Kit)
- 2 push buttons (UNO R3 Starter Kit)
- Green LED, red LED and 2 resistors, 220 Ω (UNO R3 Starter Kit)
- The printed parts from the 3D printing box below (neuron model), or the cardboard version described there
- Breadboard and jumper wires (UNO R3 Starter Kit)
Wiring

| From | To |
|---|---|
| Photoresistor module S | UNO pin A0 |
| Photoresistor module + and − | 5V and GND |
| "Light" button, one leg | UNO pin 2 |
| "Dark" button, one leg | UNO pin 3 |
| Both buttons, the diagonally opposite leg | GND |
| UNO pin 9 | 220 Ω resistor, then the green LED's long leg |
| UNO pin 10 | 220 Ω resistor, then the red LED's long leg |
| Both LED short legs | GND |
Sensor modules from different makers can label and order their pins differently. Always follow the labels printed on your module.
The sketch
const int LIGHT_PIN = A0;
const int LIGHT_BUTTON = 2, DARK_BUTTON = 3;
const int GREEN_PIN = 9, RED_PIN = 10;
const float RATE = 0.3; // learning rate: how big each correction is
const int MAX_EXAMPLES = 20;
float weight = 0; // the neuron starts knowing nothing
float bias = 0;
float examples[MAX_EXAMPLES]; // what the sensor saw
int answers[MAX_EXAMPLES]; // what you said it was: 1 light, 0 dark
int count = 0;
// The input: the light reading as a number from 0 to 1
float sense() {
long sum = 0;
for (int i = 0; i < 10; i++) sum += analogRead(LIGHT_PIN);
return sum / 10 / 1023.0;
}
// The neuron: multiply, add, decide. 1 means "light", 0 means "dark"
int think(float x) {
return weight * x + bias > 0 ? 1 : 0;
}
void learn(float x, int answer) {
examples[count % MAX_EXAMPLES] = x; // remember this example
answers[count % MAX_EXAMPLES] = answer;
count++;
int stored = min(count, MAX_EXAMPLES);
for (int epoch = 1; epoch <= 50; epoch++) { // go through all examples again and again
int mistakes = 0;
for (int i = 0; i < stored; i++) {
int error = answers[i] - think(examples[i]); // -1, 0 or +1
if (error != 0) {
weight += RATE * error * examples[i]; // the perceptron rule
bias += RATE * error;
mistakes++;
}
}
if (mistakes == 0) {
Serial.print("Learned it in ");
Serial.print(epoch);
Serial.println(epoch == 1 ? " epoch." : " epochs.");
break;
}
}
Serial.print("weight = ");
Serial.print(weight, 3);
Serial.print(" bias = ");
Serial.println(bias, 3);
if (weight != 0) {
Serial.print("It now calls everything ");
Serial.print(weight > 0 ? "above " : "below ");
Serial.print(-bias / weight, 2); // where weight * x + bias = 0
Serial.println(" \"light\".");
}
}
bool pressed(int pin) {
if (digitalRead(pin) == HIGH) return false;
delay(30);
while (digitalRead(pin) == LOW) {} // wait until you let go
return true;
}
void setup() {
Serial.begin(9600);
pinMode(LIGHT_BUTTON, INPUT_PULLUP);
pinMode(DARK_BUTTON, INPUT_PULLUP);
pinMode(GREEN_PIN, OUTPUT);
pinMode(RED_PIN, OUTPUT);
Serial.println("Teach me! Press LIGHT or DARK to tell me what the sensor sees.");
}
void loop() {
float x = sense();
int guess = think(x);
digitalWrite(GREEN_PIN, guess == 1);
digitalWrite(RED_PIN, guess == 0);
if (pressed(LIGHT_BUTTON)) {
Serial.print("You said: LIGHT at ");
Serial.println(x, 2);
learn(x, 1);
}
if (pressed(DARK_BUTTON)) {
Serial.print("You said: DARK at ");
Serial.println(x, 2);
learn(x, 0);
}
delay(50);
}
Teach it
- Open the Serial Monitor at 9600 baud. The neuron starts with weight 0 and bias 0, so it always says "dark": the red LED is on.
- Hold the sensor under a lamp and press light. The numbers change. Cover it with your hand and press dark.
- Give it three or four examples of each. Now move between light and shadow: the LEDs follow by themselves.
- Press the reset button on the UNO and teach it the opposite: dark is "light" and light is "dark". It learns that just as happily. It has no idea what light is; it only learns what you show it.
How it works
An artificial neuron does one small sum: it multiplies its input by a weight, adds a bias and checks whether the result is above zero. The weight says how important the input is and in which direction; the bias moves the point where the answer flips. That flip point, -bias / weight, is the neuron's idea of where "light" begins.
Learning means finding a weight and a bias that give the right answers. The perceptron rule, invented in 1958, does it with a simple correction: for every example the neuron gets wrong, nudge the weight and the bias a little towards the right answer. Going through all the examples once is an epoch. The neuron repeats epochs until it makes no more mistakes.
Big AI systems like the ones behind chatbots work on the same idea, with billions of weights instead of one, and a cleverer way of nudging them. But the heart of it is the same: examples, errors and small corrections.
Try this next
- Give the neuron a second input, the potentiometer, and teach it "light AND knob up".
- Make
RATEvery small (0.01) and count how many epochs it needs now. - Teach it with a wrong example on purpose. What happens to the flip point?
Troubleshooting
- It always says the same thing: give it at least one example of each kind.
- It says "50 epochs" and still makes mistakes: you gave it examples that contradict each other, like "light" and "dark" at the same reading. Press reset and teach it again.
- A button does nothing: use the diagonally opposite legs of the button.
- A printed part is too tight or too loose: printers differ by a few tenths of a millimetre. Sand or file a tight hole, and fix a loose part with a drop of hot glue or a strip of tape.