Final Project, Embedded Programming
After milling the board and soldering all components now it is the time for programming and testing, thanks to our instructor Emma, I have learned very important thing which is always start to test components one by one and never do it by one shot, this will save a lot of debugging and testing time and makes the integration of the system easier.
So following this procedure, I wrote a testing code for each part of the system and tested it, starting with the power switch and the indication LED as follows:
Since the led is connected to the output of the voltage regulator, if I pressed on the power switch and the led Lights up, this means that:
1- The power supply works correctly.
2- The power jack is checked.
3- The voltage regulator is checked.
4- The power switch is functional.
When I did it the Led lights up! so all components above are functional 100%:
Next component to test is the push button, I have connected it to the board and wrote the following code:
int pb= D3;
int pb_status=0;
void setup() {
// put your setup code here, to run once:
pinMode(pb, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
pb_status= digitalRead(pb);
Serial.print(pb_status);
delay(100);
}
The code defines pin 3 as an input pin and read the status of the pin, when the button is not pressed, the pin D3 will read a logic high (1) due to the pull-up resistor. When the button is pressed, it will connect the pin to ground, resulting in a logic low (0) reading. The internal pull-up resistor ensures a default logic high state when the button is not pressed, and the button press pulls the pin to ground to indicate a logic low state.
because the Push button also has a LED connected to pin D2 I test it using the following code:
int pb_led= D2;
int pb_status=0;
void setup() {
// put your setup code here, to run once:
pinMode(pb_led, OUTPUT);
Serial.begin(9600);
}
void loop() {
digitalWrite(pb_led, HIGH);
delay(1000);
digitalWrite(pb_led, LOW);
delay(1000);
Serial.println(pb_status);
}
The code sets D2 pin as an output pin with High and law and a delay 1 second between them, the result:
Next step is to test the potentiometer by writing the following code:
int Potintiometer= A1;
int Pot_value=0;
void setup() {
// put your setup code here, to run once:
pinMode(Potintiometer, INPUT);
Serial.begin(9600);
}
void loop() {
Pot_value= analogRead(Potintiometer);
Serial.println(Pot_value);
delay(100);
}
The code designates pin A1 as an analog input pin, allowing it to read the values from a connected potentiometer. Although there is no available video for this specific test, I recall that when rotating the potentiometer's knob, the readings ranged from 0 to 4095. This range reflects the values captured by the analog pin as the potentiometer is adjusted.
Last thing was to test the slide switch, since it connected directly between the 5V,GND and direction pin, when the slide switch is connected the DIr PIN of the motor driver it will rotate clock wise, and If the DIR pin connected to the ground it will rotate Counter Clock Wise.
Now All components are tested and verified, I wrote a full code that integrates all systems together as following:
int dirPin = 2;
int stepPin = 8;
int button = 5;
int stepsPerRevolution = 200;
int potentiometer = 2; // select the input pin for the potentiometer
int AnalogValue = 0; // variable to store the value coming from the potentiometer
int delayus;
int ButtonState =1;
int ButtonPreviousState= 0;
int Loadstate =0;
int ledPin = D2;
void setup() {
// Declare pins as Outputs
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(button, INPUT_PULLUP);
pinMode(potentiometer, INPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop() {
if (ButtonPreviousState == 0 && digitalRead(button) == 1) {
ButtonPreviousState = 1;
Loadstate = !Loadstate;
}
if (ButtonPreviousState == 1 && digitalRead(button) == 0) {
ButtonPreviousState = 0;
}
if (Loadstate) {
AnalogValue = analogRead(potentiometer);
delayus = map(AnalogValue, 0, 4095, 1, 55000);
Serial.print(AnalogValue);
Serial.print(" - ");
Serial.println(delayus);
digitalWrite(ledPin, LOW);
digitalWrite(stepPin, HIGH);
delayMicroseconds(delayus);
digitalWrite(stepPin, LOW);
delayMicroseconds(delayus);
} else {
digitalWrite(ledPin, HIGH);
}
}
To explain the code, it is mainly to control the stepper motor rotation speed based on the analog value obtained from the potentiometer, first I define the pin numbers as on the schematic file, then in setup I Sets stepPin and dirPin as outputs,button as input with pull-up resistor enabled, potentiometer as input, and ledPin as output.
In void loop section first I checks if the button state has changed and updates Loadstate accordingly. When the button is pressed, Loadstate toggles its value. Next is reading the analog value from the potentiometer using analogRead(potentiometer), and maps the obtained value to a delay range of 1 to 55000 microseconds using map().
The map() function is applied to this AnalogValue to scale it from the input range of 0-4095 to a new range of 1-55000. The resulting value is assigned to the delayus variable, which represents the delay in microseconds used for controlling the stepper motor's movement. If the delay value was 55000 microseconds (55 milliseconds) in the code, it means that there will be a delay of 55 milliseconds between each step of the stepper motor. This delay determines the speed at which the motor rotates.
It is worth to mention more delay time means slower rotation, and I conclude the 55000 delay after testing to reach the required speed.
Last part of the code is If Loadstate is true, the LED is turned off, and the stepper motor is commanded to move. It sets stepPin high, introduces the calculated delay using delayMicroseconds(), sets stepPin low, and introduces the same delay again. If Loadstate is false, the LED is turned on. this means if the motor was rotating the push button led will stay off, if I pressed on the PB, the motor rotation will stop and the led will be turned ON.
Now it is the time to connect everything together and upload the code, and yeah it worked!!