Difference between revisions of "Seanan's Engineering Notebook"

From CHS Sigma
Jump to: navigation, search
(CircuitPy Photointerrupter)
(Requirements)
 
(One intermediate revision by one user not shown)
Line 457: Line 457:
  
 
== CircuitPy Distance sensor ==
 
== 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.
 +
[[File:Color_spectrum.png]]
 +
 +
=== Process ===
 +
Read documentation of <code>adafruit_hcsr04</code>, got distance sensing working. Then I did some quick math about how to scale the rgb values based on distance, which needed <code>constrain()</code>(see above,) <code>abs()</code>, and <code>int()</code> to prevent value errors. I later realized that the g and b values w**e**re backwards and fixed it
 +
=== Code ===
 +
<div style="height:12.7em; overflow:auto; border: 1px solid #008">
 +
<syntaxhighlight lang="python">
 +
import time
 +
import board
 +
import adafruit_hcsr04
 +
import neopixel
 +
 +
sonar = adafruit_hcsr04.HCSR04(trigger_pin=board.D8, echo_pin=board.D9)
 +
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)
 +
</syntaxhighlight></div>

Latest revision as of 09:36, 11 September 2019

Seanan's Engineering notebook.

Engineering 2

LED Fade

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
//Fade
//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
   }
}

Picture

Just an led.png

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.

Sinusoidally fading led

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
//Sine fade.ino
//Makes an led fade sinusoidally
 
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.
}

Picture

Just an led.png

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; 
}

Wiring Documents

HC-SR bb.png

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);
}

Fritzing Diagram

Lcd bb.png

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

GitHub repository

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
from adafruit_motor import servo
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.

Color spectrum.png

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 adafruit_hcsr04
import neopixel
 
sonar = adafruit_hcsr04.HCSR04(trigger_pin=board.D8, echo_pin=board.D9)
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)