Captain’s Log: W18FA2022¶
My last update.¶
If your reading this I may have not made it. My mind is breaking… Hours have turned to days… Days to weeks and weeks to months… I’m having trouble keeping my eyes open. Sleeping has been hard. I Think Space weather is messing with it. Homeostasis machinery has been working overtime.
But I have to keep pushing… Only a couple more weeks left before we reach our destination. I owe it to the crew to get them to safety.
We need all the luck we can get.
See you on the other side…
New motherboard¶
The 328p board I made refuses to work… Something to do with the bootloader I think. Trying Arduino IDE’s bootloader fails setting the fuses and while I can upload simple Blink sketches I2C refuse to work.
Tried the Osciloscope but we couldn’t zoom in close enough to decode the signal and we don’t have a logic analyzer in the FCT Fablab…
Been looking at SAMDs as we have some SAMD21E18s and I also ordered some Attiny3226s so I need to figure this out asap.
New daughter boards…¶
Moving to SAMD means moving from 5v to 3.3V and I was advised to set the sensors to 3.3V too just in case they want to force 5V logic.
Reworked the whole thing. Gotta make sure the magnetic center of the sensor is centered with the mounting holes to make putting everything together easier. It’s off 0.172mm
Code is mostly done, I hope.¶
Haven’t been able to fully test it but it should work. Only untested part is the math, which is 90% of the program… #FingersCrossed
This is the very alpha, pre-release version:
#include <Wire.h>
#define PI 3.14159265358979323846
// Temporary pins
const byte buttonPin = 8; // the number of the pushbutton pin
const byte ledPin1 = 2; // the number of the LED pin
const byte ledPin2 = 3; // the number of the LED pin
const byte buzzerPin = 7; // the number of the LED pin
// Sensor I2C Addresses
const byte RadialSensorAddress = 0x40; // R - Radial Distance is made from the distance to origin point.
const byte PolarSensorAddress = 0x20; // θ - Polar Angle is the angle made from reflecting off the z-axis.
const byte AzimuthalSensorAddress = 0x10; // ϕ - Azimuthal Angle is the angle made from reflecting off the x-axis and revolves on the x-y plane.
const byte SensorReelDiameter = 10; // Sensor Reel Diameter in cm
// Magnet Status Variables
byte RadialMagnetStatus;
byte RadialMH;
byte RadialML;
byte RadialMD;
byte PolarMagnetStatus;
byte PolarMH;
byte PolarML;
byte PolarMD;
byte AzimuthalMagnetStatus;
byte AzimuthalMH;
byte AzimuthalML;
byte AzimuthalMD;
// Angle Values
float RadialAngle;
float PolarAngle;
float AzimuthalAngle;
// Wire Reel Full Revolution Counter
float RadialAngle_Old;
byte RadialRevolutions = 0;
// Wire Pull Distance Variables
float RadialAngleOrigin;
float R;
// Push Button Activity Checker
byte ButtonPress;
byte ButtonState;
byte LastButtonState = HIGH;
// Final Cartesian Coordinates
float X;
float Y;
float Z;
// Status Check Functions
void RadialStatus(){
Wire.beginTransmission(RadialSensorAddress); // Communicate with device @ deviceAddress!
Wire.write(0x0B); // Command byte to target registerAdress (0x0B Status Register)
Wire.endTransmission();
Wire.requestFrom(RadialSensorAddress, 1); // send me the data from 1 register, previously called for.
delay(1);
RadialMagnetStatus = Wire.read();
RadialMH = bitRead(RadialMagnetStatus, 3);
RadialML = bitRead(RadialMagnetStatus, 4);
RadialMD = bitRead(RadialMagnetStatus, 5);
}
void PolarStatus(){
Wire.beginTransmission(PolarSensorAddress); // Communicate with device @ deviceAddress!
Wire.write(0x0B); // Command byte to target registerAdress (0x0B Status Register)
Wire.endTransmission();
Wire.requestFrom(PolarSensorAddress, 1); // send me the data from 1 register, previously called for.
delay(1);
PolarMagnetStatus = Wire.read();
PolarMH = bitRead(PolarMagnetStatus, 3);
PolarML = bitRead(PolarMagnetStatus, 4);
PolarMD = bitRead(PolarMagnetStatus, 5);
}
void AzimuthalStatus(){
Wire.beginTransmission(AzimuthalSensorAddress); // Communicate with device @ deviceAddress!
Wire.write(0x0B); // Command byte to target registerAdress (0x0B Status Register)
Wire.endTransmission();
Wire.requestFrom(AzimuthalSensorAddress, 1); // send me the data from 1 register, previously called for.
delay(1);
AzimuthalMagnetStatus = Wire.read();
AzimuthalMH = bitRead(AzimuthalMagnetStatus, 3);
AzimuthalML = bitRead(AzimuthalMagnetStatus, 4);
AzimuthalMD = bitRead(AzimuthalMagnetStatus, 5);
}
void CheckMagnets(){
if(RadialMD==1&&PolarMD==1&&AzimuthalMD==1){
Serial.print("Sensor/Magnet check completed");
if(AzimuthalML+AzimuthalMH+PolarML+PolarMH+RadialML+RadialMH==0){
Serial.print(" successfully.\n");
}else{
Serial.print(".\n");
}
if(AzimuthalML == 1){
Serial.println("Sensor/Magnet check warning: Check distance of Magnet-Azimuthal Sensor.\nAutomatic gain too low, magnet too close.");
}
if(AzimuthalMH == 1){
Serial.println("Sensor/Magnet check warning: Check distance of Magnet-Azimuthal Sensor.\nAutomatic gain too high, magnet too far.");
}
if(PolarML == 1){
Serial.println("Sensor/Magnet check warning: Check distance of Magnet-Polar Sensor.\nAutomatic gain too low, magnet too close.");
}
if(PolarMH == 1){
Serial.println("Sensor/Magnet check warning: Check distance of Magnet-Polar Sensor.\nAutomatic gain too high, magnet too far.");
}
if(RadialML == 1){
Serial.println("Sensor/Magnet check warning: Check distance of Magnet-Radial Sensor.\nAutomatic gain too low, magnet too close.");
}
if(RadialMH == 1){
Serial.println("Sensor/Magnet check warning: Check distance of Magnet-Radial Sensor.\nAutomatic gain too high, magnet too far.");
}
} else {
if(RadialMD==0){
Serial.print("Radial");
}
if(PolarMD==0){
Serial.print("Polar");
}
if(AzimuthalMD==0){
Serial.print("Azimuthal");
}
Serial.println(" sensor failed to detect magnet.\nCheck distance of Magnet/Sensor.");
}
return;
}
// Read Functions
float RadialRead(){
Wire.beginTransmission(RadialSensorAddress); // Communicate with device @ deviceAddress!
Wire.write(0x0C);
Wire.write(0x0D);// Importante referenciar as 2 addresses
Wire.endTransmission();
Wire.requestFrom(RadialSensorAddress,2);
delay(1);
byte high = Wire.read();
byte low = Wire.read();
uint16_t temp = word(low,high);
//RadialAngle = temp * 360.0 / 4096; // .0 forces a float calculation or it won't work and give 0 as a result, division last uses less resources.
RadialAngle = temp * 2.0*PI / 4096; // Cos() and Sin() use Radians.
return RadialAngle;
}
float PolarRead(){
Wire.beginTransmission(PolarSensorAddress); // Communicate with device @ deviceAddress!
Wire.write(0x0C);
Wire.write(0x0D);// Importante referenciar as 2 addresses
Wire.endTransmission();
Wire.requestFrom(PolarSensorAddress,2);
delay(1);
byte high = Wire.read();
byte low = Wire.read();
uint16_t temp = word(low,high);
//PolarAngle = temp * 360.0 / 4096; // .0 forces a float calculation or it won't work and give 0 as a result, division last uses less resources.
PolarAngle = temp * 2.0*PI / 4096; // Cos() and Sin() use Radians.
return PolarAngle;
}
float AzimuthalRead(){
Wire.beginTransmission(AzimuthalSensorAddress); // Communicate with device @ deviceAddress!
Wire.write(0x0C);
Wire.write(0x0D);// Importante referenciar as 2 addresses
Wire.endTransmission();
Wire.requestFrom(AzimuthalSensorAddress,2);
delay(1);
byte high = Wire.read();
byte low = Wire.read();
uint16_t temp = word(low,high);
//AzimuthalAngle = temp * 360.0 / 4096; // .0 forces a float calculation or it won't work and give 0 as a result, division last uses less resources.
AzimuthalAngle = temp * 2.0*PI / 4096; // Cos() and Sin() use Radians.
return AzimuthalAngle;
}
// Check For Button Press
void CheckButtonPress(){
delay(25); //debounce?
ButtonState = digitalRead(buttonPin);
if (ButtonState != LastButtonState){
if (ButtonState == LOW){ // pulled HIGH, check if closed to LOW.
ButtonPress = true;
} else {
ButtonPress = false;
} // Button Press
} // Button Change
LastButtonState = ButtonState;
}
// Radial Rotation Counter ?
void CheckRotation(){
RadialAngle_Old = RadialAngle;
RadialAngle = RadialRead();
if(cos(RadialAngle>0)){
if(sin(RadialAngle)>sin(RadialAngle_Old)){
RadialRevolutions ++;
}
if(sin(RadialAngle)<sin(RadialAngle_Old)){
RadialRevolutions --;
}
}
}
void PrintCoordinates(){
// Read Radial Sensor
RadialAngle = RadialRead();
PolarAngle = PolarRead();
AzimuthalAngle = AzimuthalRead();
// Calculate r - Radial Distance
R = ((RadialAngle+(2.0*PI*RadialRevolutions))-RadialAngleOrigin)*SensorReelDiameter; // Current Angle + Full Rotations - Tare * Sensor Reel Diameter
// Calculate X
//x = r sinϕ(Azimuthal) cosθ(Polar)
X = R * sin(AzimuthalAngle)*cos(PolarAngle);
// Calculate Y
//y = r sinϕ(Azimuthal) sinθ(Polar)
Y = R * sin(AzimuthalAngle)*sin(PolarAngle);
// Calculate Z
// z = r cosϕ(Azimuthal)
Z = R * cos(AzimuthalAngle);
// Print Point Coordinates
Serial.print(X,6); Serial.print(" ");Serial.print(Y,6); Serial.print(" ");Serial.print(Z,6);
// Buzz Buzz Buzz
digitalWrite(buzzerPin, HIGH);
delay(50);
digitalWrite(buzzerPin, LOW);
}
void setup(){
pinMode(buttonPin, INPUT);
// initialize the LED pin as an output:
pinMode(ledPin1, OUTPUT);
// initialize the LED pin as an output:
pinMode(ledPin2, OUTPUT);
// initialize the Buzzer pin as an output:
pinMode(buzzerPin, OUTPUT);
delay(100);
Wire.begin(); // Wire communication begin
Serial.begin(9600); // The baudrate of Serial monitor is set in 9600
delay(1000);
while (!Serial); // Waiting for Serial Monitor
Serial.println("Booting up!");
delay(100);
RadialAngleOrigin = RadialRead(); // This will work as a Tare function so we can account for it when calculating wire reel rotations.
CheckMagnets(); // Startup sensor/magnet check
delay(1000);
Serial.println("Ready.\n");
Serial.println("Coordinates will be printed in a format compatible with .asc files for Point Clouds.\n");
Serial.println("Copy the coordinates and past them into a text file, then save it and change the extention to .asc");
Serial.println("Many programs recognize the format and will be able to import the cloud. Like FreeCAD.\n");
Serial.println("Fusion360 does not support Point Cloud files so take it up with Autodesk...");
Serial.println("Coordinates below\n-----------------------");
}
void loop(){
byte ReadLoop = 0;
//if (ReadLoop < 5 ){
if (ReadLoop < 5 ){
//delay(167); //6Hz refresh rate, 1000ms /6 = 166.6667ms
delay(100);
ReadLoop ++;
} else {
RadialAngle = RadialRead();
CheckRotation();
CheckButtonPress();
// if (ButtonPress == true){
if (ButtonPress){ //already a boolean?
PrintCoordinates();
ButtonPress = false;
}
ReadLoop = 0;
}
}
I was advised to check out look up tables, and they look awesome but I don’t have the time to figure out how I can include them.
The Spring Coil Situation.....¶
I finished the design but when I tried printing the final spring over the weekend it didn’t go well:
Instructor said he always has bad results with layers below 0.1mm and I was trying out 0.07mm as the lower I went with small tests the better results I had with walls not overlaping each other. Doing both at the same time probably didn’t help. By the time the head would come back the layer below was cold. Wasn’t an issue in lower layers closer to the bed.
Also randomly reading about the new Prusa XL they mentioned heat creep and as it was a 75h print that might have played a part too.
Ah well, tomorrow I should already have 2x finished coils with 0.1mm layers and printerd one at a time.
Time’s flying¶
Got an MDF skeleton cut but hopefuly by friday I’ll have the final laser cut steel parts so I can solder them during the weekend. In the next couple of days I need to figure out the motherboard thing and run a few quick test on the probe tube to get the smallest hole possible to have the least play once everything goes together.
I already have some ideas for the video, I hope I can find the time to not make a mess of it.
And #ImOut