# Difference between revisions of "Seanan's Engineering Notebook"

Seanan's Engineering notebook.

# Engineering 2

### Description and Process

In this project I had to make a led fade from the brightest to the dimmest linearly. To start, I made a for loop to increase the value I was setting the led's brightness to. I then added some things to make the led decrease in brightness at some point. The second thing I had to do was print an increasing amount of symbols, depending on the brightness. I did this by putting a for loop in my original for loop that prints a - without a line break brightness times.

### Code

```//Seanan Shanks
//Makes an led fade in and out, and prints a wave of - to the serial monitor

int led = 6;  //Which pin the led is on
int x = 1;    //How much the number is changed
void setup() {
// put your setup code here, to run once:
pinMode(led, OUTPUT);
Serial.begin(9600);
}

void loop() {
for (int i = 0; i > -1; i = i + x){   //increases a number and runs some code forever
analogWrite(led, i);              //Sets the led's brightness to a number between 0(completely off) and 255(Completelty off), unlike digitalWrite, which is either completely on or completely off.
if (i == 255) x = -1;             //Switch direction the number changes at peak
if (i == 0) x = 1;                //Switch direction the number changes at zero
for (int f = i; f > -1; f--){     //Makes a number that is identical to the other number decrese to zero and runs some code
Serial.print('-');              //Ouputs a - number times, !WITHOUT A LINE BREAK!
}
Serial.println(' ');              //Makes a new line
delay(255-i);                     //Waits a bit
}
}```

### Reflection

This project was pretty easy, which is fine. The main problem I had was trying to figure out how strings work(Syntax wise), but I just decided to just not put line breaks when printing out the symbols. This made it slow down at higher brightness's, but I think it was a fair trade off.

### Description and Process

In this project I had to make an led fade sinusoidally. To start with, I attempted to figure it out myself, but I couldn't get it to work due to thinking about it wrong. I then looked up the problem on the internet, specifically the arduino forums. I found the code for my exact problem and simply copy pasted it into my code. The code works by having a value change based on the time since the program started, converting it into radians by multiplying by 2PI and then taking the sine of it. After that, it is multiplied by 128 and added to 128, in order to get a value between 0 and 255, which is then given to the led using analogWrite.

### Code

```//Seanan Shanks

int Pin = 6;

void setup()
{
Serial.begin(9600);
pinMode(Pin, INPUT);

}

void loop()
{
float something = millis()/5000.0; //Makes a number based on the time since the program started running.
int value = 128.0 + 128 * sin(something * 2.0 * PI); //Makes a value between 255 and 0 based on the sine of the previous number. (Which is between -1 and 1)
analogWrite(Pin,value); //Actually sets the LED to be as bright as it should.
}```

### Reflection

The internet is great at giving you the answer to problems, if you are having trouble, look for an answer on the internet, it's most likely there somewhere.

## Ultrasonic sensor plus servo

### Description and process

In this assignment I had to make a serve rotate based on the distance from the Ultrasonic Sensor. The first thing I did was search up the HC-SR04 ultrasonic sensor and I found This site. Next I copied the code from the site, then added the line to control the servo.

### Code

```//Seanan Shanks
//UltrasonicAssignment.ino
//Makes a servo move based on how far away the thing the ultrasonic sensor is in centimeters

#include <Servo.h>
int trigPin = 11;    //Trig - green Jumper
int echoPin = 12;    //Echo - yellow Jumper
long duration, cm, inches;
Servo servo;
void setup() {
//Serial Port begin
Serial.begin (9600);
//Define inputs and outputs
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
servo.attach(10);
}

void loop()
{
getDistance();
Serial.print(inches);
Serial.print("in, ");
Serial.print(cm);
Serial.print("cm");
Serial.println();
servo.write(cm);
delay(250);
}

void getDistance() {
// The sensor is triggered by a HIGH pulse of 10 or more microseconds.
// Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
digitalWrite(trigPin, LOW);
delayMicroseconds(5);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

// Read the signal from the sensor: a HIGH pulse whose
// duration is the time (in microseconds) from the sending
// of the ping to the reception of its echo off of an object.
pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);
// convert the time into a distance
cm = (duration/2) / 29.1;
inches = (duration/2) / 74;
}```

### Reflections

Once again, the internet was useful.

## Hello LCD

### Description and Process

In this assignment I had to print "Hello world" to an lcd, as well as the time in seconds since the program started running. To start with, I followed the tutorial linked in the assignment, which told me how to wire the lcd up. Secondly, I went to the next part of the tutorial, which wasn't particularly helpful, as it just said to change something in "the example." I then went to the library documentation on the arduino site to look for information. I successfully found that information; remember the "example" earlier? Turns out that was on the arduino site, and it did exactly what the assignment asked. I only copied some of it (I already had most of it,) but it worked.

### Code

```//Seanan Shanks
//Hello LCD.ino
//prints hello world and the amount of seconds ince the program started to an lcd.
#include <LiquidCrystal.h>
//initilizes lcd
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void setup() {
// put your setup code here, to run once:
lcd.begin(16,2);
//Prints Hello World to the LCD
lcd.print("Hello world");
}

void loop() {
// put your main code here, to run repeatedly:
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis() / 1000);
}```

### Reflections

The internet continues to be useful.

The main difference between using an lcd and using serial monitor is that an lcd doesn't have an infinite amount of space, and that it can go back and overwrite things.

## Lcd Backpack

### Description and Process

For this I had to do the same thing I did in the previous assignment, but using an I2C lcd backpack. It was pretty easy because all of the new code was in the assignment, as well as the wiring.

### Code

```//Seanan Shanks
//LCDBackpack.ino
//prints "Hello, World!" and the time in seconds since the program started to an lcd using an I2C lcd backpack

#include <Wire.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7);

void setup() {
// put your setup code here, to run once:
lcd.begin (16,2); // for 16 x 2 LCD module
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH);
lcd.print("Hello, World!");
}

void loop() {
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis() / 1000);
}```

### Reflections

Following instructions when they are provided is a good idea. Also, lcd backpacks are good at using way less arduino space.

## Photo interrupter

### Description and Progress

```You can use attachInterrupt() anywhere, but let's specify two in the setup() function.  One will turn the LED on with RISING.  The other will turn the LED off with FALLING.  So your code won't use any digitalRead() functions,
only interrupts.
One more thing: use Serial.println() to print out how many times the photo interrupter has been interrupted.
```

I had a hard time getting the photo interrupter working. I was attaching two interrupts to the same pin, which doesn't work. Besides that, it was pretty easy.

### Code

```//Seanan Shanks
//PhotoInterupt.ino
//Turns an LED on when a photo interrupter is interrupted, and off when it isn't.

int led = 7;
int repeats = 0;
void setup() {
// put your setup code here, to run once:
pinMode(led, OUTPUT);
attachInterrupt(digitalPinToInterrupt(2), high, RISING);
attachInterrupt(digitalPinToInterrupt(3), low, FALLING);
high();
delay(200);
low();
Serial.begin(9600);
}

void loop() {}

void high() {
digitalWrite(led, HIGH);
repeats++;
Serial.println(repeats);
}
void low() {
digitalWrite(led, LOW);
}```

### Reflections

It took me too long to figure out the problem, although it wasn't documented in the assignment, nor the documentation. This will be useful for my future project(s).

## Potentiometer

### Description and Process

```Your assignment is to wire up a potentiometer and have its value scaled and read out to the LCD screen (using the backpack).  At the same time, the potentiometer controls the brightness of an LED.
```

I started out with good code, but wiring with two critical mistakes; first, I was trying to take an analog input with a digital pin, and second, the potentiometer was wired wrong. Besides those I had to add a map() function to my code in order to display good values. printNumber() is a function that I use to print number that are meant to be modified a lot, especially into smaller numbers.

### Code

```//Seanan Shanks
//Potentiometer.ino
//Lights up an LED with brightness X and displays X, where X is a potentiometer input

#include <Wire.h>
#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>

int ledPin = 5;
int potio = 0;

LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7);

void setup() {
// put your setup code here, to run once:
lcd.begin (16,2);
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH);
lcd.print("Brightness:");
pinMode(ledPin, OUTPUT);
pinMode(A3, INPUT);
}
void printNumber(int number, int column = 0, int row = 1) {
lcd.setCursor(column,row);
lcd.print(number);
lcd.setCursor(String(number).length()+column, row);
lcd.print("        ");
delay(100);
}
void loop() {
// put your main code here, to run repeatedly:
potio = map(analogRead(A3), 0, 1023, 0, 255);
analogWrite(ledPin, potio);
printNumber(potio);
}```

### Reflections

It took me too long to figure out the problem, although it wasn't documented in the assignment, nor the documentation. This will be useful for my future project(s).

# Engineering 3

## Hello CircuitPy

### Requirements

```Part 1: Make the onboard metapixel red
```
```Part 2: Make an led fade in and out
```

### Process

Part 1:

The code was basically provided, making it no big feat.

Part 2:

Some quick googling of how to do analog stuff in circuitpy, and I found that `from analogio import AnalogOut` allows you to do analog outputs. From there it was only a matter of finding that the max analog value was 65535 in circuitpy instead of the 255 it was in arduino, and a constrain function I copied from stackoverflow, and it worked.

### Code

Part 1

```import board
import neopixel

dot = neopixel.NeoPixel(board.NEOPIXEL, 1)

print("Make it red!")

while True:
dot.fill((255, 0, 0))```

Part 2

```import board
import time
from analogio import AnalogOut

led = AnalogOut(board.A0)
inc = 32
val = 0

def clamp(n, minn, maxn):
return max(min(maxn, n), minn)

while True:
if val+inc >= 65535 or val+inc < 0:
inc = -inc
clamp(val, 0, 65535)
val = val + inc
led.value = val```

## CircuitPy Servo

### Requirements

```Make a 180° servo rotate in one direction if one wire is touched and in the other direction if the other is touched.
```

### Process

I looked up the servo library and based my code on the example for the setup, and the fading led for the rotating. I then looked up the touch library and changed when it increments the angle

### Code

```import board
import time
import pulseio
import touchio

pwm = pulseio.PWMOut(board.A2, duty_cycle=2 ** 15, frequency=50)
my_servo = servo.Servo(pwm)
touch1 = touchio.TouchIn(board.A0)
touch2 = touchio.TouchIn(board.A1)

inc = 5
val = 90

while True:
if touch1.value:
val = val + inc
if touch2.value:
val = val - inc
if val > 180: val = 180
if val < 0: val = 0
#print(val)
my_servo.angle = val
time.sleep(0.015)```

## CircuitPy LCD

### Requirements

```Set up an LCD that displays a number that increases on button press
```

### Process

So the process for this one was: copy stuff from the documentation, be confused as to why it's giving errors for three days, and then updating circuitpy when Dr. Shields figure out that that was the problem. It then proceeded to work.

### Code

```from lcd.lcd import LCD
from lcd.i2c_pcf8574_interface import I2CPCF8574Interface
from lcd.lcd import CursorMode
import time
import board
from digitalio import DigitalInOut, Direction, Pull

# Talk to the LCD at I2C address 0x27 or 0x3F
lcd = LCD(I2CPCF8574Interface(0x27), num_rows=2, num_cols=16)

switch = DigitalInOut(board.D3)
switch.direction = Direction.INPUT
switch.pull = Pull.UP

pressed = True
lastState = True
count = 0

while True:
lcd.set_cursor_pos(0, 0)
lcd.print("Counting up")
pressed = switch.value
if not pressed and lastState:
count += 1
lcd.set_cursor_pos(1, 0)
lcd.print("Presses:        ")
lcd.set_cursor_pos(1,8)
lcd.print(str(count))
lastState = pressed```

## CircuitPy Photointerrupter

### Requirements

```Output the number of interrupts a photointerrupter detects over 4 seconds without using `time.sleep()`
```

### Process

The first thing I did was check out the `time` library's documentation. This told me about three different functions that I thought worked like arduino's `millis()`. The first one was deprecated, the second didn't work, and the third wasn't precise enough. When I brought it up to Dr Shields he mentioned `time.monotonic()` which was exactly what I was looking for. I then set up a check for every 4 seconds, like I did with the PID box.

### Code

```import time
import board
from digitalio import DigitalInOut, Direction, Pull

photointerupter = DigitalInOut(board.D8)
photointerupter.direction = Direction.INPUT
photointerupter.pull = Pull.UP

breaks = 0
then = time.monotonic()
previous = False

while True:
if photointerupter.value and not previous:
breaks += 1
if (time.monotonic() - then) % 4 == 0:
print("There have been", breaks, "breaks")
breaks = 0
previous = photointerupter.value```

## CircuitPy Distance sensor

### Requirements

```The HC-SR04 measures the distance to an object roughly 10 times per second.
The distance is printed out to your serial monitor.
The color of the onboard neopixel on your Metro corresponds to the distance, according to the graphic below.
```

### Process

Read documentation of `adafruit_hcsr04`, got distance sensing working. Then I did some quick math about how to scale the rgb values based on distance, which needed `constrain()`(see above,) `abs()`, and `int()` to prevent value errors. I later realized that the g and b values w**e**re backwards and fixed it

### Code

```import time
import board
import neopixel

dot = neopixel.NeoPixel(board.NEOPIXEL, 1)

def constrain(n, minn, maxn):
return min(max(n, minn), maxn)

while True:
try:
print(sonar.distance)
dot.fill((constrain(int(255-(17*sonar.distance)), 0, 255),constrain(int(255-abs(17*(35-sonar.distance))), 0, 255)\
,constrain(int(255-abs(17*(20-sonar.distance))), 0, 255)))
except RuntimeError:
print('fail')
pass
time.sleep(0.1)```