File transfer push (organization different)

This commit is contained in:
Blizzard Finnegan 2021-12-16 16:39:54 -05:00
commit 640bb766c4
95 changed files with 3534 additions and 0 deletions

139
1-January/1-13_Notes.md Executable file
View file

@ -0,0 +1,139 @@
Opening lectures are gonna be real quick, so listen up
# Announcements
- Install arduino IDE
- Download PDF for Atmel
- buy a binder
***Syllabus quiz on Wednesday***
# Basics
Microcontrollers are everywhere.
Microcontrollers have a processor, and D/A or A/D converters. (digital-analog/vice--versa)
Essentially any integrated system has a microcontroller
The board we used last year is what we're using this year. The microcontroller is the Atmel Atmega 328P. The board itself is still an arduino, but its not the microcontroller.
The robot we're making a robot with a visualizer, 2 motorized wheels, an IR module, and a Bluetooth module.
At the end of the semester, we'll come up with our own project.
USE www.Arduino.cc A LOT. There's support, code, etc. etc.
Download the datasheet. There's a lot of pages, so don't print it. Understand it, live with it, sleep with it.
# Ports
## Microcontroller Parts
They have to have the following
- Microprocessor
- Memory
- flash for program storage (stable memory)
- RAM for working memory (unstable memory)
- **I/O ports**
- Built in peripherals
- timers
- serial interfaces (maybe)
- A/D and D/A converters (maybe)
What are I/O devices for your PC?
- Keyboard
- Mouse
- Screen
- etc.
What are I/O devices for the microcontroller?
- A/D and D/A for both ins and outs
- Anything that isn't self-contained within the microcontroller is an I/O device
There are 3 ports that we'll use: B, C, D
Each microcontroller has 23 pins for I/O
It is possible to touch the 24th pin, but... just don't.
==This means that Port C only has 7 pins==
Each port can be used pin-by-pin or all of them as a (7 DT 0) vector, or any combination in between.
In output mode, the program puts either VCC or GND on the pin. In input mode, the program reads the voltage on the pin and determines if its VCC or GND.
If VCC is 5 and GND is 0, make sure the input is $\pm 2 \%$
Standard notation is PXn (Pin Port Pin#)
Memorize the pins. Its important.
![atmegaPinout](../atmegaPinout.png)
## Code example
![image-20200113102924585](image-20200113102924585.png)
What does this do?
In line order:
line 1 is a comment
line 2 is a definition for readability. In this case, its naming a pin, in the context of the code. It also removes magic numbers.
Line 4-7 is setting up for the loop. Line 5 is defining that pin 13 is an output. (Note: this is not microcontroller pin 5. This is digital pin 13, or PB5.) Line 6 sets an initial state. HIGH and LOW are arduinoC keywords, and 0 and 1 are also acceptable.
Line 9-14 is an infinite loop that flashes the LED. Note that the comment is incorrect, and the delay is for $1 \over 2$ seconds. The measurement of delay is in milliseconds.
(Note: We will eventually learn how to make this in standard C instead of Arduino C)
# Syllabus Notes
Homework: 15%
Quizzes: 15%
Hour Exams: 40%
- 2/7
- 3/6
- 4/10
Final Exam: 30%
Final Grade:
- 93%+ = A
- 90%+= A-
- 87%+= B+
- 83%+= B
- 80%+= B-
- 77%+= C+
Final Grade = (attended classes / 40) * grade earned

132
1-January/1-15_Notes.md Executable file
View file

@ -0,0 +1,132 @@
# Ports
## Port B
mainly used for oscillators and timers
## Port C
mainly used for A/D conversion or pin change interrupts. (PC6 is an external active low RESET)
## Port D
mainly used for communication or pin change interrupts
Pins dont immediately go to high or low. If you arent driving it, its an unstable output. As such, there are pull-up resistors, which pulls the value up toward 1.
Any pushbuttons will use pull-ups.
Avoid ports C until we start doing analog.
To configure and use Port D, you need to configure PORTD, the data register, DDRD, the data direction register, and the PIND, the port input pin addresses.
### DDRD - Port D Data Direction Register
Writing a 1 initializes a pin to make it an output
Writing a 0 makes the pin an input
ArduinoC uses the red numbers in the main image. In C, write to the register.
```c
void setup{
DDRD = 0b00000010;
}
```
### PORTD - Port D Data Register
Writing a 1 sets the pin high
writing a 0 sets the pin low
#### Example
```c
void setup{
DDRD = 0xFF;
}
void loop{
PORTD=0x01;
delay(1000);
PORTD=0xFE;
delay(1000);
}
```
### PIND - Port D input pin address
READING a 1 indicates its being driven externally to a high
READING a 0 indicates its being driven externally to a low
***DO NOT WRITE TO THIS REGISTER***
# Masking
In embedded programming we often need to manipulate individual bits.
- `~` inversion
- `&` AND
- use for clearing registers
- AND with 1 will leave the bit untouched, and 0s to clear
- `|` OR
- use for setting specific values in a register
- will leave all zeroes alone, only setting 1s
- `^` XOR
- `>>` shift right
- `<<` shift left
# Code examples
instead of:
```c
void setup(){
DDRD = 0x02;
}
```
Use:
```c
void setup(){
DDRD |= 0x02;
}
```
This does not change initial values already in the system, except for the ones you want it to.
```c
void setup(){
DDRD |= 0xFF;
}
void loop(){
PORTD |= 0x01;
delay(1000);
PORTD &= 0xFE;
delay(1000);
}
```
Start understanding register programming, as it takes up less space, and is more universally portable.
## Lab 1 register example
```c
void setup(){
DDRB|=0x20; //makes PB5 an output
PORTB &= 0xDF; //drives PB5 low
}
```

32
1-January/1-22_Notes.md Normal file
View file

@ -0,0 +1,32 @@
# Hardware of I/O pin
A buffer or an amp is a WYSIWYG part. Its used to ensure that the chip doesnt burn out (Also, ESD protection and amplification).
![triState](triState.png)
There is also a 3-state buffer. This allows for bi-directional output by having a tri-state out and a buffer in from the same line. This is how bi-directional I/O on the microcontroller works.
# Inputs and Pullups
So, weve already established how inputs work, using the DDRx (1 for out, 0 for in), PINx (current value), and PORTx (driven value from microcontroller). Weve also established that pull-ups exist. But how do we force the pin to USE the resistor?
In ArduinoC, we use the `pinMode(x, INPUT_PULLUP);`. We make the pin an input, then write a 1.
ex.
```c
DDRD &= 0xFB;
PORTD |= 0x04;
```
# Reading Input Pins
If you want to know the value of pin 2, `AND` the PINx register with a mask, where the mask has a 1 in the positions of the bits you care about, and a 0 in the ones you dont. If the result is true, its `HIGH`.
```c
if (PIND & 0x04){};
```
The above `AND`ing function works as such. If ALL of the values are `0` then its `FALSE`. If there is ANY OTHER VALUE, it is `TRUE`.
In ArduinoC, the function is `digitalRead(pinNumber)`, and will output a high, or a low.

53
1-January/1-27_Notes.md Normal file
View file

@ -0,0 +1,53 @@
On the resume, dont put ArduinoC, put C. You worked with the Arduino platform, not the ArduinoC language.
Here is a step by step for lab 2.
```c
enum {STOP, LED_ON, LED_OFF};
int state = STOP, prevState = !state;
// This previous state is to define that its the first time in that state
boolean isNewState;
int stateTimer;
boolean isSwPressed, prevIsSwPressed, isSwJustPressed;
void setup(){
DDRD &= 0xDF;
PORTD |= 0x20;
DDRB |= 0x08;
PORTB &= 0xF7;
}
void loop(){
prevIsSwPressed = isSwPressed;
isSwPressed = !(PIND & 0x20);
isSwJustPressed = (!isSwPressed && prevIsSwPressed);
isNewState = (state != prevState);
prevState = state;
switch(state){
case STOP:
if(isNewState){
Serial.printls("STOP");
PORTB &= 0xF7;
}
if(isSwJustPressed) state = LED_ON;
break;
case LED_ON:
if(isNewState){
stateTimer = 0;
Serial.println("LED_ON");
PORTB |= 0x04;
}
stateTimer++;
if (isSwJustPressed){
PORTB &= 0xF7;
state = STOP;
}
if (stateTimer >= 250) state = LED_OFF;
break;
default: state = STOP;
}
delay(1);
}
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

87
1-January/1-29_Notes.md Normal file
View file

@ -0,0 +1,87 @@
# Counters and Timers
Its the same internal structure. The difference is whether its connected to system clock or an external event.
![timerStructure](1-29_Notes.assets/timerStructure.png)
But whats wrong with delays? Delays stop everything the CPU is doing. The timers dont. When they hit the “time”, they interrupt, but it lets things run instead of it.
There are 3 timers.
timer/counter 0 and 2 are 8bit, with a 256 step resolution. Timer/counter 1 is a 16 bit timer, with a 65k step resolution.
==**Remember: Frequency = 1/time**==
==The clock on the arduino is 16Mhz. This works out to 62.5ns. This will most likely be tested on.==
TCNTn is the generic way of referring to a counter register. You can read or write to this register. This makes something like a stopwatch easy to implement. (write 0s, do something, read the register)
Timer0 and Timer2 will roll over after $16\mu s$, so dont expect it to go farther than that. Timer1 is for long-term timing (maxes out at 1ms)
But timers arent this simple. You can do more fun things with them, and less difficult things as well.
## Timer Registers
### Output Comparator Registers
![outputCompareRegister](1-29_Notes.assets/outputCompareRegister.png)
You can set OCRnA and OCRnB to a specific value. When the TCNT hits the value in OCR, then the OCF will go high. The TOV goes high to let you know that the TCNT has rolled over.
Timer0 information:
- `TCNT0`
- `OCR0A`
- `OCR0B`
Timer2 information:
- `TCNT2`
- `OCR2A`
- `OCR2B`
Timer1 information:
- `TCNT1H` (15:8)
- `TCNT1L` (7:0)
- `OCR1AH`
- `OCR1AL`
- `OCR1BH`
- `OCR1BL`
### Timer Control Registers
`TCCRnA` and `TCCRnB` control the functionality of the timers.
- the mode of operation
- what to do on compare match
- force output compare
- fast PWM mode
- Phase Corrected PWM mode
- more that havent been discussed (:sadface:)
#### Normal mode
Simplest. Counter counts, then rolls over.
Used for counting ticks.
#### CTC mode
clears timer to 0 when `TCNTn ` matches `OCRnA`.
Eventually, well use Fast PWM, and Phase Corrected PWM once or twice, but these are about it.
`TCCRnB` does clock-division, while `TCCRnA` does the above shown tasks.

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

69
1-January/1-31_Notes.md Normal file
View file

@ -0,0 +1,69 @@
# ==END OF WEEK 3==
---
# Normal Mode
- Constant incrementing
- rollover when clock-space filled
- TIFRx bit 0 returns whether the timer has overflowed. ==***Reset this by writing a 1***==
- Write to the TCNTx to set when the timer should reset. The number is to be subtracted from the timers max before writing. For example
- 160 count timer: $255-160=95$
- `TCNT0 = 95;`
- `if (TIRF0 & 0x01)`
- `TIFR0 |=0x01;`
- This will reset the overflow bit
## Code Example ($10\mu s$ delay)
```c
void setup(){
//initialize i/o
//initialize timer
}
void loop(){
//do stuff
TCNT0 = 95;
while ((TIFR0 & 0x01) == 0); //wait for 10us
TIFR0 |= 0x01;
//do more stuff
}
```
Still inefficient, but interrupts are something we dont know yet
# CTC Mode
- Counts up from 0 until it reaches `OCRnA`. When theyre equal, `TCNTn` is set back to 0, and the `OCFxA` is set, and counting resets
- Can be used to output a square wave. The output inverts every time `TCNTn` reaches `OCRnA`
# Controlling outputs
![pinoutDiagram](1-31_Notes.assets/image-20200113102850434.png)
Pins `PD3`, `PD5`, `PD6`, `PB1`, `PB2`, and `PB3` are connected to timers.
3 bit waveform generation:
![outputControl](1-31_Notes.assets/outputMode.png)
`WGM02` is bit 3 in `TCCRxB`. `WGM01` and `WGM00` are bits 1 and 0 respectively in `TCCRnA`
Setting Prescaler:
![preScaler](1-31_Notes.assets/preScaler.png)
`TCCRnA` bits 7 and 6 are how to set the output pin for `OCnA`. bits 5 and 4 are for `OCnB`, and have the same table.
![outputClock](1-31_Notes.assets/clockOutput.png)
# Clock Scaling
Each timer has prescaling options to divide down the clock
$t_{elapsed}=cnt\times{N\over16MHz}$
The prescaler for the clock is bits 2-0 in `TCCRnB`
![clockScaling](1-31_Notes.assets/clockScaling.png)

BIN
1-January/clockOutput.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
1-January/clockScaling.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

11
1-January/homework1.md Executable file
View file

@ -0,0 +1,11 @@
# Skyler MacDougall
## Homework 1 : due 1/22/2020
1. Research some widely used microcontrollers, and compare and contrast their performance.
After significant research, I was unable to find two microcontrollers with easily comparable performance numbers, such as some form of MIPS.
3. Create an invention using a microcontroller. Describe your invention and the role the microcontroller plays in the invention.
My invention would be a switch that keeps itself flipped in one direction. It is a box containing a switch, a flap, and an actuator. When the switch is flipped, the flap would open, and the actuator would flip the switch back to its original position. The microcontroller would control the flap and the actuator.

BIN
1-January/homework1.pdf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
1-January/outputMode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
1-January/preScaler.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
1-January/triState.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

66
2-February/2-10_Notes.md Normal file
View file

@ -0,0 +1,66 @@
# PWM
But why tho?
- power efficiency
- having the light off 10% of the time
- fade/dim instead of blink
- variable speed motors
- non-square audio waves
Signal toggles extremely fast, and is observed as a rough sine wave
frequency is how often it pulses
duty cycle is how much of the frequency is high
## Pins used by PWM
- PD3
- OC2B
- PD5
- OC0B
- PD6
- OC0A
- PB1
- OC1A
- PB2
- OC1B
- PB3
- OC2A
# Fast PWM mode (0 & 2)
## Mode 3
OCRA or OCRB determine when it comes down from 1. It goes back up to 1 when the timer rolls over
# Mode 7
OCRB sets when to come down from 1. OCRA says to go back to 1
Non-inverting is standard (see above), inverting is the opposite of above
$$
f_{OCnxPWM}={f_{clkI/O}\over N\times count_{clock}}
$$
# Servos
20ms PWM period
1-2ms duty cycle

88
2-February/2-12_Notes.md Normal file
View file

@ -0,0 +1,88 @@
# Modes of Operation review
- **==Normal mode==**
- simplest mode
- counter counts to 255/2^16^ and then rolls over
- used most when youre counting ticks or timing an event
- **==CTC==**
- counter cleared when `TCNT==OCRA | OCRB`
- used to create waveforms and interrupts
- **==Fast PWM==**
- creates a waveform with fixed frequency and variable duty cycle
- Toggles high and low quickly enough that only an average voltage is detected
# Timer configuration checklist
- [ ] consult datasheet registers
- [ ] decide the timer to use
- [ ] default to T1
- [ ] if 8 bits is fine, use T0 or T2
- [ ] Decide which mode you need
- counting or timing?
- [ ] normal mode (no configuration)
- Are you using the timer as a time base or frequency generator?
- [ ] Use CTC mode
- Are using the timer for PWM?
- [ ] PWM mode… duh
- [ ] Direct output pins?
- [ ] `COMA`
- [ ] `COMB`
- [ ] Determine which clock speed devisor you need
- [ ] set in `TCCRB`
- [ ] Set a default for `OCRA/OCRB`
- [ ] Set the pins to output mode
- [ ] interrupts?
- [ ] `cli();`
- [ ] Write to `TIMSK`
- [ ] Enable counter overflow interrupt in normal mode
- [ ] enable output compare interrupts in PWM/CTC mode
- [ ] `sei();`
- [ ] Write `ISR` function
# PWM mode in T1
Many different PWM modes. Todays focus:
- mode 5 (8-bit top)
- mode 6 (9-bit top)
- mode 7 (10-bit top)
- mode 14 (`ICR1` top)
- mode 15 (`OCR1A` top)
Frequency is fixed in modes 5, 6, 7. `OCR1A/OCR1B` determines the duty cycle.
In mode 14, `ICR1` sets the frequency, and `OCR1A/OCR1B` determines the duty cycle.
In the above, the duty cycle determines the pin.
In mode 15, `OCR1A` sets the frequency, and `OCR1B` is used to set the duty cycle. The output pin is always `OCR1B/PB2`
# Question
20ms period. What mode, and what scale for the clock?
I would use mode 15, so the prescaler is easy to set, and the output pin is defined.
$$
4ms=prescale_1;\ 32ms=prescale_8;\ 262ms=prescale_{64}\\
1s=prescale_{256};\ 4s=prescale_{1024}\\
4ms\le20ms\le32ms\\
\therefore\\
prescaler=8
$$

View file

@ -0,0 +1,8 @@
# Question
20ms period. What mode, and what scale for the clock?
I would use mode 15, so the prescaler is easy to set, and the output pin is defined.
$$
4ms=prescale_1;\ 32ms=prescale_8;\ 262ms=prescale_{64}\\1s=prescale_{256};\ 4s=prescale_{1024}\\4ms\le20ms\le32ms\\\therefore\\prescaler=8
$$

View file

@ -0,0 +1,15 @@
1. 60 second timer
- (15) 4 second timers.
- main waits for a button, then runs the code, then waits again
```c
```
2. copy above, but drive the LED using the PWM signal
```c
```

57
2-February/2-17_Notes.md Normal file
View file

@ -0,0 +1,57 @@
# Interrupts vs Polling
Interrupts provide priority, free up the CPU, and let you complete tasks faster
Where do interrupts come from?
- A/D converters
- Timers/counters
- Push buttons
- Sensors
- etc.
Only one interrupt at a time. (Except RESET, but thats… different)
Interrupts do the following
- stores and shuts down all processes
- runs ISR
- restores programs
# Pin Change Interrupts
`pinState != prevPinState`
Pin interrupts are grouped together in banks (these are the same as the ports).
`INT0` and `INT1` can trigger on specific points (Rising/falling edge, toggle, or cont. low), with second highest priority interrupt
==MULTIPLE PINS SHARE INTERRUPT VECTORS==
`PCINT0`=`PCINT0_vect`
`PCINT1`=`PCINT1_vect`
`PCINT2`=`PCINT2_vect`
`PCMSKn` tells the microcontroller what pins are valid interrupts. Essentially, an enable for the interrupts.
`PCICRn` turns on the individual interrupt
## Set pin change interrupts
1. `cli()`
2. Enable `PCICR`
3. set pins `PCMSKn`
4. `sei()`

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

76
2-February/2-19_Notes.md Normal file
View file

@ -0,0 +1,76 @@
# External Interrupts
These are PD2 and PD3. labeled as `INTn` with the logical vector.
Changing bits 1 and 0 in `EIMSK` enables those interrupts. `EICRA` determines when the interrupt is triggered.
steps:
- [ ] `cli();`
- [ ] Enable your specific detection mode `EICRA`
- [ ] set appropriate bits in `EIMSK`
- [ ] `sei();`
# Volatile and Static variables
## Volatile
Denotes variables changable in the ISR.
![](2-19_Notes.assets/codeBlock1.png)
## Static
used when a variable should keep its value between ISR calls
# Coding problem
Create a game show setup
- [ ] each contestant has the ability to force PD4-PD7 low
- [ ] first to buzz in lights up PB0-PB3 respectively
- [ ] interrupt definition for who buzzed first
Tasks
- [x] initialize ports
- [x] initialize interrupts
- [x] write ISR
```c
void setup(){
DDRB |= 0x0F;
DDRD &= 0x0F;
PORTB &= 0xF0;
PORTD |= 0xF0;
cli();
PCICR = 4;
PCMSK2 = 0xF0;
sei();
}
void loop(){
while(1){}
}
ISR(PCINT2_vect){
byte inputPins = PIND;
if(inputPins & 0x10) {
PORTB |= 0x01;
PORTB &= 0xF1;
}
if(inputPins & 0x20) {
PORTB |= 0x02;
PORTB &= 0xF2;
}
if(inputPins & 0x40) {
PORTB |= 0x04;
PORTB &= 0xF4;
}
}
```

View file

@ -0,0 +1,47 @@
# Coding problem
Create a game show setup
- [x] each contestant has the ability to force PD4-PD7 low
- [x] first to buzz in lights up PB0-PB3 respectively
- [x] interrupt definition for who buzzed first
Tasks
- [x] initialize ports
- [x] initialize interrupts
- [x] write ISR
```c
void setup(){
DDRB |= 0x0F;
DDRD &= 0x0F;
PORTB &= 0xF0;
PORTD |= 0xF0;
cli();
PCICR = 4;
PCMSK2 = 0xF0;
sei();
}
void loop(){
while(1){}
}
ISR(PCINT2_vect){
byte inputPins = PIND;
if(inputPins & 0x10) {
PORTB |= 0x01;
PORTB &= 0xF1;
}
if(inputPins & 0x20) {
PORTB |= 0x02;
PORTB &= 0xF2;
}
if(inputPins & 0x40) {
PORTB |= 0x04;
PORTB &= 0xF4;
}
}
```

Binary file not shown.

View file

@ -0,0 +1,99 @@
# Skyler MacDougall
## 2-21-2020 In Class Problem
Assume the following setup:
```c
TCCR1A = 0b00100011;
TCCR1B = 0b00011011;
OCR1A = 9999;
OCR1B = 2499;
```
1. What mode is the timer in?
Fast PWM (OCR1A top)
2. What is the prescaler?
256
3. What is the period?
6.25s
4. What is the pulse width?
1.5625s
5. What is the duty cycle?
25%
6. On which pin will the output wave appear?
digital pin 10 (SS/OC1B/PCINT2) PB2
7. In Timer1, what is the difference between modes 5, 6, and 7?
Bit depth. Mode 5 has a bit-depth of 8; Mode 6, 9; Mode 7, 10.
8. What is the minimum PWM frequency that can be achieved with Timer0 or Timer2?
$$
\frac{1}{256\times\frac{1024}{16MHz}}=f\\
f\approx61Hz
$$
9. What is the minimum PWM frequency that can be achieved with Timer1?
$$
\frac{1}{2^{16}\times\frac{1024}{16MHz}}=f\\
f\approx238mHz
$$
10. Write the C code to achieve the following:
- [x] Use a PWM wave to control the brightness of an LED connected to pin PD6
- [x] The LED is at 10% brightness at the start of the program.
- [x] There is one pushbutton connected to INT0 and one connected to INT1.
- [x] each time INT0 is pressed, an interrupt increases the brightness of the LED by 10%
- [x] each time INT1 is pressed, an interrupt decreases the brightness of the LED by 10%
- [x] the brightness cannot go below 10% or above 90%
```c
void setup(){
TCCR0A = 0b10000011;
TCCR0B = 0b00000001;
OCR0A = 25;
TCNT0 = 0;
cli();
EICRA = 0;
EIMSK = 3;
sei();
}
void loop(){
while(1);
}
ISR(INT1_vect){
if(OCR0A > 25){
OCR0A -= 25;
}
}
ISR(INT0_vect){
if(OCR0A < 230){
OCR0A += 25;
}
}
```
11. Could you swap out the LED in the previous program and have it work the same (without changing the code)?
From my experience with servos from homework and lab; no, because the servos dont react to a PWM signal in the intended way, and will most likely act extraneously.

Binary file not shown.

View file

@ -0,0 +1,26 @@
void setup(){
TCCR0A = 0b10000011;
TCCR0B = 0b00000001;
OCR0A = 25;
TCNT0 = 0;
cli();
EICRA = 0;
EIMSK = 3;
sei();
}
void loop(){
while(1);
}
ISR(INT1_vect){
if(OCR0A > 25){
OCR0A -= 25;
}
}
ISR(INT0_vect){
if(OCR0A < 230){
OCR0A += 25;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

58
2-February/2-24_Notes.md Normal file
View file

@ -0,0 +1,58 @@
# I^2^C
Inter integrated circuits
- standard serial bus protocol
- enables communication between microprocessor and peripherals
- 2 wires in the interface
- clock
- `SCL ` or `SCLK`
- provided by master
- uni-directional
- data
- `SDA` or `SDAT`
- bi-directional
- inexpensive and simple
Arduino calls it 2-wire serial interface
Broadcasting is possible
Data should only change when `SCLK` is low. Both signals idle high. The master initiates the transfer by pulling `SDAT` low while holding `SCLK` high. To end the transmission the master pulls `SCLK` high.
![](2-24_Notes.assets/dataPacketFormat.png)
Step 1 establishes the location of the device. Step 2 defines where in the memory needs to be written to the device. Step 3 actually writes to the device. (This is for writes only. Reads are the same)
On a write, the peripheral pulls data low every 9th bit. On a read, the master pulls data low on the 9th bit (except on the last one, where it pulls high to disconnect). If you dont disconnect (`NAK`), you can do a register dump, in or out. If youre doing this, its recommended to start in internal address `0`. You can start wherever you like, but you can only increment in register counts.
The master begins by sending start, the peripheral address, and a singular bit to establish data transfer direction (1 to read, 0 to write). The peripheral device whose address matches the address sent by the master will answer with an `ACK`. After the peripheral `ACK`s, data transfer takes place in the direction specified, and it takes 9 cycles for one byte. The master completes communication by sending a `STOP` signal.
To allow for continued communications, there is a repeated start. Send the `SCLK` high, and pull the `SDAT` low.
In order to read, you have to point the address to the correct location, so you start with a write command. After this, you restart, and request a read.
The pins on the board are on the end, past the digital pins, and on the other side, its next to the `GVS` male pins.
To initialize properly, do the following:
```c
DDRC &= 0b11001111;
PORTC |= 0b00110000;
//arduinoCode
pinMode(A4, INPUT_PULLUP);
pinMode(A5, INPUT_PULLUP);
```

111
2-February/2-26_Notes.md Normal file
View file

@ -0,0 +1,111 @@
# I^2^C Bus Speeds
## Standards
Original Standard: 100kHz
Fast Mode: 400kHz
Fast Mode Plus: 1MHz
High-speed mode: 3.4MHz[^1]
Ultra Fast mode: 5MHz [^1]
## Setting bus speed
`TWBR` defines the bit rate for the two wire interface (`TWI`).
$$
SCL= \frac{clock}{16+2(TWBR)\times prescale}\\
assume\ prescale=1\\
TWBR={\frac{16MHz}{bitrate}-16\over2}
$$
# TWI enable
`TWCR` is the `TWI` control register.
==ONLY CHANGE `TWEN` WHEN YOU WANT TO TURN OFF `TWI`==
`TWINT` sets when its finished its current job and expects application software response.
`TWSTA` is the start bit.
`TWSTO` is the stop bit.
`TWDR` (register) contains the data that you wish to send or receive.
# Important Code blocks
```c
void initI2C (unsigned long bit_rate){
TWBR = ((16000000/bit_rate)-16)/2; //TWBR set
TWCR |= 0b00000100;
DDRC &= 0b11001111;
PORTC |= 0b00110000; //initialize pins PC4/PC5 as pullups (clocks idle high)
}
void i2cWaitForComplete(){
while(!(TWCR & 0x80)){} //wait until TWINT is true
}
void i2cStart(){
TWCR = 0b10100100; //clear interrupt, initiate start, enable TWI
i2cWaitForComplete(); //wait to know start is complete
}
void i2cStop(){
TWCR = 0b10010100; //clear interrupt, initiate stop, enable TWI
}
void i2cSend(byte data){
TWDR = data;
TWCR = 0b10000100; //clear interrupt and enable
i2cWaitForComplete(); //wait to know data is sent
}
byte i2cReadAck(){ //multi-read
TWCR = 0b11000100; //clear interrupt, allow ACK, enable TWI
i2cWaitForComplete(); //wait to know data is recieved
return(TWDR); //return recieved data
}
byte i2cReadNoAck(){ //single read (always done eventually)
TWCR = 0b10000100; //clear interrupt, enable TWI
i2cWaitForComplete(); //wait to know data is recieved
return(TWDR); //return recieved data
}
```
## Example code in use
```c
void setup(){
Serial.begin(9600);
initI2C(100000);
}
void loop(){
i2cStart();
i2cSend(MPU6050_address_W);
i2cSend(WHOAMI);
i2cStart();
i2cSend(MPU6050_address_R);
read_data = i2cReadNoAck();
i2cStop();
if(read_data == 0x68)
Serial.println("MPU Successfully connected!");
else
Serial.println("MPU not connected. Check your setup.");
}
```
[^1]:Note that this is not possible on our boards, due to overhead and max clock speed of our chip

83
2-February/2-3_Notes.md Normal file
View file

@ -0,0 +1,83 @@
# Interrupts
Better than polling, because it uses less resources. But building an interrupt structure means we need a priority structure.
Lower value = interrupt faster, with higher priority
reset has the highest priority
## Interrupt steps
- current program halts
- registers stored
- program execution is passed to an Interrupt Routine (ISR)
- each interrupt capable event has an ISR
- When the ISR completes execution
- interrupt is turned off
- registers are restored
- original program picks up where it was
## Programmers job
- Write to the ISR
- its a function, but not explicitly called
- `sei()` for turning on global interrupts
- `cli()` for turning off global interrupts
# Programming Interrupts
3 enables for interrupt;
- overflow interrupt (`TIMSKn0`)
- OCA interrupt (`TIMSKn1`)
- OCB (`TIMSKn2`)
```c
void setup(){
cli();//turn off global interrupts
//set interrupt flag(s) in TIMSKn
sei();//turn on global interrupts again
}
ISR()//vector name (slide 13)
{
//K.I.S.S. Minimize lines
}
void loop(){
}
```
## In class coding
Write a program to use interrupts to toggle an LED connected to PD2 every second
```c
void setup()
{
cli();
TIMSK1 |= 0x02;
TIFR1 |= 0x02;
sei();
DDRD |= 0x04;
TCCR1A = 0x42;
TCCR1B = 0x8C;
OCR1A = 31249;
}
ISR(TIMER1_COMPA_vect)
{
PORTD = PORTD ^ 0x04;
}
```

View file

@ -0,0 +1,25 @@
# In class coding
Write a program to use interrupts to toggle an LED connected to PD2 every second
```c
void setup()
{
cli();
TIMSK1 |= 0x02;// correct
TIFR1 |= 0x02;
sei();
DDRD |= 0x04; // correct
TCCR1A = 0x00; // wrong: 0x42;
TCCR1B = 0x0C; // wrong: 0x8C;
OCR1A = 62499;// wrong. 31249 needs to be doubled
TCNT1 = 0; // also needed
}
ISR(TIMER1_COMPA_vect)
{
PORTD = PORTD ^ 0x04;
//PORTD ^= 0x04; is easier, and is acceptable
}
```

Binary file not shown.

63
3-March/3-2_Notes.md Normal file
View file

@ -0,0 +1,63 @@
# A-D Converters
==Not on the upcoming exam==
==HW7 due in 3 weeks==
==HW8 is individual. Fill out one for each of your group members==
Analog signals are inherently not digital. In electrical systems, analog signals are represented by a voltage that is proportional to its intensity.
Digital signals are discrete. A digital representation is the result of a number of limited precision to a continuously variable quantity.
## Digitizing
periodic sampling to approximate the value
More samples is more better-er
Sampling rate must be at least twice as high as the highest frequency you want to represent.
Bare minimum spec, and you can go higher.
## Hardware
hardware exists to convert analog to digital
it can be a standalone component, and is built into many microcontrollers
Theres different ways that it can be done, but we will focus on *successive Approximation ADC*
ex.
Voltage Range = 0-10
I have a voltage in that range, we successfully divide by two until we find essentially the same number.
Were inputting a 7.65V source.
Were gonna cut it in half, then we compare to the source. If its higher, write a 1, take the divided number, and set as the lower bound. If its lower, write a 0, take the divided number, set as the upper bound.
$$
{(10+0)\over2}=5<7.65;\ 1\\
{(10+5)\over2}=7.5<7.65;\ 1\\
{(10+7.5)\over2}=8.75>7.65;\ 0\\
{(8.75+7.5)\over2}=8.125>7.65;\ 0\\
{(8.125+7.5)\over2}=7.8125>7.65;\ 0\\
{(7.8125+7.5)\over2}=7.65625>7.65;\ 0\\
{(7.65625+7.5)\over2}=7.578125<7.65;\ 1\\
{(7.65625+7.578125)\over2}=7.578125<7.65;\ 1\\
$$
Final result is `11000011`
Bit-depth of the microcontroller creates the resolution.

24
3-March/3-4_Notes.md Normal file
View file

@ -0,0 +1,24 @@
# Exam Review
## PWM
### Timer0/2
Modes 3 and 7 are FastPWM.
Mode 3: 8 bit timer. 2 possible independent triggers, on `OCRxA` and `OCRxB`
Mode 7: reset on `OCRxA`. trigger on `OCRxB`
### Timer1
Mode 5: 8 bit timer. 2 possible independent triggers, on `OCR1A` and `OCR1B`
Mode 6: 9 bit timer. 2 possible independent triggers, on `OCR1A` and `OCR1B`
Mode 7: 10 bit timer. 2 possible independent triggers, on `OCR1A` and `OCR1B`
Mode 14: reset on `ICR1`. 2 possible independent triggers, on `OCR1A` and `OCR1B`
Mode 15: reset on `OCR1A`. Trigger on `OCR1B`

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,32 @@
1. Go to MyCourses and click on Zoom. Join the meeting and say "hi". :white_check_mark:
2. Indicate which of the following quantities are analog and which are digital.
1. ten position switch
analog/==digital==
2. current flowing from an electrical circuit
==analog==/digital
3. Temperature of a room
==analog==/digital
4. sand grains on a beach
analog/==digital==
5. automobile fuel gauge
==analog/digital==[^1]
[^1]:While the gauge that we see is often analog, it can also be digital. Furthermore, there is some level of data lost between the pseudo-analog gauge we see in the drivers seat and the actual measurement in the tank, due to the information being fed through the computer of the car first.
3. The process of converting an analog signal to a digital signal is called digitizing. How can the accuracy of the digital representation of an analog signal be increased?
One way is increasing the sample rate. The other is to make your high and low limits smaller, leaving your more possible datapoints in the middle.
4. The process used by the ADC in the ATMega328 is called *Successive Approximation ADC*
5. Refer to slide 32 and take out a calculator. The formula for resolution is $V_{ref}-V_{min}\over2^n$. Do that calculation on your calculator and don't round off. Now multiply that number by 195. What do you get?
7.605V
Does it look familiar?
Its almost the same as the value we're measuring.
6. Now assume an ADC with a 10-bit resolution and a 5V $V_{ref}$. What is the resolution?
0.0048828125
If the ADC returns `0111000101` what is the voltage value it is reading?
2.2119140625V

Binary file not shown.

View file

@ -0,0 +1,76 @@
There are 3 registers associated with ADC:
# `ADMUX`
1. Set the `ADLAR` bit to left or right justify the results. You would justify if you only need 8 bits of precision and just use the `ADCH` byte. When you right justify, use both the `ADCH` and `ADCL` bytes for 10 bits of precision.
How would the following registers be filled by the ADC hardware when the result of the conversion is `1110001100`?
Left Aligned: `ADLAR=0`
| b~15~ | b~14~ | b~13~ | b~12~ | b~11~ | b~10~ | b~9~ | b~8~ | b~7~ | b~6~ | b~5~ | b~4~ | b~3~ | b~2~ | b~1~ | b~0~ |
| ----- | ----- | ----- | ----- | ----- | ----- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 |
Right Aligned: `ADLAR=1`
| b~15~ | b~14~ | b~13~ | b~12~ | b~11~ | b~10~ | b~9~ | b~8~ | b~7~ | b~6~ | b~5~ | b~4~ | b~3~ | b~2~ | b~1~ | b~0~ |
| ----- | ----- | ----- | ----- | ----- | ----- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2. Set `REFS1` and `REFS0` to set your reference voltage. If you choose `00` for these bits you must connect a voltage source to the `AREF` pin externally.
Write the instruction(s) that initializes the `ADMUX` register so that the reference voltage is `AVCC` (On an Arduino platform, `AVCC` is internally connected to 5V `VCC`)
```c
ADMUX |= 0x40;
```
3. Choose your analog source pin (from port C) and enable it using the `MUX3`-`MUX0` bits.
Write the instruction(s) to select pin PC2 as the analog source pin to the ADC.
```c
ADMUX |= 0x02;
```
# `ADCSRA`
1. Choose a clock divider given the frequency of your system clock. Remember that ADCs work best between 50-200kHz. The Arduino clock frequency is 16MHz but other systems may be different. Prescale is set with `ADPS2`-`ADPS0` bits.
What are the only clock divider options we can use to ensure a frequency between 50-200kHz range on an Arduino platform?
`111` and `110`, or 64 and 128
2. Do you want to trigger an interrupt when the conversion is complete? If so, set the `ADIE` bit. If you trigger an interrupt, you will also need an ISR.
What is the name of the interrupt vector for the ADC interrupt?
`ADC_vect`
3. If you don't use an interrupt, you can poll the `ADIF` bit to know when the conversion is complete. It will go high.
Write the code for a While loop that waits for the `ADIF` bit to go high.
```c
while(ADCSRA & 0x10){}
```
4. Do you want to start the conversion under program control, or upon the occurrence of another event (or free running mode)? Set the `ADATE` bit accordingly- 0 for program controlled conversions, and 1 for free-running mode and event-driven conversions.
If you are initializing the conversion on the occurrence of another event, what other register needs to be initialized in `setup()`?
The interrupt that corresponds with the other event. (i.e. The pin-change interrupt or the timer interrupt.)
5. Turn on the ADC circuitry with the `ADEN` bit.
6. Finally, use the `ADSC` to start the conversions. In free running mode, do this at the end of setup. In program controlled conversions, it gets set in the main loop at the time a conversion is needed.
If you are not in free-running mode, why should you wait to set the `ADSC` bit in `loop()`?
If you don't, then it will only run the conversion once, then stop. Putting it in the loop ensures it runs every instance that you want it to.
# `ADCSRA`
1. If you want free-running mode or an event-triggered interrupt, use the `ADTS2`-`ADTS0` bits to set that.
Write the instructions to initialize the ADC to start a conversion on a `TIMER1` overflow interrupt.
```c
void setup(){
//assumed timer1 setup here
//other ADC setup not established in this question
ADCSRB |= 0x07;
}
```

Binary file not shown.

View file

@ -0,0 +1,56 @@
1. Using the ADC notes and the ATmega328 datasheet, write the code for the following:
- assume an arduino set up with a potentiometer on PC3
- initialize the pin
- in `setup()` function, initialize the ADC by writing to its 3 registers. It should be in free-running mode.
- In `loop()` print the ADC value to the serial terminal each time a conversion completes, you can use polling to determine when the conversion is completed.
```c
void setup()
{
DDRC |= 0x04;
ADMUX = 0x43;
ADCSRA = 0xAD;
ADCSRA |= 0x40;
Serial.begin(9600);
}
void loop()
{
while(1){}
}
ISR(ADC_vect)
{
byte tempVar = ADCL;
Serial.println(tempVar);
}
```
2. Starting from the above code, write a second program that reads the potentiometer every one second (use a timer interrupt as a trigger)
```c
void setup()
{
DDRC |= 0x04;
ADMUX = 0x43;
ADCSRA = 0xAD;
TCCR1A = 0x02;
TCCR1B = 0x1B;
ICR1 = 62499;
Serial.begin(9600);
}
void loop()
{
while(1){}
}
ISR(TIMER1_OVF_vect)
{
ADCSRA |= 0x40;
while(ADCSRA & 0x10){}
byte tempVar = ADCL;
Serial.println(tempVar);
}
```

Binary file not shown.

View file

@ -0,0 +1,45 @@
# Lecture 20 Worksheet
1. BPS stands for Band Pass Filter when referring to carrier frequencies.
==True==/False
2. A preamplifier makes a recieved signal smaller so it is easier to read.
True/==False==
3. Blocking out interfering signals is the main goal of IR modulation
True/==False==
4. Infrared waves are not visible to humans.
==True==/False
1. Which of the following generates/emits IR waves? Highlight all that apply.
1. Picture Frame
2. ==Cats==
3. ==Sun==
4. ==Soldering Iron==
5. Coat Hanger
2. Which directive is used to import a header file into your C code so you may use a library?
1. #define
2. #ifdef
3. ==#include==
4. #library
3. At what frequency are you modulating the transmission from your lab kit IR remote?
38kHz
4. Write a nested if statement required to detect a 1 or a 2 from your lab kit remote. If a 1 is recieved, write a 1 to a variable named `read_data`. If it is a 2, write a 2 to `read_data`. If any other number is recieved, write a 0 to `read_data`.
```c++
#include <IRremote.h>
#define IR_RECV_PIN A3
IRrecv irrecv(IR_RECV_PIN);
decode_results IR_command_recieved;
int read_data;
void setup(){
}
void loop(){
if(irrecv.decode(&IR_command_received)){
if (IR_command_recieved.value == ONE) read_data = 1;
else if (IR_command_recieved.value == TWO) read_data = 2;
else read_data = 0;
}
}
```

Binary file not shown.

View file

@ -0,0 +1,46 @@
1. List reasons why Bluetooth is a popular wireless communication protocol.
Small, low cost, low power, widely implemented.
2. List limitations of Bluetooth.
Prevalence creates interference amongst nets, its on the same frequency as a lot of proprietary communication standards leading to further interference, short communcation range, and slow transfer rate.
3. It is possible to communicate via Bluetooth in an adjacent classroom.
True/==False==[^1]
[^1]: It is possible, but isn't completely true, as the connection may drop out when using the farthest points of the classrooms
4. A Bluetooth Piconet can have up to how many active peripherals?
1. 63
2. 31
3. 15
4. ==7==
5. Bluetooth can support simultaneous connections. The devices don't interfere with each other due to:
1. ==Spread-spectrum frequency hopping==
2. radio shielding in each device
3. dedicated frequencies for each stream of data
4. none of the above
6. Bluetooth devices change frequencies
1. five times per second
2. 100 times per second
3. ==1600 times per second==
4. 3200 times per second
7. You can change the address of a Bluetooth device.
True/==False==
8. Which of the following transfer protocols are supported by Bluetooth
1. ==AVRCP==
2. I2C
3. ==GAVDP==
4. ==RFCOMM==
9. Which transfer protocol is used by the Bluetooth module in our lab kit?
RFCOMM
10. With your Bluetooth devices in ==discover== mode, other bleutooth devices can find and make contact with you.

Binary file not shown.

Binary file not shown.

14
4-April/examSetup.md Normal file
View file

@ -0,0 +1,14 @@
Go to class section on micros, primarily focusing on I2C and new things
Look at exam 3 topics
The exam is in Quizzes at the normal class time
1 hour to complete exam
When you complete exam, the final exam grade may not be the exam grade you get
Same question set as normal
Coding will be read individually. Unknown length on coding. I2C coding and EEPROM coding questions will be able to use the functions given in lecture (i2cstart, eepromwrite)

View file

@ -0,0 +1,9 @@
1. How does EEPROM differ from EPROM?
2. Think of a system with an embedded processor. What data do you think is stored in EEPROM? Remember that the data can be over written, but is saved upon power loss.
3. There are ==8== bits in a byte. As such, when we say that EEPROM is 1kbyte, it indicates that there are ==1000== locations each containing ==8== bits.
4. Why is the EEPROM address register, EEAR 16 bits in length?
5. Why are there 3 different options for erasing and writing? Why would you use one over the other?
6. What triggers the EEPROM interrupt? Why do you need to be careful when enabling the EEPROM interrupt?
7. In the code on slide 18, why are the interrupts turned off then back on again?
8. Write the lines of code necessary to retrieve the data stored in EEPROM location 255, invert it, and store it to location 511. You may call the read and write functions provided in the lecture.

BIN
ATmega328-328P_Datasheet_2016.pdf Executable file

Binary file not shown.

BIN
Homework/TeammateEval1.docx Normal file

Binary file not shown.

BIN
Homework/TeammateEval2.docx Normal file

Binary file not shown.

BIN
Homework/homework2.pdf Normal file

Binary file not shown.

BIN
Homework/homework3.pdf Normal file

Binary file not shown.

BIN
Homework/homework4.pdf Normal file

Binary file not shown.

BIN
Homework/homework5.pdf Normal file

Binary file not shown.

BIN
Homework/homework7.pdf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

120
Homework/hw2.md Normal file
View file

@ -0,0 +1,120 @@
# Skyler MacDougall
## Homework 2: Due 1/29/2020
1. Rewrite Lab 1, page 15, using C and register writes. ArduinoC is allowed for the use of Serial outputs and delays.
```c
//Lab_1_hello_arduino
//#define LED_PIN 13
char inChar;
boolean isFreshInChar;
void setup() {
DDRB |= 0x20; //pinMode(LED_PIN , OUTPUT);
PORTB &= 0xDF; //digitalWrite(LED_PIN , LOW);
// Set serial monitor console termination for 'No line ending'
Serial.begin(9600);
Serial.println("Lab 1: hello arduino v0.3\n");
delay(5000);
}
void loop() {
isFreshInChar = false;
if (Serial.available()) {
inChar = Serial.read();
Serial.print("Serial input detected: ");
Serial.println(inChar);
isFreshInChar = true;
}
if (inChar == 'n') PORTB |= 0x20; //digitalWrite(LED_PIN , HIGH); oN
if (inChar == 'f') PORTB &= 0xDF; //digitalWrite(LED_PIN , LOW); oFf
if (inChar == 'b') { // blink with 25% duty cycle
PORTB |= 0x20; //digitalWrite(LED_PIN , HIGH);
delay(250);
PORTB &= 0xDF; //digitalWrite(LED_PIN , LOW);
delay(750);
}
// Discover 't' persistence bug by observing high rate LED blink
if (inChar == 't') { // toggle
//digitalWrite(LED_PIN , !digitalRead(LED_PIN ));
if (PINB & 0x20){
PORTB &= 0xDF;
}
else{
PORTB |= 0x20;
}
}
// Add state change detection to get proper toggle action.
if (inChar == 'T') { // toggle
if (isFreshInChar){//digitalWrite(LED_PIN , !digitalRead(LED_PIN ));
if (PINB & 0x20){
PORTB &= 0xDF;
}
else{
PORTB |= 0x20;
}
}
}
} // loop()
```
2. Assuming the below, write a program using register reads and writes, read the state of the switches and turn the LEDs on if the switches are closed.
![hw2q2](hw2.assets/hw2q2.png)
```c
void setup(){
DDRB = 0xF0;
PORTB = 0x0F;
}
void loop(){
//LED0
if(PINB & 0x01){
PORTB |= 0x10;
}
else{
PORTB &= 0xEF;
}
//LED1
if(PINB & 0x02){
PORTB |= 0x20;
}
else{
PORTB &= 0xCF;
}
//LED2
if(PINB & 0x04){
PORTB |= 0x40;
}
else{
PORTB &= 0xBF;
}
//LED3
if(PINB & 0x08){
PORTB |= 0x80;
}
else{
PORTB &= 0x7F;
}
}
```
3. Explain the steps necessary when changing the state of a port from input to output, or vice versa.
```c
//The following is a step by step for how to go from in to out.
PORTD = 0x00;
DDRD = 0xFF;
//The following is a step by step for how to go from out to in
DDRD = 0x00;
PORTD = 0xFF;
```
The steps stated above are for full ports. The process is similar for single pin assignment.

BIN
Homework/hw2.pdf Normal file

Binary file not shown.

BIN
Homework/hw2q2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

187
Homework/hw3.md Normal file
View file

@ -0,0 +1,187 @@
3.
![stateMachineLight](hw3.assets/stateMachineLight.jpg)
```c
enum{HGFR, HYFR, HRFR, HRFG, HRFY, HRFRR, HRRFRR};
bool detect = false;
int state = HRFRR, prevState = !state;
float stateTimer = 0;
boolean isNewState;
void setup(){
DDRD |= 0xFC; //setting light pins to output
DDRB &= ~(0x01); //set detect pin to input
PORTB |= 0x01; //turn on detect pin pullup
}
void loop(){
detect = (PINB & 0x01);
isNewState = (state != prevState);
prevState = state;
switch(state){
case HGFR:
if(isNewState){
PORTD &= ~(0x80);
PORTD |= 0x30;
}
if(detect) state = HYFR;
break;
case HYFR:
if(isNewState){
PORTD &= ~(0x20);
PORTD |= 0x40;
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if(stateTimer >= 5000)state = HRFR;
break;
case HRFR:
if(isNewState){
PORTD &= ~(0x40);
PORTD |= 0x80;
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if(stateTimer >= 5000)state = HRFR;
break;
case HRFG:
if(isNewState){
PORTD &= ~(0x10);
PORTD |= 0x04;
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if((stateTimer >= 40000) || !(detect)) state = HRFY;
break;
case HRFY:
if(isNewState){
PORTD &= ~(0x04);
PORTD |= 0x08;
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if(stateTimer >= 5000)state = HRFRR;
break;
case HRFRR:
if(isNewState){
PORTD &= ~(0x08);
PORTD |= 0x10;
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if(stateTimer >= 5000)state = HGFR;
break;
case HRRFRR:
if(isNewState){
PORTD &= ~(0x08);
PORTD |= 0x10;
stateTimer=0;
}
break;
default: state = HRRFRR;
}
delay(1);
}
```
4.
![stateMachineCar](hw3.assets/stateMachineCar.jpg)
```c
enum{fwd, backr, backl, turnr, turnl, stop};
bool rs = false, ls = false;
int state = fwd, prevState = !fwd;
int stateTimer = 0;
#define forward 0xC0
#define rightTurn 0x40
#define leftTurn 0x80
boolean isNewState;
void setup(){
DDRD |= 0xC0; DDRD &= ~(0x03); //setting input/output pins
PORTD |= 0x03; //setting pushbutton pullups
}
void loop(){
rs = !(PIND & 0x02);
ls = !(PIND & 0x01);
isNewState = (state != prevState);
prevState = state;
switch(state){
case fwd:
if(isNewState){
PORTD |= forward;
}
if(rs) state = backr;
else if(ls) state = backl;
break;
case backr:
if(isNewState){
PORTD &= ~(forward);
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if (stateTimer >= 500) state = turnr;
break;
case turnr:
if(isNewState){
PORTD |= rightTurn;
}
if (stateTimer >= 500) state = fwd;
break;
case backl:
if(isNewState){
PORTD &= ~(forward);
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if (stateTimer >= 500) state = turnl;
break;
case turnl:
if(isNewState){
PORTD |= leftTurn;
}
if (stateTimer >= 500) state = fwd;
break;
case stop:
if(isNewState){
PORTD &= ~(forward);
}
break;
default: state = stop;
}
delay(1);
}
```

BIN
Homework/hw3.pdf Normal file

Binary file not shown.

73
Homework/hw3q1/hw3q1.ino Normal file
View file

@ -0,0 +1,73 @@
enum{fwd, backr, backl, turnr, turnl, stop};
bool rs = false, ls = false;
int state = fwd, prevState = !fwd;
int stateTimer = 0;
#define forward 0xC0
#define rightTurn 0x40
#define leftTurn 0x80
boolean isNewState;
void setup(){
DDRD |= 0xC0; DDRD &= ~(0x03); //setting input/output pins
PORTD |= 0x03; //setting pushbutton pullups
}
void loop(){
rs = !(PIND & 0x02);
ls = !(PIND & 0x01);
isNewState = (state != prevState);
prevState = state;
switch(state){
case fwd:
if(isNewState){
PORTD |= forward;
}
if(rs) state = backr;
else if(ls) state = backl;
break;
case backr:
if(isNewState){
PORTD &= ~(forward);
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if (stateTimer >= 500) state = turnr;
break;
case turnr:
if(isNewState){
PORTD |= rightTurn;
}
if (stateTimer >= 500) state = fwd;
break;
case backl:
if(isNewState){
PORTD &= ~(forward);
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if (stateTimer >= 500) state = turnl;
break;
case turnl:
if(isNewState){
PORTD |= leftTurn;
}
if (stateTimer >= 500) state = fwd;
break;
case stop:
if(isNewState){
PORTD &= ~(forward);
}
break;
default: state = stop;
}
delay(1);
}

96
Homework/hw3q2/hw3q2.ino Normal file
View file

@ -0,0 +1,96 @@
enum{HGFR, HYFR, HRFR, HRFG, HRFY, HRFRR, HRRFRR};
bool detect = false;
int state = HRFRR, prevState = !state;
float stateTimer = 0;
boolean isNewState;
void setup(){
DDRD |= 0xFC; //setting light pins to output
DDRB &= ~(0x01); //set detect pin to input
PORTB |= 0x01; //turn on detect pin pullup
}
void loop(){
detect = (PINB & 0x01);
isNewState = (state != prevState);
prevState = state;
switch(state){
case HGFR:
if(isNewState){
PORTD &= ~(0x80);
PORTD |= 0x30;
}
if(detect) state = HYFR;
break;
case HYFR:
if(isNewState){
PORTD &= ~(0x20);
PORTD |= 0x40;
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if(stateTimer >= 5000)state = HRFR;
break;
case HRFR:
if(isNewState){
PORTD &= ~(0x40);
PORTD |= 0x80;
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if(stateTimer >= 5000)state = HRFR;
break;
case HRFG:
if(isNewState){
PORTD &= ~(0x10);
PORTD |= 0x04;
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if((stateTimer >= 40000) || !(detect)) state = HRFY;
break;
case HRFY:
if(isNewState){
PORTD &= ~(0x04);
PORTD |= 0x08;
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if(stateTimer >= 5000)state = HRFRR;
break;
case HRFRR:
if(isNewState){
PORTD &= ~(0x08);
PORTD |= 0x10;
stateTimer=0;
}
if(!(isNewState)){
stateTimer++;
}
if(stateTimer >= 5000)state = HGFR;
break;
case HRRFRR:
if(isNewState){
PORTD &= ~(0x08);
PORTD |= 0x10;
stateTimer=0;
}
break;
default: state = HRRFRR;
}
delay(1);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

263
Homework/hw4.md Normal file
View file

@ -0,0 +1,263 @@
# Skyler MacDougall, Matthew Gerace
# Homework 4: Due 2/12/2020
1. There are 25 notes of the musical scale. They are each produced by a square wave with the frequency as defined by the following formula:
$$
f_{note}=440\times 2^{P\over12}\\
-12\le P\le 12
$$
The period of the square wave is as follows:
$$
T_{note}={1\over f_{note}}\\
hint:\ (OCR1A+1)={T_{note}\over 2}={16MHz\over2\times f_{note}}
$$
1. For the 25 notes where $220\le f_{note}\le 880$, determine the `OCR1A` values needed to output the square wave of each note using Timer1 in CTC mode.
2. Open another program and use `#define` to create 25 constants for the results of part 1. Also create time delay constants.
3. In the initialization section setup Timer1 to create a square wave.
4. Create a function called `playNote()`.
1. It takes in an integer representing the max count for a given note and assigns that value to the `OCR1A` register.
2. It also takes in a delay constant to hold the note for a given amount of time.
3. it must then turn off CTC mode and `delay(50)` to put a break between notes.
5. In the main loop call the function with different notes and delays in between. You can look up simple songs on the internet and experiment with delays to actually play a song.
6. Use the speaker in your lab kit and drive one pin with the waveform output and the other to ground.
![music](hw4.assets/music.jpg)
```c
//Note-name/constant conversion
#define LA 36363
#define LAS 34323
#define LB 32396
#define LC 30578
#define LCS 28861
#define LD 27242
#define LDS 25713
#define LE 24270
#define LF 22908
#define LFS 21622
#define LG 20408
#define LGS 19263
#define MA 18182
#define MAS 17161
#define MB 16198
#define MC 15289
#define MCS 14430
#define MD 13620
#define MDS 12856
#define ME 12135
#define MF 11454
#define MFS 10811
#define MG 10204
#define MGS 9631
#define HA 9091
//Note Length definitions
#define QUARTER 400
#define EIGHTH 200
#define DOTQUARTER 600
#define HALF 800
void setup(){
TCCR1A=0x40;
TCCR1B=0x09;
TCCR1C=0;
TCNT1=0;
DDRB|=0x02;
}
void playNote(int note, int time){
OCR1A = note;
delay(time);
OCR1A = 0;
delay(50);
}
void loop(){
playNote(LD, EIGHTH);
playNote(LD, EIGHTH);
playNote(LG, QUARTER);
playNote(LG, EIGHTH);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(LG, EIGHTH);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MD, QUARTER);
playNote(MD, EIGHTH);
playNote(MC, EIGHTH);
playNote(MB, QUARTER);
playNote(MA, EIGHTH);
playNote(LG, EIGHTH);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, EIGHTH);
playNote(LFS, EIGHTH);
playNote(LD, QUARTER);
playNote(LD, QUARTER);
playNote(LG, EIGHTH);
playNote(LFS, EIGHTH);
playNote(LG, EIGHTH);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MA, EIGHTH);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MC, QUARTER);
playNote(MD, DOTQUARTER);
playNote(MD, EIGHTH);
playNote(MA, QUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, QUARTER);
playNote(LG, EIGHTH);
playNote(LG, EIGHTH);
playNote(MA, QUARTER);
playNote(LG, EIGHTH);
playNote(LFS, EIGHTH);
playNote(LG, HALF);
playNote(MD, HALF);
playNote(MB, DOTQUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, EIGHTH);
playNote(LG, DOTQUARTER);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MD, QUARTER);
playNote(MB, QUARTER);
playNote(MA, QUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, DOTQUARTER);
playNote(LD, EIGHTH);
playNote(LG, HALF);
playNote(LG, DOTQUARTER);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MD, QUARTER);
playNote(MC, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MB, QUARTER);
playNote(MB, EIGHTH);
playNote(MA, EIGHTH);
playNote(LG, QUARTER);
playNote(LG, QUARTER);
playNote(LG, HALF);
delay(1000);
}
```
2. Use Timer1 in normal mode to create an output wave that has the following properties:
$$
f=1Hz\\
duty\ cycle=25\%
$$
Assume that this output is driving an LED that will cause it to blink. You can use a 2-state state machine.
(Hint: Use `TOV1` as the exit condition for the states. you will need a prescaler.)
***DO NOT USE PWM.***
```c
#define OVERFLAG 0x02
#define OVERFLOW 0x01
#define LEDHIGH 0x02
#define LEDLOW 0xFD
enum{LED_on, LED_off, stop};
int state = LED_on, prevState = !LED_on;
int stateTimer = 0;
boolean isNewState;
void setup(){
TCCR1A = 0x80;
TCCR1B = 0x04;
TCCR1C = 0;
TCNT1 = 65536 - 23437;
OCR1A = 24520;
DDRB |= 0x02;
PORTB &= ~(0x02);
}
void loop(){
isNewState = (state != prevState);
prevState = state;
switch(state){
case LED_on:
if(isNewState)
{
PORTB |= LEDHIGH;
TIFR |= OVERFLOW;//Flag reset
}
if(TIFR & OVERFLAG) state = LED_off;
break;
case LED_off:
if(isNewState)
{
PORTB &= LEDLOW;
TIFR |= OVERFLAG; //Flag reset
}
if(TIFR & OVERFLOW) state = LED_on;
break;
case stop:
PORTB |= 0x02;
break;
default: state = stop;
}
}
```
3. For each group member, discuss the feasibility of the invention. Is it feasible? Why or why not? List the I/O devices that each invention would require.
1. Skyler MacDougall
one-way switch
- 2 servos
- 3 pins each
- 1 servo to move the arm
- 1 servo to adjust the y-axis to flip the switch
- 1 switch
- 1 pin
2. Matthew Gerace
Pool measurement device
Screen for temp and pH readout
I/O devices:
- pH sensor
- 2 pins
- thermocouple
- 2 pins
- switch
- 1 pin
- for changing between pH and temp
- 2 7seg displays
- 7 pins per display

BIN
Homework/hw4.pdf Normal file

Binary file not shown.

133
Homework/hw4q1/hw4q1.ino Normal file
View file

@ -0,0 +1,133 @@
//Note-name/constant conversion
#define LA 36363
#define LAS 34323
#define LB 32396
#define LC 30578
#define LCS 28861
#define LD 27242
#define LDS 25713
#define LE 24270
#define LF 22908
#define LFS 21622
#define LG 20408
#define LGS 19263
#define MA 18182
#define MAS 17161
#define MB 16198
#define MC 15289
#define MCS 14430
#define MD 13620
#define MDS 12856
#define ME 12135
#define MF 11454
#define MFS 10811
#define MG 10204
#define MGS 9631
#define HA 9091
//Note Length definitions
#define QUARTER 400
#define EIGHTH 200
#define DOTQUARTER 600
#define HALF 800
void setup(){
TCCR1A=0x40;
TCCR1B=0x09;
TCCR1C=0;
TCNT1=0;
DDRB|=0x02;
}
void playNote(int note, int time){
OCR1A = note;
delay(time);
OCR1A = 0;
delay(50);
}
void loop(){
playNote(LD, EIGHTH);
playNote(LD, EIGHTH);
playNote(LG, QUARTER);
playNote(LG, EIGHTH);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(LG, EIGHTH);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MD, QUARTER);
playNote(MD, EIGHTH);
playNote(MC, EIGHTH);
playNote(MB, QUARTER);
playNote(MA, EIGHTH);
playNote(LG, EIGHTH);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, EIGHTH);
playNote(LFS, EIGHTH);
playNote(LD, QUARTER);
playNote(LD, QUARTER);
playNote(LG, EIGHTH);
playNote(LFS, EIGHTH);
playNote(LG, EIGHTH);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MA, EIGHTH);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MC, QUARTER);
playNote(MD, DOTQUARTER);
playNote(MD, EIGHTH);
playNote(MA, QUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, QUARTER);
playNote(LG, EIGHTH);
playNote(LG, EIGHTH);
playNote(MA, QUARTER);
playNote(LG, EIGHTH);
playNote(LFS, EIGHTH);
playNote(LG, HALF);
playNote(MD, HALF);
playNote(MB, DOTQUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, EIGHTH);
playNote(LG, DOTQUARTER);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MD, QUARTER);
playNote(MB, QUARTER);
playNote(MA, QUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, DOTQUARTER);
playNote(LD, EIGHTH);
playNote(LG, HALF);
playNote(LG, DOTQUARTER);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MD, QUARTER);
playNote(MC, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MB, QUARTER);
playNote(MB, EIGHTH);
playNote(MA, EIGHTH);
playNote(LG, QUARTER);
playNote(LG, QUARTER);
playNote(LG, HALF);
delay(1000);
}

313
Homework/hw5.md Normal file
View file

@ -0,0 +1,313 @@
# Skyler MacDougall, Matthew Gerace, Kaitlin Berryman
# Homework 5: Due 2/19/2020
1. Create a reaction timer.
- After a random amount of time, the yellow LED turns on, the timer starts.
- If the user presses the button before the timer times out, the green LED goes on, and the yellow turns off.
- If the timer times out, the red LED goes on, and the yellow goes off.
- Use `delay();` and `random();` for the delay before the yellow light.
- check for the button push in the main program loop and use the timer interrupt to know that time is up
- start with setting the timer to 1/2 second and shorten it from there.
- be sure to disable the interrupt as soon as the user presses the button.
```c
// Homework 5, Problem 1
// digital pins D5, D6, D7, D8
void setup()
{
DDRD |= 0x20; // make PD5 an output -- green
DDRD |= 0x40; // make PD6 an output -- yellow
DDRD |= 0x80; // make PD7 an output -- red
DDRB |= 0x01; // make PB0 an input -- switch
PORTD &= 0xDF; // turn PD5 output off
PORTD &= 0xBF; // turn PD6 output off
PORTD &= 0x7F; // turn PD7 output off
// CTC mode timer setups
TCCR1A = 0;
TCCR1B = 0x0C;
TCNT1 = 0;
OCR1B = 31249;
cli(); // turn off global interrupts
// set the intertupt flag
TIMSK1 = 0x04;
sei(); // turn on global interrupts
}
void loop()
{
// wait a random amount of time
delay(random());
// turn the yellow LED on
PORTD |= 0x40;
//reset the timer
TCNT1 = 0;
while(PIND & 0x40)
{
if (!(PINB & 0x01))
{
PORTD &= ~(0x40);
PORTD |= 0x10;
}
}
//spaced resets a set amount of time
delay(100);
}
ISR(TIMER1_COMPB_vect)
{
// code for servicing the interrupt
PORTD &= ~(0x40); // turn yellow LED off
PORTD |= 0x80; // turn red LED on
}
```
2. Rewrite lab #3 section 6 using registers and timer interrupts. Note that when interrupts are used for timers, you dont have to implement a state timer. Remember that when a variable is updated outside the main loop you must use the volatile design so that the compile does not optimize the variable out.
```c
volatile bool greenFirstRun=0, loopBack=0, redFirstRun=0, grFirstRun=0;
#define MSEC_SAMPLE 1
#define SW1_PIN 5
//#define LED1_PIN 8
//#define LED2_PIN 11
#define LED_CLOCK_PIN 11
#define LED_DATA_PIN 12
#define QTR_SIG_PIN A3
#define QTR_5V_PIN A4
#define QTR_GND_PIN A5
#define MSEC_SAMPLE 1
enum {LED_OFF, BLINK_G_OFF, BLINK_R, BLINK_G_ON, BLINK_GR, BLINK_RATE};
boolean isSwPressed, prevIsSwPressed, isSwJustReleased, isSwJustPressed, isSwChange;
volatile int state = LED_OFF;
int prevState = !state;
int stateTimer, adcQTR;
boolean isNewState;
boolean greentimer = true;
void setup() {
DDRD &= ~(1 << 5); PORTD |= (1 << 5); //pinMode(SW1_PIN, INPUT_PULLUP);
DDRB |= (1 << 3);//pinMode(LED_CLOCK_PIN, OUTPUT);
PORTB &= ~(1 << 3);//digitalWrite(LED_CLOCK_PIN, LOW);
DDRB |= (1 << 4); //pinMode(LED_DATA_PIN, OUTPUT);
PORTB &= ~(1 << 4);//digitalWrite(LED_DATA_PIN, LOW);
pinMode(QTR_SIG_PIN, INPUT);
DDRC |= (1 << 4);//pinMode(QTR_5V_PIN, OUTPUT);
PORTC |= (1 << 4);//digitalWrite(QTR_5V_PIN, HIGH);
DDRC |= (1 << 5);//pinMode(QTR_GND_PIN, OUTPUT);
PORTC &= ~(1 << 5);//digitalWrite(QTR_GND_PIN, LOW);
OCR1A = 15624;
OCR1B = 31249;
ICR1 = 0xFFFF;
Serial.begin(9600);
Serial.println(F("Lab 2 Complex State Machine"));
} // setup()
//****************************************************************************
void display_color_on_RGB_led(unsigned long color) {
unsigned long bitmask=0UL; // UL unsigned long literal (forces compiler to use long data type)
unsigned long masked_color_result=0UL;
// digitalWrite(LED_CLOCK_PIN,LOW); //start with clock low.
PORTB&=0b11110111;
for(int i=23; i>=0; i--) { // clock out one data bit at a time, starting with the MSB first
bitmask= (1UL<<i); // build bit mask. Note must use "1UL" unsigned long literal, not "1"
masked_color_result = color & bitmask; // reveals just one bit of color at time
boolean data_bit=!(masked_color_result==0); // this is the bit of data to be clocked out.
// digitalWrite(LED_DATA_PIN,data_bit);
if( data_bit ==1)
PORTB|=0b00010000;
else
PORTB&=0b11101111;
// digitalWrite(LED_CLOCK_PIN,HIGH);
PORTB|=0b00001000;
// digitalWrite(LED_CLOCK_PIN,LOW);
PORTB&=0b11110111;
}
// digitalWrite(LED_CLOCK_PIN,HIGH);
PORTB|=0b00001000;
delay(1); // after writing data to LED driver, must hold clock line
// high for 1 ms to latch color data in led shift register.
}
void redOn(void) {
PORTB = PORTB |(1 << 0); // sets Uno dig_8, PORTB.0, pin to 1 (HIGH)
display_color_on_RGB_led(0xFF0000); // physical pin 14 (28 pin DIP)
}
//****************************************************************************
void greenOn(void) {
display_color_on_RGB_led(0x0000FF);
if (greentimer == true){
unsigned long start_time_microseconds,end_time_microseconds;
start_time_microseconds=micros();
end_time_microseconds=micros();
Serial.print("Displaying the green color took ");
Serial.print(end_time_microseconds-start_time_microseconds);
Serial.println(" microseconds ");
}
}
//****************************************************************************
void allOff(void) {
display_color_on_RGB_led(0x000000);
}
ISR(TIMER1_COMPA_vect){
if(greenFirstRun){
allOff();
greenFirstRun = !greenFirstRun;
}
if(redFirstRun){
allOff();
redFirstRun = !redFirstRun;
}
if(grFirstRun){
redOn();
grFirstRun = !grFirstRun;
}
}
ISR(TIMER1_COMPB_vect){
loopBack=true;
}
void loop() {
prevIsSwPressed = isSwPressed;
isSwPressed = !(PINC & 0x20);
isSwJustPressed = (isSwPressed && !prevIsSwPressed);
isSwJustReleased = (!isSwPressed && prevIsSwPressed);
isSwChange = (isSwJustReleased || isSwJustPressed);
isNewState = (state != prevState);
prevState = state;
switch (state) {
case LED_OFF:
if (isNewState) Serial.println("LED_OFF");
allOff();
if (isSwJustReleased)
state = BLINK_G_ON;
break;
case BLINK_G_ON:
if (isNewState) {
Serial.println("BLINK_G_ON");
greenFirstRun = true;
grFirstRun = false;
OCR1A = 15624;
OCR1B = 62499;
TIMSK1 = 0x06;//Use OCR1A and OCR1B
sei();
greenOn();
}
if (loopBack){
greenOn();
TCNT1 = 0;
loopBack = 0;
greenFirstRun = true;
}
greentimer = false;
if (isSwJustReleased) {
cli();
allOff();
state = BLINK_R;
}
break;
case BLINK_R:
if (isNewState) {
TCNT1 = 0;
greenFirstRun = false;
redFirstRun = true;
sei();
redOn();
Serial.println("BLINK_R");
}
if (loopBack){
redOn();
TCNT1 = 0;
loopBack = false;
redFirstRun = true;
}
if (isSwJustReleased) {
allOff();
cli();
state = BLINK_GR;
}
break;
case BLINK_GR:
if (isNewState) {
stateTimer = 0;
TCNT1 = 0;
OCR1A = 15624*2;
grFirstRun = true;
redFirstRun = false;
sei();
Serial.println("BLINK_GR");
}
if (loopBack){
greenOn();
TCNT1 = 0;
loopBack = false;
grFirstRun = true;
}
if (isSwJustReleased) {
allOff();
state = LED_OFF;
}
break;
default: state = LED_OFF;
} // switch (state)
} // loop()
```
3. Servos should react to a PWM signal as shown in the homework diagram. however, a pulse width of 1ms does not always put the servo at $0^\circ$ and a pulse width of 2ms does not always put the servo at $180^\circ$. Using timer1 and a FAST PWM mode create a PWM signal to drive a servo motor. You may need to adjust the registers for pulse width to get a full $180^\circ$ of rotation. Note, you cannot just copy the code from lab 4 as that was not fast PWM mode.
```c
unsigned long servoValue=0;
//***********************************************************************************
void setup()
{
pinMode(9,OUTPUT);
Serial.begin(9600);
TCCR1A=0xB2;
TCCR1B=0x1B;
ICR1=0x1387;
}
//***********************************************************************************
void loop()
{ delay(100);
servoValue++;
OCR1A=144+servoValue;
if (servoValue>=470) servoValue=0;
}
```
4. Read sections “Reset and Interrupt Handling” in the datasheet and answer the following questions:
1. How does microcontroller handle multiple interrupts arriving from different peripherals while an ISR is being serviced?
All interrupts are disabled while an ISR is being serviced.
2. What does microcontroller do in the 4 cycle response time to service an ISR?
To enter the ISR, the program counter is pushed onto the Stack during the first cycle. The next three cycles are to jump to the correct spot in memory where the interrupt routine is stored. When exiting the ISR, the program counter is popped back from the stack (two cycles), incremented twice (one cycle), and interrupts are re-enabled.

BIN
Homework/hw5.pdf Normal file

Binary file not shown.

304
Homework/hw6.md Normal file
View file

@ -0,0 +1,304 @@
# Skyler MacDougall, Matthew Gerace
# Homework 6: Due 2/26/2020
1. Rewrite the reaction timer game program using only interrupts.
- A pin change interrupt on PD7 is used to start the game. When the active-low button is pressed, the yellow LED turns on after a random delay. When the LED turns on, `TCNT1=0`.
- `INT0` is attached to another active-low button. This is for the reaction button. if the button is pressed before a $1\over2$ second has elapsed, the green LED should light.
- A Timer1 interrupt should be used to count to $1\over2$ second. If $1\over2$ second passes before `INT0`, the red LED should be lit.
- [x] Which pins will the 3 LEDs be connected to?
Green = `PC0`. Yellow = `PC1`. Red = `PC2`.
- [x] Initialize the pins for the LEDs.
See line 8
- [x] Initialize the two interrupt pins as inputs.
See line 5
- [x] What mode should Timer1 be in to create a $1\over2$ second interrupt?
CTC, although PWM is also possible.
- [x] Initialize for `TCCR1A` and `TCCR1B` for the correct mode.
See lines 11 and 12.
- [x] Is a clock prescaler needed for $1\over2$ second interrupt?
Yes.
- [x] If so, set it up in `TCCR1B`.
See line 12.
- [x] What value goes in `OCR1A` for $1\over2$ second?
See line 14.
- [x] Enable the Timer1 interrupt.
See line 18.
- [x] Enable the pin change interrupt in the control register.
See line 19.
- [x] Enable the external interrupt in the control register.
See line 21.
- [x] Set the correct pin for the pin change interrupt in `PCMSK`
See line 20.
- [x] Set the correct pin for the external interrupt in the `EIMSK`
See line 22.
- [x] What are the names of the 3 interrupt vectors?
`PCINT2_vect`, `INT0_vect`, and `TIMER1_COMPA_vect`.
```c
// Homework 6, Problem 1
void setup()
{
DDRD &= ~(0x82); // make PD6 and PD7 inputs -- reaction switch and start switch
DDRC |= (1 << 0|1 << 1|1 << 2);//PC0, PC1, and PC2 outputs -- green, yellow, and red light
PORTC &= ~(1 << 0|1 << 1|1 << 2); //start all lights off
// CTC mode timer setups
TCCR1A = 0;
TCCR1B = 0x0C;
TCNT1 = 0;
OCR1A = 31249;
cli(); // turn off global interrupts
// set the intertupt flag
TIMSK1 = 4;
PCICR = 4;
PCMSK2 = 0x80;
EIMSK = 1;
EICRA = 3;
sei(); // turn on global interrupts
}
void loop(){while(1)}
ISR(PCINT2_vect){
// wait a random amount of time
delay(random());
// turn the yellow LED on
PORTC |= 0x02;
//reset the timer
TCNT1 = 0;
}
ISR(INT0_vect){
PORTC &= ~(0x02); // turn yellow LED off
PORTC |= 0x01; // turn red LED on
}
ISR(TIMER1_COMPA_vect)
{
// code for servicing the interrupt
PORTC &= ~(0x02); // turn yellow LED off
PORTC |= 0x04; // turn red LED on
}
```
2. In the previous homework, you determined the constants that control your servo motor to rotate $180^\circ$. Starting from that point, complete the following:
1. Once youve determined the constants that will move the servo a full $180^\circ$, modify your program to create a windshield wiper controller. As you know, a windshield wiper moves smoothly across $180^\circ$. It doesnt “snap” back to position like the servo did in lab 4. You can achieve a smooth motion by incrementally increasing and decreasing your pulsewidth.
2. The last step is to add a pushbutton interrupt to start the windshield wiper. You can choose either a pin change or an external interrupt as a source.
3. Submit a video of your working system (or bring it to me for a demonstration).
```c
unsigned long servoValue=0, prevValue=0;
void setup()
{
pinMode(9,OUTPUT);
Serial.begin(9600);
TCCR1A=0xB2;
TCCR1B=0x1B;
ICR1=0x1387;
}
void loop()
{
delay(10);
prevValue = servoValue;
while ((servoValue>=525) || (prevValue > servoValue))
{
if (servoValue > 0){
servoValue--;
OCR1A=144+servoValue;
Serial.println(OCR1A);
delay(10);
}
else{break;}
}
if (prevValue == servoValue) {servoValue++;}
OCR1A=144+servoValue;
Serial.println(OCR1A);
}
```
[link to video](https://drive.google.com/file/d/1-DiePSXHLN-g091YAH-m3jBtCqhLYHJB/view?usp=drivesdk)
3. Rewrite Q1 of HW#4, using PWM mode instead of CTC mode.
Because the code is quite lengthy, code modifications can be seen in lines 35, 36, and 44.
```c
//Note-name/constant conversion
#define LA 36363
#define LAS 34323
#define LB 32396
#define LC 30578
#define LCS 28861
#define LD 27242
#define LDS 25713
#define LE 24270
#define LF 22908
#define LFS 21622
#define LG 20408
#define LGS 19263
#define MA 18182
#define MAS 17161
#define MB 16198
#define MC 15289
#define MCS 14430
#define MD 13620
#define MDS 12856
#define ME 12135
#define MF 11454
#define MFS 10811
#define MG 10204
#define MGS 9631
#define HA 9091
//Note Length definitions
#define QUARTER 400
#define EIGHTH 200
#define DOTQUARTER 600
#define HALF 800
void setup(){
TCCR1A=0b10100011;
TCCR1B=0b00011001;
TCCR1C=0;
TCNT1=0;
DDRB|=0x02;
}
void playNote(int note, int time){
OCR1A = note;
OCR1B = note / 2;
delay(time);
OCR1A = 0;
delay(50);
}
void loop(){
playNote(LD, EIGHTH);
playNote(LD, EIGHTH);
playNote(LG, QUARTER);
playNote(LG, EIGHTH);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(LG, EIGHTH);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MD, QUARTER);
playNote(MD, EIGHTH);
playNote(MC, EIGHTH);
playNote(MB, QUARTER);
playNote(MA, EIGHTH);
playNote(LG, EIGHTH);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, EIGHTH);
playNote(LFS, EIGHTH);
playNote(LD, QUARTER);
playNote(LD, QUARTER);
playNote(LG, EIGHTH);
playNote(LFS, EIGHTH);
playNote(LG, EIGHTH);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MA, EIGHTH);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MC, QUARTER);
playNote(MD, DOTQUARTER);
playNote(MD, EIGHTH);
playNote(MA, QUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, QUARTER);
playNote(LG, EIGHTH);
playNote(LG, EIGHTH);
playNote(MA, QUARTER);
playNote(LG, EIGHTH);
playNote(LFS, EIGHTH);
playNote(LG, HALF);
playNote(MD, HALF);
playNote(MB, DOTQUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, EIGHTH);
playNote(LG, DOTQUARTER);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MD, QUARTER);
playNote(MB, QUARTER);
playNote(MA, QUARTER);
playNote(MA, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, DOTQUARTER);
playNote(LD, EIGHTH);
playNote(LG, HALF);
playNote(LG, DOTQUARTER);
playNote(MA, EIGHTH);
playNote(MB, QUARTER);
playNote(MB, EIGHTH);
playNote(MC, EIGHTH);
playNote(MD, QUARTER);
playNote(MC, EIGHTH);
playNote(MB, EIGHTH);
playNote(MA, QUARTER);
playNote(MA, QUARTER);
playNote(MB, QUARTER);
playNote(MB, EIGHTH);
playNote(MA, EIGHTH);
playNote(LG, QUARTER);
playNote(LG, QUARTER);
playNote(LG, HALF);
delay(1000);
}
```

BIN
Homework/hw6.pdf Normal file

Binary file not shown.

BIN
Homework/hw7.docx Normal file

Binary file not shown.

168
Homework/hw7.md Normal file
View file

@ -0,0 +1,168 @@
1. Control the movement of a servo motor using the gyroscope from lab. Use the library functions for the MPU6050 used in lab. The servo should be controlled with timer 1, starting at 0 degrees (pulsewidth $1.5\mu s$), and have a range of motion of $\pm90^\circ$
```c++
#include <Wire.h>
#include <MPU6050.h>
#define SERVOrotate 500
#define SERVO 375
#define degree 5
MPU6050 mpu; // declare a variable called mpu of datatype MPU6050
unsigned long timeStampStartOfLoopMs = 0;
float timeStepS = 0.01;
float yaw = 0.0f; // pitch, roll and yaw values
unsigned long posistion = 0;
Vector normalizedGyroDPS; //stores the three gyroscope readings XYZ in degrees per second (DPS)
volatile bool newDataFlag=false; // boolean flag to indicate that timer1 overflow has occurred
unsigned long startMicroseconds,elapsedMicroseconds; // use for profiling time for certain tasks
//==============================================================================
void setup()
{
Serial.begin(115200);
cli();
TCCR1A = 0b00100010; //Mode 14 fast PWM, 256 scalar
TCCR1B = 0b00011101;
TIMSK1 |= 0b00000100; //enable timer 1 overflow interrupt
ICR1 = 4999;
OCR1A = SERVO;
sei();
while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
{
Serial.println("Could not find a valid MPU6050 sensor, check wiring.");
delay(1000);
}
mpu.calibrateGyro();
mpu.setThreshold(1);
}
//==============================================================================
void loop()
{
normalizedGyroDPS = mpu.readNormalizeGyro();
yaw = yaw + normalizedGyroDPS.ZAxis * timeStepS;
Serial.println(yaw);
posistion = (SERVOrotate - SERVO) * yaw / degree;
OCR1A = SERVO + servoValue;
}
//==============================================================================
```
2. Write the instructions necessary to initialize the microcontroller for I^2^C fast mode to write `0xF0` to the `0xAA` register in the peripheral address `0b1001101`.
```c++
void initI2C (unsigned long bit_rate){
TWBR = ((16000000/bit_rate)-16)/2; //TWBR set
TWCR |= 0b00000100;
DDRC &= 0b11001111;
PORTC |= 0b00110000; //initialize pins PC4/PC5 as pullups (clocks idle high)
}
void i2cWaitForComplete(){
while(!(TWCR & 0x80)){} //wait until TWINT is true
}
void i2cStart(){
TWCR = 0b10100100; //clear interrupt, initiate start, enable TWI
i2cWaitForComplete(); //wait to know start is complete
}
void i2cStop(){
TWCR = 0b10010100; //clear interrupt, initiate stop, enable TWI
}
void i2cSend(byte data){
TWDR = data;
TWCR = 0b10000100; //clear interrupt and enable
i2cWaitForComplete(); //wait to know data is sent
}
void setup(){
Serial.begin(9600);
initI2C(400000);
}
void loop(){
i2cStart();
i2cSend(0b10011010);
i2cSend(0xAA);
i2cSend(0xF0);
i2cStop();
}
```
3. Write the instructions necessary to initialize the microcontroller for I^2^C standard mode to read 4 bytes of data from register `0x0F` in a peripheral at address `0b1001101`. Each byte of data read should be stored in a different variable.
```c++
byte read_data0, read_data1, read_data2, read_data3;
void initI2C (unsigned long bit_rate){
TWBR = ((16000000/bit_rate)-16)/2; //TWBR set
TWCR |= 0b00000100;
DDRC &= 0b11001111;
PORTC |= 0b00110000; //initialize pins PC4/PC5 as pullups (clocks idle high)
}
void i2cWaitForComplete(){
while(!(TWCR & 0x80)){} //wait until TWINT is true
}
void i2cStart(){
TWCR = 0b10100100; //clear interrupt, initiate start, enable TWI
i2cWaitForComplete(); //wait to know start is complete
}
void i2cStop(){
TWCR = 0b10010100; //clear interrupt, initiate stop, enable TWI
}
void i2cSend(byte data){
TWDR = data;
TWCR = 0b10000100; //clear interrupt and enable
i2cWaitForComplete(); //wait to know data is sent
}
byte i2cReadAck(){ //multi-read
TWCR = 0b11000100; //clear interrupt, allow ACK, enable TWI
i2cWaitForComplete(); //wait to know data is recieved
return(TWDR); //return recieved data
}
byte i2cReadNoAck(){ //single read (always done eventually)
TWCR = 0b10000100; //clear interrupt, enable TWI
i2cWaitForComplete(); //wait to know data is recieved
return(TWDR); //return recieved data
}
void setup(){
Serial.begin(9600);
initI2C(100000);
}
void loop(){
i2cStart();
i2cSend(0b10011010);
i2cSend(0x0F);
i2cStart();
i2cSend(0b10011011);
read_data0 = i2cReadAck();
read_data1 = i2cReadAck();
read_data2 = i2cReadAck();
read_data3 = i2cReadNoAck();
i2cStop();
}
```

BIN
Homework/hw9.docx Normal file

Binary file not shown.

82
Homework/hw9.md Normal file
View file

@ -0,0 +1,82 @@
1. Write a program to quantize the analog input from a $10k\Omega$ potentiometer fed to channel ADC02, and create a light dimmer that dims and brightens an LED using a PWM signal. Consider the following setup:
1. A $10k\Omega$ potentiometer is connected to analog input channel 2 (`ADC02`)
2. The potentiometer is connected to +5V and GND, via suitable resistors.
3. Utilize the on-board LED (on the Arduino) to create a dimmer routine.
The potentiometer should be connecteed to an analog input pin. It will put a voltage between 0 and 5 volts on the input pin. This voltage will be converted in the ADC to a digital number between 0 and 1023 acording to the following formula:
$$
ADC_{digital}={V_{in}*1023\over V_{ref}}
$$
A lights brightness is can be controlled by a PWM signal. The higher the duty cycle, the brighter the light. The mappings of input voltage, ADC and duty cycle is shown below:
| Duty Cycle | 0% | 25% | 50% | 75% | 100% |
| ---------- | ---- | ----- | ---- | ----- | ---- |
| $V_{in}$ | 0V | 1.25V | 2.5V | 3.75V | 5V |
| ADC | 0 | 255 | 511 | 767 | 1023 |
Since the mapping is linear, you can set up the equation of a line and determine the pulsewidth for the PWM signal for any ADC value between 0-1023.
Your program should use the free-running mode of the ADC to continuously sample to analog input from the potentiometer. The ADC value should be put into a formula to set the appropriate register to regulate the pulsewidth of the PWM signal.
```c
void setup()
{
DDRC |= 0x04;
ADMUX = 0x43;
ADCSRA = 0xAD;
ADCSRA |= 0x40;
TCCR1A = 0x02;
TCCR1B = 0x1B;
ICR1 = 62535;
OCR1A = 0;
}
void loop()
{
while(1){}
}
ISR(ADC_vect)
{
byte tempVar = ADCL;
int pwmChange = 64 * tempVar;
OCR1A = pwmChange;
}
```
2. A potentiometer can also be used to turn the arm of a servo motor. As the potentiometer goes from 0-5V, the servo motor follows from $-90^\circ\leftrightarrow90^\circ$. In thatt a servo's angle is controlled by the pulsewidth of the PWM signal, a linear mapping of pulsewidth to ADC value can be defined. The mapping of angle to voltage to ADC value is shown below.
| angle ($^\circ$) | -90 | -45 | 0 | 45 | 90 |
| ---------------- | ---- | ---- | ---- | ---- | ---- |
| Pulsewidth (ms) | 1 | 1.25 | 1.5 | 1.75 | 2 |
| $V_{in}$ (V) | 0 | 1.25 | 2.5 | 3.75 | 5 |
| ADC | 0 | 255 | 511 | 767 | 1023 |
Repeat the exercise from problem 1, but this time controlling the servo. Remember that you must come up with an equation of the line so that you can set the pulsewidth for any input voltage on a continuous range.
```c
void setup()
{
DDRC |= 0x04;
ADMUX = 0x43;
ADCSRA = 0xAD;
ADCSRA |= 0x40;
TCCR1A = 0x02;
TCCR1B = 0x1B;
ICR1 = 62499;
OCR1A = 93;
}
void loop()
{
while(1){}
}
ISR(ADC_vect)
{
byte tempVar = ADCL;
int pwmChange = ((62 / 1023) * tempVar) + 62;
OCR1A = pwmChange;
}
```

BIN
Homework/hw9.pdf Normal file

Binary file not shown.

View file

@ -0,0 +1,59 @@
#include <Wire.h>
#include <MPU6050.h>
#define SERVOrotate 500
#define SERVO 375
#define degree 5
MPU6050 mpu; // declare a variable called mpu of datatype MPU6050
unsigned long timeStampStartOfLoopMs = 0;
float timeStepS = 0.01;
float yaw = 0.0f; // pitch, roll and yaw values
unsigned long posistion = 0;
Vector normalizedGyroDPS; //stores the three gyroscope readings XYZ in degrees per second (DPS)
volatile bool newDataFlag=false; // boolean flag to indicate that timer1 overflow has occurred
unsigned long startMicroseconds,elapsedMicroseconds; // use for profiling time for certain tasks
//==============================================================================
void setup()
{
Serial.begin(115200);
cli();
TCCR1A = 0b00100010; //Mode 14 fast PWM, 256 scalar
TCCR1B = 0b00011101;
TIMSK1 |= 0b00000100; //enable timer 1 overflow interrupt
ICR1 = 4999;
OCR1A = SERVO;
sei();
while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
{
Serial.println("Could not find a valid MPU6050 sensor, check wiring.");
delay(1000);
}
mpu.calibrateGyro();
mpu.setThreshold(1);
}
//==============================================================================
void loop()
{
normalizedGyroDPS = mpu.readNormalizeGyro();
yaw = yaw + normalizedGyroDPS.ZAxis * timeStepS;
Serial.println(yaw);
posistion = (SERVOrotate - SERVO) * yaw / degree;
OCR1A = SERVO + servoValue;
}
//==============================================================================

View file

@ -0,0 +1,59 @@
#include <Wire.h>
#include <MPU6050.h>
#define SERVOrotate 500
#define SERVO 375
#define degree 5
MPU6050 mpu; // declare a variable called mpu of datatype MPU6050
unsigned long timeStampStartOfLoopMs = 0;
float timeStepS = 0.01;
float yaw = 0.0f; // pitch, roll and yaw values
unsigned long posistion = 0;
Vector normalizedGyroDPS; //stores the three gyroscope readings XYZ in degrees per second (DPS)
volatile bool newDataFlag=false; // boolean flag to indicate that timer1 overflow has occurred
unsigned long startMicroseconds,elapsedMicroseconds; // use for profiling time for certain tasks
//==============================================================================
void setup()
{
Serial.begin(115200);
cli();
TCCR1A = 0b00100010; //Mode 14 fast PWM, 256 scalar
TCCR1B = 0b00011101;
TIMSK1 |= 0b00000100; //enable timer 1 overflow interrupt
ICR1 = 4999;
OCR1A = SERVO;
sei();
while(!mpu.begin(MPU6050_SCALE_2000DPS, MPU6050_RANGE_2G))
{
Serial.println("Could not find a valid MPU6050 sensor, check wiring.");
delay(1000);
}
mpu.calibrateGyro();
mpu.setThreshold(1);
}
//==============================================================================
void loop()
{
normalizedGyroDPS = mpu.readNormalizeGyro();
yaw = yaw + normalizedGyroDPS.ZAxis * timeStepS;
Serial.println(yaw);
posistion = (SERVOrotate - SERVO) * yaw / degree;
OCR1A = SERVO + servoValue;
}
//==============================================================================

22
Homework/teamContract.md Normal file
View file

@ -0,0 +1,22 @@
# Team Contract
As a group, we will
1. Agree to do an equal share of the work, ensuring an understanding of the problems, and communicating when discrepancies arise
2. Notify other team members when they are unavailable, or when questions are incomplete
3. Be open to differing approaches, and listen to new ideas
Meetings will be on Tuesdays from 4-5pm in Gleason 1360, although if necessary it may run longer, as the lab is open until the end of the day. If possible, each individual will have their part of the homework done. The meeting will be to finish homework, if necessary, and discuss issues that we had with said problems. Homework will be turned in by the end of the meeting.
---
---
---

BIN
atmegaPinout.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 KiB

8
classDescription.txt Normal file
View file

@ -0,0 +1,8 @@
CPET-251-03
Microcontroller Systems
Professor: Holly Dickens
Semester: 2195 (2020 Spring)
Time Slot: MWF 10-11 (10-11am)
Professor Dickens was a wonderful professor. She is very well versed in the topics of the class, and is willing to teach something multiple times if certain students don't understand a topic. She is very passionate about the subject as well, and is happy to give more information than necessary if students are interested in a particular topic.
Being very math/programming inclined, and because the course has prerequisites of similarly based courses, we found that we did very well in this class, with not too much additional effort. Time estimate for work amount unavailable, as this document is being created after taking the class, and an estimate is impossible to make. Tests were fairly straightforward, assuming you understood the material. REFERENCE DIAGRAMS HANDED OUT IN CLASS ARE ESSENTIAL FOR SUCCESS. DO NOT LOSE THEM.

BIN
syllabus.pdf Executable file

Binary file not shown.