Project

General

Profile

Revision e2a3c71f

IDe2a3c71f71fc38f72a7175df2e257c5b024bee41
Parent 2dde134c

Added by Thomas Mullins over 9 years ago

Added shutoff when current is sensed when enabling tool

Also made a number of fixes to current sensing, which was quite broken.

View differences:

toolbox/current.c
3 3
#include <avr/interrupt.h>
4 4
#include <math.h>
5 5

  
6
// TODO the ADC is run once every 2ms no matter what these numbers
7
// say. They're not used. Actual samples/cycle is around 8.3
6 8
#define CYCLES_PER_SECOND 60 // wall power
7
#define SAMPLES_PER_CYCLE 16
8
#define N_SAMPLES 48
9
#define SAMPLES_PER_CYCLE  8
10
#define N_SAMPLES 24
9 11

  
10 12
unsigned int samples[N_SAMPLES];
11 13
int sample_idx;
......
18 20
  /* TODO reduce power consumption with DIDR* */
19 21

  
20 22
  /*
21
   * COM1A = COM1B = 0, disconnect pins
22
   * WGM1 = 4, clear timer on compare A
23
   * CS1 = 1, no prescaler
24
   */
25
  TCCR1B = _BV(WGM12) | _BV(CS10);
26

  
27
  /* Timer is cleared on A, ADC is triggered on B */
28
  OCR1A = F_CPU / SAMPLES_PER_CYCLE / CYCLES_PER_SECOND;
29
  OCR1B = OCR1A;
30

  
31
  /*
32 23
   * REFS = 0, Vcc reference (set to 2 for internal 1.1V reference)
33 24
   * MUX = 8, PB3(ADC8)
34 25
   */
......
36 27

  
37 28
  /*
38 29
   * ADLAR = 0, right adjust result
39
   * ADTS = 5, start on timer 1 compare match B
40 30
   */
41
  ADCSRB = _BV(ADTS2) | _BV(ADTS0);
31
  ADCSRB = 0;
42 32

  
43 33
  /*
44 34
   * ADEN = 1, enable
45 35
   * ADSC = 0, don't start yet
46
   * ADATE = 1, auto trigger
36
   * ADATE = 0, no auto trigger
47 37
   * ADIE = 1, enable interrupt
48 38
   * ADPS = 6, prescale clock by 64
49 39
   */
50
  ADCSRA = _BV(ADEN) | _BV(ADATE) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1);
40
  ADCSRA = _BV(ADEN) | _BV(ADIE) | _BV(ADPS2) | _BV(ADPS1);
41
}
42

  
43
void current_start_adc() {
44
  ADCSRA |= _BV(ADSC);
51 45
}
52 46

  
53 47
ISR(ADC_vect) {
54 48
  unsigned int old, new;
55 49

  
56
  /* clear the timer interrupt flag so that the ADC will be triggered again
57
   * next time the timer resets */
58
  TIFR |= _BV(OCF1B);
59

  
60 50
  new = ADC;
61 51

  
62 52
  /* put sample into ring buffer */
toolbox/current.h
2 2
#define CURRENT_H
3 3

  
4 4
void current_init();
5
void current_start_adc();
5 6
unsigned int current_read();
6 7

  
7 8
#endif
toolbox/main.c
21 21
  TS_DENY,
22 22
  TS_REQ_DIS,
23 23
  TS_MISSING_ID,
24
  TS_ON
24
  TS_ON,
25
  TS_OVER_CURRENT
25 26
};
26 27

  
27 28
static enum toolstate_t toolstate = TS_INIT;
......
31 32
static uint16_t current;
32 33
//static uint16_t current_max_warn, current_max_hard;
33 34

  
35
// watch for current spike when tool turns on
36
#define CURRENT_STARTUP_THRESH   10
37
#define CURRENT_STARTUP_TIMEOUT 200 // ms
38
static uint8_t current_startup_timeout;
39
static uint16_t current_startup_value;
40

  
34 41
static inline void set_coil(char coil, char bit) {
35 42
  coils = (coils & ~(1 << coil)) | (bit << coil);
36 43
}
......
92 99
      if (get_coil(MB_COIL_EN)) {
93 100
        tool_enable();
94 101
        toolstate = TS_ON;
102
        current_startup_timeout = CURRENT_STARTUP_TIMEOUT / TICK_MS;
103
        current_startup_value = current + CURRENT_STARTUP_THRESH;
95 104
      } else if (!get_coil(MB_COIL_NEW)) {
96 105
        toolstate = TS_DENY;
97 106
      } else if (!serno_equal(current_user, latest_reading)) {
......
125 134
      break;
126 135

  
127 136
    case TS_MISSING_ID:
128
      if (!get_coil(MB_COIL_EN)) {
137
      if (current_startup_timeout > 0 && current > current_startup_value) {
138
        tool_disable();
139
        set_coil(MB_COIL_EN, 0);
140
        toolstate = TS_OVER_CURRENT;
141
        led_blink_start(500, 16, RED);
142
      } else if (!get_coil(MB_COIL_EN)) {
129 143
        tool_disable();
130 144
        toolstate = TS_OFF;
131 145
      } else if (get_coil(MB_COIL_REQ_DIS)) {
......
138 152
        serno_zero(current_user);
139 153
        toolstate = TS_OFF;
140 154
      }
155
      if (current_startup_timeout > 0) {
156
        current_startup_timeout--;
157
      }
141 158
      break;
142 159

  
143 160
    case TS_ON:
144 161
      led_green();
145
      if (!get_coil(MB_COIL_EN)) {
162
      if (current_startup_timeout > 0 && current > current_startup_value) {
163
        tool_disable();
164
        set_coil(MB_COIL_EN, 0);
165
        toolstate = TS_OVER_CURRENT;
166
        led_blink_start(500, 16, RED);
167
      } else if (!get_coil(MB_COIL_EN)) {
146 168
        tool_disable();
147 169
        serno_zero(current_user);
148 170
        toolstate = TS_OFF;
......
150 172
        toolstate = TS_REQ_DIS;
151 173
      } else if (!serno_equal(current_user, latest_reading)) {
152 174
        toolstate = TS_MISSING_ID;
153
        led_blink_start(500, 6, YELLOW); // TODO made 10 seconds
175
        led_blink_start(500, 16, YELLOW);
176
      }
177
      if (current_startup_timeout > 0) {
178
        current_startup_timeout--;
179
      }
180
      break;
181

  
182
    case TS_OVER_CURRENT:
183
      if (led_blink_done() && !serno_equal(current_user, latest_reading)) {
184
        toolstate = TS_OFF;
185
        serno_zero(current_user);
154 186
      }
155 187
      break;
156 188

  
toolbox/time.c
2 2
#include <avr/io.h>
3 3
#include <avr/interrupt.h>
4 4
#include "time.h"
5
#include "current.h"
5 6

  
6 7
/* F_CPU / PRESCALE = OCR * 1000 + ERROR */
7 8
#define OCR (F_CPU / PRESCALE / 1000UL)
......
23 24
    ready = 1;
24 25
    ms = 0;
25 26
  }
27
  if (ms % 2 == 0) {
28
    current_start_adc(); // TODO don't do this here
29
  }
26 30
}
27 31

  
28 32
void time_init() {

Also available in: Unified diff