Site Tools


projects:arduino_with_dragon_attiny13

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
projects:arduino_with_dragon_attiny13 [2020/09/21 13:10] – [Getting started] adminprojects:arduino_with_dragon_attiny13 [2020/10/11 19:20] (current) admin
Line 88: Line 88:
 void loop() { void loop() {
   for (int i=0; i <= 255; i++) {   for (int i=0; i <= 255; i++) {
-    digitalWrite(P2_PB3, (i & 1) != 0); +    digitalWrite(P2_PB3, (i & 1) ? HIGH : LOW); 
-    digitalWrite(P5_PB0, (i & 2) != 0); +    digitalWrite(P5_PB0, (i & 2) ? HIGH : LOW); 
-    digitalWrite(P6_PB1, (i & 4) != 0); +    digitalWrite(P6_PB1, (i & 4) ? HIGH : LOW); 
-    digitalWrite(P7_PB2, (i & 8) != 0);+    digitalWrite(P7_PB2, (i & 8) ? HIGH : LOW);
     delay(500);     delay(500);
   }   }
Line 97: Line 97:
 </code> </code>
  
-Now you can easy verify if all pins are correctly controlled: Pin 2 should show every 0.5 second a change, Pin 5 should show every second, pint 6 every 2 seconds and pin 7 every 4 seconds.+Now you can easy verify if all pins are correctly controlled: Pin 2 should show every 0.5 second a change, Pin 5 should show every second, pin 6 every 2 seconds and pin 7 every 4 seconds. 
 + 
 +===== Burst Controller ===== 
 +<code c> 
 +/** 
 + * ESD burst control 
 + * Controllersoftware for switching output pins in a sequence 
 + * based on a trigger from one input pin. 
 + *  
 + * The output pins control 3 high voltage relays and one 
 + * trigger output for measurement purposes. 
 + *  
 + * Input pin uses gpio and timer based interrupt to handle  
 + * debouncing and signal edge processing. This simplifies 
 + * processing a great deal. 
 + *  
 + * Hardware is based on the ATTINY13 8-bit microcontroller. 
 + * Development was done with Arduino IDE, extended with the 
 + * MicroCore, installed via:  
 + * Arduino Preferences -> Additional Boards Manager URLs 
 +   https://mcudude.github.io/MicroCore/package_MCUdude_MicroCore_index.json 
 + * And then selected via Tools -> Board -> MicroCore -> ATtiny13 
 + * The device is programmed using ISP programming with the AVR Dragon. 
 + * From within Arduino the ATtiny13 can then be programmed with the Upload 
 + * button. The selected programmer is the DragonISP. 
 + *  
 + * You need to edit the programmers.txt file in Arduino: 
 +   $HOME/.arduino15/packages/MicroCore/hardware/avr/1.0.6/programmers.txt 
 + *  
 + * See here for details: 
 +   https://www.auditeon.com/projects:arduino_with_dragon_attiny13 
 + *  
 + * For pinout, see following page: 
 + * https://github.com/MCUdude/MicroCore 
 + * 
 + * License: MIT 
 + * Author: Marc Nijdam 10-10-2020 
 + */ 
 + 
 + 
 +#define ARRAY_SIZE(x)  (sizeof(x) / sizeof(x[0])) 
 + 
 +#define P1_PB5_NC 5 
 +#define P2_PB3_TRIGOUT 3 
 +#define P3_PB4_TOGGLESW 4 
 +#define P5_PB0_CHARGE 0 
 +#define P6_PB1_DSCHRG 1 
 +#define P7_PB2_ALLOFF 2 
 + 
 +#define STOP 255 
 + 
 +/** 
 + * pin name and active state 
 + */ 
 +const struct { 
 +  const uint8_t pin; // pin name 
 +  const uint8_t das; // default active state 
 +} io[] = { 
 +  [0] = {P7_PB2_ALLOFF ,1}, // bit 0, active high 
 +  [1] = {P2_PB3_TRIGOUT,1}, // bit 1, active high 
 +  [2] = {P6_PB1_DSCHRG ,0}, // bit 2, active low 
 +  [3] = {P5_PB0_CHARGE ,0}, // bit 3, active low 
 +  [4] = {P1_PB5_NC ,1}      // reset pin 
 +   
 +}; 
 + 
 +/** 
 +  ____> charge -------------> (i.e. on high, switch closes) 
 + * | ___> discharge ----------> (i.e. on high, switch closes) 
 + * || __> trigout + pulldown -> (i.e. on high, trigger goes up.) 
 + * ||| _> all off ------------> (i.e. on high, it connects output to gnd) 
 + * |||| 
 + * 0000 
 + * 
 + * 0: not active  
 + * 1: active 
 + */ 
 +const struct { 
 +  const uint8_t bits; // bitpattern for gpio output pins 
 +  const uint16_t dur; // duration in ms 
 +} patterns[] = { 
 +  {0b0000,  100}, /*  charge   */ 
 +  {0b0000,  100}, /*         */ 
 +  {0b1000,    0}, /*    \ /    */ 
 +  {STOP, 0},      /*   _____   */ 
 +  {0b0101,    0}, /*           */ 
 +  {0b0110, 5000}, /*    / \    */ 
 +  {0b0010,    0}, /*         */ 
 +  {0b0000,  500}, /*         */ 
 +  {0b0000,  100}, /* discharge */ 
 +}; 
 + 
 +/* counter which points to index of array */ 
 +volatile uint8_t processing; 
 +volatile uint8_t pat_idx; 
 +volatile uint8_t mode; // 0: charge, 1: discharge 
 + 
 +void setup() { 
 +  /* initialize digital in- and output pins */ 
 +  pinMode(P3_PB4_TOGGLESW, INPUT_PULLUP); 
 +  for (uint8_t i=0; i < ARRAY_SIZE(io); i++) { 
 +    pinMode(io[i].pin, OUTPUT); 
 +  } 
 + 
 +  mode = digitalRead(P3_PB4_TOGGLESW); // switch: 0=charging, 1=discharging 
 + 
 +  /* initialize flag, 0: processing not initiated, 1: processing */ 
 +  processing = 0; 
 + 
 +  /* enable interrupt from PB4 */ 
 +  setup_gpio_interrupt(P3_PB4_TOGGLESW); 
 +  enable_pcint_interrupt(); 
 + 
 +  /* enable interrupt from timer for semi-automatic with 1x 0.12ms debounce */ 
 +  setup_timer_interrupt(1); 
 + 
 +  /* enable all interrupts */ 
 +  sei(); 
 +
 + 
 +// the loop function runs over and over again forever 
 +void loop() { 
 +  if (!processing) { 
 +    processing = 1; 
 +    process_sequence(mode); 
 +  } 
 +
 + 
 +void process_sequence(uint8_t md) { 
 +  pat_idx = md ? ARRAY_SIZE(patterns) - 1 : 0; 
 +  for (;;) { 
 +    set_bits(patterns[pat_idx].bits); 
 +    /* wait ms duration, unless interrupted by switch */ 
 +    if (wait_ms(patterns[pat_idx].dur)) return; 
 +    pat_idx += 1 - 2*md; 
 +    if (patterns[pat_idx].bits == STOP) return; 
 +  } 
 +
 + 
 +/** 
 + * Set bit pattern onto gpio output 
 + * take into account active state 
 + */ 
 +void set_bits(uint8_t bits) { 
 +  for (uint8_t i=0; i < ARRAY_SIZE(io); i++) { 
 +    digitalWrite(io[i].pin, !io[i].das ^ (( (1 << i) & bits) ? HIGH : LOW)); 
 +  } 
 +
 + 
 +uint8_t wait_ms(uint16_t d) { 
 +  unsigned long ts = millis() + d; 
 +  for (;;) { 
 +    if (millis() >= ts) return 0; 
 +    if (!processing) return 1; 
 +    delay(1); 
 +  } 
 +
 + 
 +void setup_gpio_interrupt(uint8_t port) { 
 +  pinMode(port, INPUT_PULLUP); 
 +  MCUCR |=  (1<<ISC00); // Trigger INT0 on rising edge 
 +  MCUCR &= ~(1<<ISC01); // Trigger INT1 on rising edge 
 +  PCMSK |= (1<<PCINT4); // pin change mask: listen to portb, pin PB4 
 +
 + 
 +/** 
 + * enable PCINT interrupt 
 + */ 
 +void enable_pcint_interrupt(void) { 
 +  GIMSK |= (1<<PCIE); 
 +
 + 
 +/** 
 + * disable PCINT interrupt 
 + */ 
 +void disable_pcint_interrupt(void) { 
 +  GIMSK &= ~(1<<PCIE); 
 +
 + 
 +/** 
 + * @brief setup timer interrupt 
 + * @param duration in unit of +/- 0.125ms 
 + */ 
 +void setup_timer_interrupt(uint8_t d) { 
 +  TCCR0A |= _BV(WGM01); // set timer counter mode to CTC 
 +  TCCR0B |= _BV(CS02)|_BV(CS00); // set prescaler to 1024 (CLK=1200000Hz/1024/256=4.57Hz, 0.22s) 
 +  OCR0A = d; // set Timer's counter max value 
 +
 + 
 +void enable_timer_interrupt(void) { 
 +  TIMSK0 |= _BV(OCIE0A); // enable Timer CTC interrupt 
 +
 + 
 +void disable_timer_interrupt(void) { 
 +  TIMSK0 &= ~_BV(OCIE0A); // disable Timer CTC interrupt 
 +
 + 
 +ISR(PCINT0_vect) // Interrupt on Int0 vector 
 +
 +  disable_pcint_interrupt(); 
 +  /* prevent false interrupt from switch, only allow toggle */ 
 +  if (mode != digitalRead(P3_PB4_TOGGLESW)) { 
 +    mode = digitalRead(P3_PB4_TOGGLESW); 
 +    processing = 0; 
 +  } 
 +  /* use timer interrupt for debouncing */ 
 +  enable_timer_interrupt();   
 +
 + 
 +ISR(TIM0_COMPA_vect) // Interrupt on Timer0 vector 
 +
 +  disable_timer_interrupt(); 
 +  enable_pcint_interrupt(); 
 +
 +</code>
projects/arduino_with_dragon_attiny13.1600686620.txt.gz · Last modified: 2020/09/21 13:10 by admin