-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtask 23 switch case.ino
145 lines (117 loc) · 3.48 KB
/
task 23 switch case.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <util/delay.h>
#include <avr/io.h> //allows for register commands to be understood
//Store at least 1000 result in a ring buffer (unsigned integers arrays): Done
//sample rate 200sample/s DONE
//External 5V at AREF: DONE
//Left Adjust ADC: DONE
//Use only 8 bit resolution: DONE
//Use ADC prescalar factor to 128: DONE
//Modify the circuit layout DONE
//Implement push button with two states: 1 to records and 2 to send data to PC
//Reset buffer when turn state 2 to 1
//Blink LED to show status
//Use PUTTY tools for input logging
#define S0 0
#define S1 1
// Declare variables
volatile bool state;
volatile bool read_on;
volatile uint8_t val;
volatile uint16_t reading;
volatile float voltage;
//Declare variable for ring buffer
#define SIZE_OF_BUFFER 5
volatile int start = -1;
int volatile end = -1;
uint8_t volatile database[SIZE_OF_BUFFER] = { 0 };
// Check if the array is full
bool isFull() {
if ((start == (end + 1)) || ((start == 0) && (end == SIZE_OF_BUFFER - 1))) {
return 1;
}
return 0;
}
//Add value to array
void add(uint8_t value) {
if (start == -1) {
start = 0;
}
end = (end + 1) % SIZE_OF_BUFFER;
database[end] = value;
}
//Remove value from array
void removeFirst() {
if (start == end) {
start = -1;
end = -1;
} else {
start = (start + 1) % SIZE_OF_BUFFER;
}
}
//Interrupt actions
ISR(TIMER1_COMPA_vect) {
read_on = 1;
}
ISR(INT0_vect) {
//Serial.println("Enter button ISR...");
state = !state;
//Serial.println("Exit button ISR...");
//Serial.print("State is ");
//Serial.println(state);
}
int main(void) {
cli();
// Set Pin 2 on Port D to read
DDRD &= ~(1 << DDD2);
//Set Left Adjust (8 bit ADC)
ADMUX |= (1 << ADLAR);
// Start the ADC, and set the LSBs in ADCSRA to 111, which corresponds to a division factor of 128. This should give us 200Sa/s
ADCSRA |= 0b10000111; // ADCSRA |= (1 << ADPS0)|(1 << ADPS1)|(1 << ADPS2)|(1 << ADEN);
//Set timer
TCCR1B |= (1 << WGM12); //CTC Mode
TCCR1B |= (1 << CS11) | (1 << CS10); //Set prescalar to 64
TCNT1 = 0; //Initialise timer to 0
TCCR1A |= (1 << COM1A0); //OC1A is toggled on match
OCR1A = 1250; //Set compare value Correspond to 200Hz count
TIMSK1 |= (1 << OCIE1A); //Enable CTC interrupt for OCR1A
//Set external interupt 0 (push button)
EICRA |= (1 << ISC00) | (1 << ISC01);
EIMSK |= (1 << INT0);
sei();
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
state = 1;
read_on = 0;
// the loop routine runs over and over again forever:
while (1) {
switch (state) {
case S0:
// Write
for (int i = start; i < SIZE_OF_BUFFER + start; i++) { // Check whether 2nd statement needs to be i != end + 1 or something
count = i % SIZE_OF_BUFFER;
reading = (database[count] << 2) | (0b11);
voltage = reading * 5.0 / 1023.0;
Serial.println(voltage);
//_delay_ms(5);
}
start = -1;
end = -1;
read_on = 0;
//Serial.println("End data readout...");
case S1:
// Read
//Serial.println("Reading...");
ADCSRA |= (1 << ADSC); //start conversion
//Use Ring Buffer to store data
val = ADCH;
if (isFull()) {
removeFirst();
add(val);
} else {
add(val);
}
// print out the value you read:
//Serial.println(database[end]);
}
}
}