Skip to content
Snippets Groups Projects
Commit d4108dee authored by Sam Calisch's avatar Sam Calisch
Browse files

first paths

parent 339cc5f3
No related branches found
No related tags found
No related merge requests found
......@@ -3,60 +3,69 @@
#include <avr/sleep.h>
#include <util/delay.h>
#define CLOCK_DIV_bm TC_CLKSEL_DIV64_gc
#define CLOCK_DIV 64
#define LED1_mask PIN2_bm
#define LED2_mask PIN3_bm
#define encoder_mask PIN0_bm
//#define wire_d 202000 //32 AWG, magnet wire diameter in nanometers
#define wire_d 180000 //33 AWG, magnet wire diameter in nanometers
uint32_t wire_d = 180000; //33 AWG, magnet wire diameter in nanometers
//#define wire_d 160000 //34 AWG, magnet wire diameter in nanometers
#define n_ticks_per_rev 400 //number of encoder edges per revolution
#define nm_per_step 1270 //full steps for now
#define n_layers 10 //how many layers total
#define n_wraps_per_layer 8 //how many coil wraps per layer before reversing
//unsigned uint16_t wire_d = 202000; //32 AWG, magnet wire diameter in nanometers
//const uint32_t wire_d = 180000; //33 AWG, magnet wire diameter in nanometers
//unsigned uint16_t wire_d = 160000; //34 AWG, magnet wire diameter in nanometers
//const uint32_t nm_per_step = 1270; //full steps, TODO: measure this, right now its approximate.
//const uint32_t n_wraps_per_layer = 8; //how many coil wraps per layer before reversing
//const uint32_t n_layers = 10; //how many layers total
//const uint32_t n_ticks_per_rev = 200; //number of encoder ticks per revolution
uint32_t max_x = n_wraps_per_layer*wire_d; //maximum distance traversed
uint32_t n_ticks_per_layer = n_ticks_per_rev * n_wraps_per_layer; //how many encoder ticks per layer
uint32_t n_ticks_per_rev = 400; //number of encoder edges per revolution
uint32_t nm_per_step = 1270; //full steps for now
uint32_t n_layers = 10; //how many layers total
uint32_t n_wraps_per_layer = 8; //how many coil wraps per layer before reversing
//uint32_t max_x = n_wraps_per_layer*wire_d; //maximum distance traversed
//uint32_t n_ticks_per_layer = n_ticks_per_rev * n_wraps_per_layer; //how many encoder ticks per layer
//state variables
uint32_t n_ticks_per_layer = 0;
uint32_t count = 0;
uint32_t n_layers_done = 0;
uint32_t n_wraps_this_layer = 0;
uint32_t n_ticks_this_rev = 0;
uint32_t x_desired = 0; //where we want the tip, measured in nanometers
uint32_t x_current = 0; //where we are currently, measured in nanometers
void update_desired_x(){
//function to implement wraps and layering.
//ticks: current number of encoder ticks as measured from the starting point.
// one tick is an edge of the encoder signal
//TODO: measure ticks per rev of the coil winder. It's about 100.
n_layers_done = TCC0.CNT / n_ticks_per_layer;
n_wraps_this_layer = (TCC0.CNT % n_ticks_per_layer) / n_ticks_per_rev;
n_ticks_this_rev = (TCC0.CNT % n_ticks_per_rev);
x_desired = n_wraps_this_layer * wire_d + (n_ticks_this_rev * wire_d) / n_ticks_per_rev;
if (n_layers_done % 2 == 1){
x_desired = max_x - x_desired; //flip odd layer directions
}
n_ticks_per_layer = n_ticks_per_rev * n_wraps_per_layer; //how many encoder ticks per layer
count = (uint32_t)TCC0.CNT + 65535*(uint32_t)TCC1.CNT;
n_layers_done = count / n_ticks_per_layer;
if (n_layers_done == n_layers){
x_desired = 0; //stay at home if we're done
} else {
n_wraps_this_layer = (count % n_ticks_per_layer) / n_ticks_per_rev;
n_ticks_this_rev = (count % n_ticks_per_rev);
x_desired = n_wraps_this_layer * wire_d + (n_ticks_this_rev * wire_d) / n_ticks_per_rev;
if (n_layers_done % 2 == 1){
x_desired = n_wraps_per_layer*wire_d - x_desired; //flip odd layer directions
}
}
}
void step(){
PORTD.OUTSET = PIN5_bm;
PORTC.OUTSET = PIN4_bm;
void step_forward(){
PORTD.OUTCLR = PIN6_bm; //dir forward
PORTC.OUTCLR = PIN5_bm; //dir forward
PORTD.OUTSET = PIN5_bm; //step up
PORTC.OUTSET = PIN4_bm; //step up
//PORTE.OUTSET = LED1_mask; //light led
_delay_us(10);
PORTD.OUTCLR = PIN5_bm;
PORTC.OUTCLR = PIN4_bm;
PORTD.OUTCLR = PIN5_bm; //step down
PORTC.OUTCLR = PIN4_bm; //step down
x_current += nm_per_step; //update current x
//PORTE.OUTCLR = LED1_mask; //dark led
}
void step_backward(){
PORTD.OUTSET = PIN6_bm; //dir backward
PORTC.OUTSET = PIN5_bm; //dir backward
PORTD.OUTSET = PIN5_bm; //step up
PORTC.OUTSET = PIN4_bm; //step up
//PORTE.OUTSET = LED2_mask; //light led
_delay_us(10);
PORTD.OUTCLR = PIN5_bm; //step down
PORTC.OUTCLR = PIN4_bm; //step down
x_current -= nm_per_step; //update current x
//PORTE.OUTCLR = LED2_mask; //dark led
}
int main(void) {
......@@ -83,9 +92,9 @@ int main(void) {
//cascade tcc0 overflow into tcc1 using event channel 1 so we get 32 bit counter of encoder pulses
//with 400 ticks per revolution, that's ~160 turns before 16-bit overflow
//only issue is we can't discriminate overflow from underflow...
//EVSYS.CH1MUX = EVSYS_CHMUX_TCC0_OVF_gc;
//TCC1.CTRLA = TC_CLKSEL_EVCH1_gc;
//TCC1.PER = 0xFFFF;
EVSYS.CH1MUX = EVSYS_CHMUX_TCC0_OVF_gc;
TCC1.CTRLA = TC_CLKSEL_EVCH1_gc;
TCC1.PER = 0xFFFF;
//DAC for current control, PB3 = DAC CHannel 1
DACB.CTRLA = DAC_CH1EN_bm | DAC_ENABLE_bm;
......@@ -98,13 +107,20 @@ int main(void) {
//stepper 1
PORTD.DIRSET = PIN3_bm | PIN4_bm | PIN5_bm | PIN6_bm | PIN7_bm; //set outputs
PORTD.OUTSET = PIN3_bm | PIN4_bm; //full steps
//PORTD.OUTSET = PIN7_bm; //enable
PORTD.OUTSET = PIN7_bm; //enable
//stepper 2
PORTC.DIRSET = PIN2_bm | PIN3_bm | PIN4_bm | PIN5_bm | PIN6_bm; //set outputs
PORTC.OUTSET = PIN2_bm | PIN3_bm; //full steps
//PORTC.OUTSET = PIN6_bm; //enable
PORTC.OUTSET = PIN6_bm; //enable
while (1) {
update_desired_x();
if (x_desired > x_current){
step_forward();
} else if (x_desired < x_current){
step_backward();
}
/*if (TCC0.CNT % 100 == 0){ PORTE.OUTSET = LED1_mask; step();}
if (TCC0.CNT % 100 == 25){ PORTE.OUTSET = LED2_mask; step();}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment