Week 18
This week I wanted to get the axes drives running with the feedback of the encoders. Also the plan was to test the integrated GPS module and have it update the date, time an location.
GPS module
To continue with the GPS module, I needed to take the partly assembled machine outside and test it there.
After a while I was able to connect to some satellites and get my location and UTC time.
I integrated it into the program and tested, that the information would be updated. Then the solar calculator library would calculate the required azimuth and elevation angle.
// Update GPS information
void checkgps(unsigned long duration){
static unsigned long chrono = millis();
if (millis() - chrono < duration) return;
chrono = millis();
while (millis() - chrono < 1000) {
while (gpsSerial.available() > 0) {
gps.encode(gpsSerial.read());
}
if (gps.location.isUpdated() && gps.date.year() > 2024) {
gps_ok = true;
// Update location and time
lat = gps.location.lat();
lon = gps.location.lng();
setTime(gps.time.hour(),gps.time.minute(),gps.time.second(),gps.date.day(),gps.date.month(),gps.date.year());
}else{
gps_ok = false;
}
}
}
Encoder
I decided to change my design of the encoder magnet integration. I decided that I would place the Ø6 mm magnets in the threaded end of the M10 x 80 bolts, instead of in the head. By turning them around, I could glue one bolt in the zenith drive and spot weld the other onto the steel plate of the azimuth drive. As a result their location won't change and I could calibrate the home position once and hard-code it into the program.
Here is a picture of the bolt end with a Ø6 mm magnet integrated and a nylon lock nut to hold the drive together.
Removing super glue bonding
I had to remove one of the magnets, I had already glued with cyanoacrylate (super glue). I read that acetone should dissolve the glue, but even after six hours it was still stuck. Then I tried boiling it in water and I could pull it of with pliers.
Last week I discovered, that the I2C communication with the encoders would only work with a third device connected (OLED screen with I2C). This week I finally realized what the cause for this strange behaviour was. The SDA and SCL lines need to be pulled up to the working voltage of the microprocesser (5 V). In my case, neither the main board with the AVR nor the breakout board with the encoder had these resistors, but obviously the screen had them and was therefore able to fix the connectivity for me.
Fortunately I had the additional I2C connector on my board, so I made a small pullup adaptor, where I used two 4,7 kΩ resistors to pull SDA and SCL to 5 V.
Even though I got the I2C communication finally working properly, I still found that I had some issues with reading the encoders. They would either not respond or just send a fixed value of 14 bit. I started debugging by running an absolute minimal code. There trick there was to declare the uint16_t
variable inside the loop as a local - not global variable.
However, when going on with the main code it wouldn't work so I started adding code line-by-line into the minimal example until it stopped working. It stopped. when I set the pinMode for the motor driver pins and I found out that PIN_PA4
caused the issues. As it is the pin next to the SDA pin (PIN_PA3
) I started to suspect the hardware.
A closer look under the stereoscope revealed a tin bridge shorting two pins.
After fixing this, I got a stable reading from the sensors! Now I could continue with the programming.
Kinematics
While I was programming and playing around with the zenith drive, I realized, that I would need a transfer function, because there isn't a linear relationship between the encoder angle and the elevation angle of the sphere. I went back to Fusion and discovered as well, that the movement isn't a perfect arc. It is more complex and therefore I decided to go for a numerical approach and measure the angles in 5° steps.
The graphic shows, that a 85° rotation of the drive results in 90° rotation of the sphere around the pyranometer.
Next I entered the determined angles into an excel sheet and had it calculate a transfer function.
The formula is this polynomial function with \(\alpha\) as elevation angle and \(\beta\) as encoder angle:
I then figured out that I need to improve the accuracy of the function by adding more decimal places (which can be adjusted in excel).
Here it is:
Then I implemented the function in the code and tested it.
Counterweight
For testing the drives, I set the time and location manually and attached the counterweight to the arm and adjusted it accordung to the measurments from CAD.
Here is a picture of it.