There were two main parts to this lab. The first involved data storage, while the second involved manipulating a servo motor to perform various tasks.
The first portion of the lab was data storage. In essence, we were tasked with saving data into our microcontroller's very limited memory, and then recalling it to prove that we were successful. To write data into the microcontroller, the write() function was used.
Since the microcontroller's memory can only be rewritten about 100,000 times before it breaks, we had to add measures into the code to prevent infinite looping. We did this by making the microcontroller only record numbers when the letter "W" was entered into the Serial Monitor. The microcontroller outputted the information saved into its memory only when the letter "R" was entered into the Serial Monitor. The code that handles this process is below.
void loop()
{
if(Serial.available()>0)
{
input = Serial.read();
}
if(input==87) //for writing must press W
{
EEPROM.write(i,dummy);
i=i+1;
dummy=dummy+2;
}
else if(input==82) //for reading press R
{
while(k<i)
{
value=EEPROM.read(k);
Serial.println(value);
k=k+1;
}
k=0;
}
input=0;
}
The second part of this lab concerned the maniuplation of a servo motor. We first learned how to simply tell the servo motor how far to rotate. We did this by changing the amount of time that pulses were sent to the servo motor. This was enacted with the digitalWrite(pin,HIGH) function, then the delayMicroseconds() function, and finally the digitalWrite(pin,LOW) function. It was noted that the longer the pulses were left on, the more that the servo motor would rotate. If the pulse widths did not fall approximately within the 1-2 ms range, the servo motor did not function. Also, pulses had to be sent every 20 ms.
The next part of the lab was to make the servo motor rotate between two positions. This was performed with two "for" loops that counted to certain values. The method used is below.
for(i=200;i>2500;i++)
{
digitalWrite(pin,HIGH);
delayMicroseconds(i);
digitalWrite(pin,LOW);
delayMicroseconds(19000-i);
//delayMicroseconds(1);
}
for(i=2500;i>200;i--)
{
digitalWrite(pin,HIGH);
delayMicroseconds(i);
digitalWrite(pin,LOW);
delayMicroseconds(19000-i);
//delayMicroseconds(1);
}
As can be seen in this method, one counted up to a value, and the other counted down to a value. This effectively rotated the servo motor back and forth.
The next step in the lab was to manipulate the speed with which the servo motor rotated between the two positions. This was enacted with a "stepSize" variable that was inputted from the user. The code can be seen below.
void loop()
{
int degree = 180;
final=13.89*degree;
if(Serial.available()>0)
{
int inputChar=Serial.read();
int stepSize = inputChar;
i=200;
if(stepSize==70)
{
stepSize=2;
}
else if(stepSize==77)
{
stepSize=1.5;
}
else if(stepSize==83)
{
stepSize=1;
}
while(i<final)
{
digitalWrite(pin,HIGH);
delayMicroseconds(i);
digitalWrite(pin,LOW);
delayMicroseconds(19000-i);
//delayMicroseconds(1);
i=i+stepSize;
}
}
}
In this way, if the user entered "F" for fast, the step size would be 2. If they entered "M" for medium, the step size would be 1.5. Likewise, if they entered "S" for slow, the step size would be 1. This functionality accounted for the user-interactivity required by the lab.
The next part of the lab was to place a cardboard disk with holes in it and controlling where the holes are placed by manipulating the servo. The setup used can be seen below. The picture is for the "multiple holes" portion of the experiment, but the concept is the same for both "single hole" and "multiple holes."
The code for this portion of the experiment can be seen below.
void loop()
{
int degree = 90;
final=13.89*degree;
if(Serial.available()>0)
{
int inputChar=Serial.read();
int stepSize = inputChar;
i=200;
if(stepSize==70)
{
stepSize=2;
}
else if(stepSize==77)
{
stepSize=1.5;
}
else if(stepSize==83)
{
stepSize=1;
}
while(i<final)
{
digitalWrite(pin,HIGH);
delayMicroseconds(i);
digitalWrite(pin,LOW);
delayMicroseconds(19000-i);
//delayMicroseconds(1);
i=i+stepSize;
Serial.println(RCtime(6));
}
}
Serial.println(RCtime(6));
}
long RCtime(int sensPin)
{
long result = 0;
pinMode(sensPin, OUTPUT); // make pin OUTPUT
digitalWrite(sensPin, HIGH); // make pin HIGH to discharge capacitor - study the schematic
delay(1); // wait a ms to make sure cap is discharged
pinMode(sensPin, INPUT); // turn pin into an input and time till pin goes low
digitalWrite(sensPin, LOW); // turn pullups off - or it won't work
while(digitalRead(sensPin)){ // wait for pin to go low
result++;
}
return result; // report results
}
The same basic setup that was used for servo motor manipulation is used, except the "degree" variable was changed. After some calibration, a multiplying constant is multiplied by the "degree" variable to yield a "final" variable. The result is that the degree can easily be coded into the program to place the holes wherever one pleases.
It is also worth noting that the voltage running through a photoresistor was monitored using the "RCtime()" function. This enabled us to determine quantitatively when a hole was successfully placed over a photoresistor.