Compare commits

...

5 Commits

Author SHA1 Message Date
f05c78e400 drone driver seems to work 2025-03-17 16:42:34 +01:00
49fe84e1a6 docs broken programmer 2025-03-17 15:07:43 +01:00
76ebfd9677 It finally outputs data
now need to get it parsed  correctly
2025-03-17 15:06:52 +01:00
011cc8ccfd typo 2025-03-17 10:26:55 +01:00
5a985367f2 images 2025-03-17 10:04:07 +01:00
22 changed files with 239 additions and 35 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -0,0 +1,83 @@
# Electronic Production
Henk thought us how to use the pcb milling machine. It was a lot easier to use than the big shopbot.
## Preparing the material and machine for use
First Henk showed us how to clean and prepare the material. He first took out the platform and removed the plate that was cut from the sacrificial layer.
![alt text](image.jpg)
After that he removed the tape from the backside of the material and cleaned off the glue from the plates using `sticker remover`.
![alt text](IMG_8970.jpg)
After that we grabbed the double sided tape and after cleaning we taped it back up and put the plate back on the sacrificial layer.
![alt text](IMG_8974.jpg)
![alt text](IMG_8975.jpg)
![alt text](IMG_8977.jpg)
Then he placed the plate precisely back on the sacrificial layer.
![alt text](IMG_8981.jpg)
![alt text](IMG_8982.jpg)
Then he cleaned it and put the plate back in and screwed it down. He told us to not screw it too tightly otherwise the plate will be uneven.
## Exporting from KiCad
File > Fabcrication output > Gerber
Then only select F.Cu and Edge.Cuts
![alt text](image-1.jpg)
gerber2img on class website.
![alt text](image-2.jpg)
convert gerber files to images.
For the traces without `fill edge cuts`
For edge cuts with `fill edge cuts`
Then load jpg file into ModsProject.
## Using modsProject to use the machine
We use modsproject.org to send our designs to the machine. The website uses webserial to communicate to the device so you need chrome or any chromium based browsers to use this website. Otherwise it won't work.
![alt text](image-3.jpg)
Then we needed to select the MDX mill.
After that Henk showed us that we needed. To start the Serial communication with the machine.
![alt text](image-4.jpg)
After that we could load all the tool configurations.
![alt text](image-5.jpg)
These where our settings for making the traces and these where for cutting out the board.
![alt text](image-6.jpg)
After that we could import the file
![alt text](image-7.jpg)
And press calculate over here
![alt text](image-8.jpg)
When it's done a new page will pop up with the toolpath. You can close that. Now you need to set the starting coordinates.
![alt text](image-9.jpg)
That can be done over here. The origin is the starting position of your job. After it's set. You can finaly click the send file button.
![alt text](image-10.jpg)
## Making my first programmer
I went through the fabacademy website and looked for my first board to make. I wanted to make a programmer so I could program other Atiny's and SAMD's and get started on making small boards.
The first board I had calibrated the Z too low and it went a bit too far into the board. It also destroyed a trace.
I read some more form the github repository and saw that these mcu's only need one pin to program. I was concerned with the 6 pin connector that it could only be attached one way but it can go both ways which is a nice design choice.
![alt text](image-11.jpg)
After soldering I realized that some traces where broken. I attempted to fix them using bypass wires. But I accidentally ripped off the voltage regulator when I was stripping the wire I already soldered to it. So for next time don't strip a wire while the other end is soldered.
![alt text](IMG_9266.jpg)
[link](https://gitlab.fabcloud.org/pub/programmers/programmer-updi-d11c)

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

View File

@@ -0,0 +1,35 @@
# Lecuture Notes
Starting this week every week a board.
Direct write processes
Use tape to hold board down or use clamps
Milling bit needs to be on the copper.
2 Sided boards
Always make sure you have the exact same origin
## Thursday Notes
Dual sided tape to stick FR-1 on
Only fasten one side with the black tape
When origin set. unfasten the mill and drop down the bit to the plate
Offset number how much extra passes around the lines to be done
After re-doing a file after a fault you should reset the machine. Using the up-down buttons. You should hold them for 10 seconds
The cut was not deep enough so we shoved a piece of paper under it and now it goes too deep. Maybe doing the paper single sided under there was enough.
for cutting out the pcb it's the same process except with a few different settings
Press plate down a bit and then calibrate the z for good cuts
With 0,1 mm milling bit need higher offset. Otherwise there would not be enough space between the traces.
Offset of 0 means remove all the excess copper

View File

@@ -1,5 +1,6 @@
#include <Arduino.h>
#include <SparkFun_BNO080_Arduino_Library.h>
#include <Wire.h>
#include "SparkFun_BNO080_Arduino_Library.h"
#include <ESP32Servo.h>
#include <esp_now.h>
#include <WiFi.h>
@@ -47,23 +48,24 @@ static const uint8_t num_DSM_channels = 6; // If using DSM RX, change this to ma
#define USE_BNO085_I2C // Custom
// Uncomment only one full scale gyro range (deg/sec)
#define GYRO_250DPS // Default
// #define GYRO_250DPS // Default
// #define GYRO_500DPS
// #define GYRO_1000DPS
// #define GYRO_2000DPS
#define GYRO_SCALE_BNO085
// Uncomment only one full scale accelerometer range (G's)
// #define ACCEL_2G // Default
// #define ACCEL_4G
#define ACCEL_8G
// #define ACCEL_8G
// #define ACCEL_16G
#define ACCEL_SCALE_BNO085
//========================================================================================================================//
// REQUIRED LIBRARIES (included with download in main sketch folder)
#include <Wire.h> //I2c communication
#include <SPI.h> //SPI communication
#include <Wire.h> //I2c communication
#if defined USE_SBUS_RX
#include "src/SBUS/SBUS.h" //sBus interface
@@ -77,6 +79,7 @@ static const uint8_t num_DSM_channels = 6; // If using DSM RX, change this to ma
#include "src/MPU6050/MPU6050.h"
MPU6050 mpu6050;
#elif defined USE_MPU9250_SPI
#include <SPI.h> //SPI communication
#include "src/MPU9250/MPU9250.h"
MPU9250 mpu9250(SPI2, 36);
#elif defined USE_BNO085_I2C
@@ -109,14 +112,15 @@ BNO080 myIMU;
#define ACCEL_FS_SEL_8 mpu9250.ACCEL_RANGE_8G
#define ACCEL_FS_SEL_16 mpu9250.ACCEL_RANGE_16G
#elif defined USE_BNO085_I2C
#define GYRO_FS_SEL_250 MPU6050_GYRO_FS_250
#define GYRO_FS_SEL_500 MPU6050_GYRO_FS_500
#define GYRO_FS_SEL_1000 MPU6050_GYRO_FS_1000
#define GYRO_FS_SEL_2000 MPU6050_GYRO_FS_2000
#define ACCEL_FS_SEL_2 MPU6050_ACCEL_FS_2
#define ACCEL_FS_SEL_4 MPU6050_ACCEL_FS_4
#define ACCEL_FS_SEL_8 MPU6050_ACCEL_FS_8
#define ACCEL_FS_SEL_16 MPU6050_ACCEL_FS_16
// these are all placeholders since the bno does this all by itself
#define GYRO_FS_SEL_250 0
#define GYRO_FS_SEL_500 1
#define GYRO_FS_SEL_1000 2
#define GYRO_FS_SEL_2000 3
#define ACCEL_FS_SEL_2 0
#define ACCEL_FS_SEL_4 1
#define ACCEL_FS_SEL_8 2
#define ACCEL_FS_SEL_16 3
#endif
#if defined GYRO_250DPS
@@ -131,6 +135,9 @@ BNO080 myIMU;
#elif defined GYRO_2000DPS
#define GYRO_SCALE GYRO_FS_SEL_2000
#define GYRO_SCALE_FACTOR 16.4
#elif defined GYRO_SCALE_BNO085
#define GYRO_SCALE 0
#define GYRO_SCALE_FACTOR 1.0 // BNO085 gives values already in deg/s when converted in getIMUdata
#endif
#if defined ACCEL_2G
@@ -145,6 +152,9 @@ BNO080 myIMU;
#elif defined ACCEL_16G
#define ACCEL_SCALE ACCEL_FS_SEL_16
#define ACCEL_SCALE_FACTOR 2048.0
#elif defined ACCEL_SCALE_BNO085
#define ACCEL_SCALE 0
#define ACCEL_SCALE_FACTOR 1.0 // BNO085 gives values already in g's when converted in getIMUdata
#endif
//========================================================================================================================//
@@ -220,7 +230,7 @@ const int ch3Pin = 17; // ele
const int ch4Pin = 20; // rudd
const int ch5Pin = D7; // gear (throttle cut)
const int ch6Pin = D7; // aux1 (free aux channel)
const int PPM_Pin = 23;
const int PPM_Pin = D7;
// OneShot125 ESC pin outputs:
const int m1Pin = D0;
const int m2Pin = D1;
@@ -366,7 +376,11 @@ void setup()
{
Serial.begin(9600); // USB serial
Serial.println("Serial started");
delay(10000);
// Initialize IMU communication
Serial.println("Initiating IMU");
IMUinit();
Serial.println("Initiating pins");
// Initialize all pins
// pinMode(13, OUTPUT); // Pin 13 LED blinker on board, do not modify
@@ -408,9 +422,6 @@ void setup()
channel_5_pwm = channel_5_fs;
channel_6_pwm = channel_6_fs;
// Initialize IMU communication
IMUinit();
delay(5);
// Get IMU error to zero accelerometer and gyro readings, assuming vehicle is level when powered up
@@ -463,12 +474,12 @@ void loop()
loopBlink(); // Indicate we are in main loop with short blink every 1.5 seconds
// Print data at 100hz (uncomment one at a time for troubleshooting) - SELECT ONE:
printRadioData(); //Prints radio pwm values (expected: 1000 to 2000)
printDesiredState(); //Prints desired vehicle state commanded in either degrees or deg/sec (expected: +/- maxAXIS for roll, pitch, yaw; 0 to 1 for throttle)
// printRadioData(); //Prints radio pwm values (expected: 1000 to 2000)
// printDesiredState(); //Prints desired vehicle state commanded in either degrees or deg/sec (expected: +/- maxAXIS for roll, pitch, yaw; 0 to 1 for throttle)
// printGyroData(); //Prints filtered gyro data direct from IMU (expected: ~ -250 to 250, 0 at rest)
// printAccelData(); //Prints filtered accelerometer data direct from IMU (expected: ~ -2 to 2; x,y 0 when level, z 1 when level)
// printAccelData(); // Prints filtered accelerometer data direct from IMU (expected: ~ -2 to 2; x,y 0 when level, z 1 when level)
// printMagData(); //Prints filtered magnetometer data direct from IMU (expected: ~ -300 to 300)
// printRollPitchYaw(); //Prints roll, pitch, and yaw angles in degrees from Madgwick filter (expected: degrees, 0 when level)
printRollPitchYaw(); //Prints roll, pitch, and yaw angles in degrees from Madgwick filter (expected: degrees, 0 when level)
// printPIDoutput(); //Prints computed stabilized PID variables from controller and desired setpoint (expected: ~ -1 to 1)
// printMotorCommands(); //Prints the values being written to the motors (expected: 120 to 250)
// printServoCommands(); //Prints the values being written to the servos (expected: 0 to 180)
@@ -614,12 +625,20 @@ void IMUinit()
mpu9250.setSrd(0); // sets gyro and accel read to 1khz, magnetometer read to 100hz
#elif defined USE_BNO085_I2C
Wire.begin();
myIMU.begin();
if (myIMU.begin() == false) // from sparkfun example
{
Serial.println("BNO080 not detected at default I2C address. Check your jumpers and the hookup guide. Freezing...");
while (1)
;
}
Wire.setClock(400000); // Increase I2C data rate to 400kHz
Serial.println("IMU initialized");
myIMU.enableMagnetometer(50);
myIMU.enableGyro(50);
delay(100);
myIMU.enableAccelerometer(50);
delay(100);
myIMU.enableMagnetometer(50);
delay(500);
#endif
}
@@ -636,12 +655,17 @@ void getIMUdata()
* the constant errors found in calculate_IMU_error() on startup are subtracted from the accelerometer and gyro readings.
*/
int16_t AcX, AcY, AcZ, GyX, GyY, GyZ, MgX, MgY, MgZ;
#if defined USE_MPU6050_I2C
mpu6050.getMotion6(&AcX, &AcY, &AcZ, &GyX, &GyY, &GyZ);
#elif defined USE_MPU9250_SPI
mpu9250.getMotion9(&AcX, &AcY, &AcZ, &GyX, &GyY, &GyZ, &MgX, &MgY, &MgZ);
#elif defined USE_BNO085_I2C
#elif defined USE_BNO085_I2C
// Keep waiting until data becomes available
while (!myIMU.dataAvailable())
{
delay(1); // Small delay to avoid hammering the I2C bus too hard
}
// All the error checking is done here because the BNO085 handles all the sensor fusion internally
// BNO magnetometer
MgX = myIMU.getMagX();
MgY = myIMU.getMagY();
@@ -652,10 +676,67 @@ void getIMUdata()
GyY = myIMU.getGyroY() * 180 / PI;
GyZ = myIMU.getGyroZ() * 180 / PI;
// Acelleration (dont know if I need linear or normal. One way to find out)
AcX = myIMU.getAccelX();
AcY = myIMU.getAccelY();
AcZ = myIMU.getAccelZ();
// Acceleration
// Convert acceleration m/s² to g (9.81 m/s² = 1g)
AcX = myIMU.getAccelX() / 9.80665; // m/s² to g
AcY = myIMU.getAccelY() / 9.80665; // m/s² to g
AcZ = myIMU.getAccelZ() / 9.80665; // m/s² to g
AccX = AcX;
AccY = AcY;
AccZ = AcZ;
// Correct the outputs with the calculated error values
AccX = AccX - AccErrorX;
AccY = AccY - AccErrorY;
AccZ = AccZ - AccErrorZ;
// LP filter accelerometer data
AccX = (1.0 - B_accel) * AccX_prev + B_accel * AccX;
AccY = (1.0 - B_accel) * AccY_prev + B_accel * AccY;
AccZ = (1.0 - B_accel) * AccZ_prev + B_accel * AccZ;
AccX_prev = AccX;
AccY_prev = AccY;
AccZ_prev = AccZ;
// Process gyro data
GyroX = GyX;
GyroY = GyY;
GyroZ = GyZ;
// Correct with gyro error values
GyroX = GyroX - GyroErrorX;
GyroY = GyroY - GyroErrorY;
GyroZ = GyroZ - GyroErrorZ;
// LP filter gyro data
GyroX = (1.0 - B_gyro) * GyroX_prev + B_gyro * GyroX;
GyroY = (1.0 - B_gyro) * GyroY_prev + B_gyro * GyroY;
GyroZ = (1.0 - B_gyro) * GyroZ_prev + B_gyro * GyroZ;
GyroX_prev = GyroX;
GyroY_prev = GyroY;
GyroZ_prev = GyroZ;
// Process mag data
MagX = MgX / 6.0; // uT
MagY = MgY / 6.0;
MagZ = MgZ / 6.0;
// Correct the outputs with the calculated error values
MagX = (MagX - MagErrorX) * MagScaleX;
MagY = (MagY - MagErrorY) * MagScaleY;
MagZ = (MagZ - MagErrorZ) * MagScaleZ;
// LP filter magnetometer data
MagX = (1.0 - B_mag) * MagX_prev + B_mag * MagX;
MagY = (1.0 - B_mag) * MagY_prev + B_mag * MagY;
MagZ = (1.0 - B_mag) * MagZ_prev + B_mag * MagZ;
MagX_prev = MagX;
MagY_prev = MagY;
MagZ_prev = MagZ;
// Return to avoid executing code for other IMUs
return;
#endif
// Accelerometer
@@ -732,6 +813,12 @@ void calculate_IMU_error()
#elif defined USE_MPU9250_SPI
mpu9250.getMotion9(&AcX, &AcY, &AcZ, &GyX, &GyY, &GyZ, &MgX, &MgY, &MgZ);
#elif defined USE_BNO085_I2C
while (!myIMU.dataAvailable())
{
delay(1); // Small delay to avoid hammering the I2C bus too hard
}
// bno magnetometer
MgX = myIMU.getMagX();
MgY = myIMU.getMagY();
@@ -741,13 +828,12 @@ void calculate_IMU_error()
GyX = myIMU.getGyroX() * 180 / PI;
GyY = myIMU.getGyroY() * 180 / PI;
GyZ = myIMU.getGyroZ() * 180 / PI;
Serial.println(GyZ);
// Acelleration (dont know if I need linear or normal. One way to find out)
AcX = myIMU.getAccelX();
AcY = myIMU.getAccelY();
AcZ = myIMU.getAccelZ();
AcX = myIMU.getAccelX() / 9.80665; // m/s² to g
AcY = myIMU.getAccelY() / 9.80665; // m/s² to g
AcZ = myIMU.getAccelZ() / 9.80665; // m/s² to g
#endif
AccX = AcX / ACCEL_SCALE_FACTOR;