meta data for this page
  •  

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
ixc2025:team_2:start [2025/05/14 14:06] tautorixc2025:team_2:start [2025/05/15 16:29] (current) – completing sections 1 and 6 tomc1
Line 1: Line 1:
 ====Thunder Bolts==== ====Thunder Bolts====
  
-Current solutions being developed: +=== 1. Group Introduction === 
-  * Motion detector detects how many people used the tram +Team MembersTauri TorpRehan AliHaben YohannesMishqat MaqboolThomas Curtis  
-  *   * Unimplemented +Roles utilised throughout: Programmerarchitectelectriciandesigner
-  * Motion detector can automatically stop tram before collision - activates RGB light in red as brake lightbuzzer as warning sound +
-  *   * Partially implemented +
-  * Button for emergency stoptriggers alert system +
-  *   * Unimplemented +
-  * Fan control – fan activates at certain temperature (data also from internet?) BUT turns off if doors open​ +
-  *   * Unimplemented +
-  * Lights turn on first as dimthen later gradually brighter​ +
-  *   * Unimplemented +
-  * Passenger information system via display- cycling through info e.g. temp, next tramp stopalert (if sudden stop) +
-    * Mostly implemented +
-  * Data sent to website e.g. log of actionspassenger numbersalertstemperature on tram +
-  *   * Unimplemented +
- +
- +
- +
-Possible additional solutions: +
-  * Unordered List ItemSmoking detector warns if any smoke or toxic gas is detected​ +
- +
  
 +=== 2. Initial brainstorming ideas/concepts ===
 Problem: Energy waste with lights being on all the time. Problem: Energy waste with lights being on all the time.
  
Line 65: Line 47:
 3. Prevention: Automated safety measures reduce risk. 3. Prevention: Automated safety measures reduce risk.
  
 +=== 3. Day 2 Presentation slides ===
 +https://utufi-my.sharepoint.com/:p:/g/personal/tjcurt_utu_fi/EajJ4qdvY-tKmBoB6I-NMPcBsNiMwygQtwIO_VnHju2J7w?e=dEHmlX
  
-<!DOCTYPE html> +=== 3. Finalised Idea, description & Functions === 
-<html> +Solutions completed 
-<head> +  * Motion detector can automatically stop tram before collision - activates RGB light in red as brake light, buzzer as warning sound 
-</head> +  * Button for emergency stop, triggers alert system 
-<body>+  * Passenger information system via display- cycling through info e.g. temp, next tramp stop, alert (if sudden stop) 
 + 
 + 
 +Current solutions being developed: 
 +  * Fan control – fan activates at certain temperature BUT turns off if doors open​ 
 +  *   * Mostly implemented 
 +  * Lights turn on first as dim, then later gradually brighter​ 
 +  *   * Unimplemented 
 +  * Data sent to website e.g. log of actions, passenger numbers, alerts, temperature on tram 
 +  *   * Implementation started 
 + 
 + 
 +Possible additional solutions: 
 +  * Smoking detector warns if any smoke or toxic gas is detected​ 
 +  * Motion detector detects how many people used the tram 
 + 
 +=== 4. SUSAF Analysis === 
 +See final powerpoint slide on susaf 
 + 
 +=== 5. Power meter measurements === 
 +Attempted but incomplete due to time constraints. Did achieve some results 
 + 
 +=== 6. Future Improvements === 
 +See final powerpoint slide on future improvements and reflection 
 + 
 +=== 7. Final Day Presentation Slides === 
 +https://utufi-my.sharepoint.com/:p:/g/personal/tautor_utu_fi/ERYLEUsP55xEsYmF-mjSuLYBstzINHCUbmxqcY2E-rxbSw?e=M3qavC 
 + 
 +=== 8. Final Code === 
 + 
 +main.py 
 + 
 +import time 
 + 
 +import website_manager as wm 
 +import display_manager as dm 
 +import combine_btn_motion as bm 
 + 
 +def test_func(): 
 +    pass 
 + 
 + 
 +def main(): 
 +    alert_state = False 
 +    alert_length = 0 
 +     
 +    rolling_timer = time.time() 
 +    alert_timer = time.time() 
 +    print("Starting main loop"
 +    dm.write_message("Tram start!"
 +    detections = 0 
 + 
 + 
 +    while True: 
 +        current_time = time.time() 
 +         
 +         
 +        if alert_state == False: 
 +            print("no alert"
 +            if current_time - rolling_timer > 5: 
 +                print("Display: New rolling message"
 +                rolling_timer += 5 
 +                dm.rolling_message() 
 +                 
 +            #check for danger 
 +            alert_state, alert_length = bm.detect_alert_state() 
 +            alert_timer = current_time 
 +             
 +            if alert_state == True: 
 +                detections += 1 
 +                if detections < 3: 
 +                    alert_state = False 
 +                else: 
 +                    detections = 0 
 + 
 +        else: 
 +            print("alert!"
 +            if current_time - alert_timer < alert_length: 
 +                dm.force_message("Emergency stop!"
 +                bm.activate_brake_and_warning() 
 +                bm.clear_brake_light() 
 +                bm.stop_buzzer() 
 +            else: 
 +                alert_state = False 
 +    wm.force_message("Tram shutdown!"
 +             
 +         
 + 
 +#trigger buzzer 
 +#write message on lcd 
 +#send message to website 
 +def trigger_alert(alert_message : str): 
 +    wm.alert_website(alert_message) 
 +    dm.force_message(alert_message) 
 +     
 +     
 + 
 +test_func() 
 +print() 
 +main() 
 + 
 + 
 + 
 +display_manager.py 
 + 
 +from time import sleep_ms, ticks_ms  
 +from machine import I2C, Pin  
 +from i2c_lcd import I2cLcd  
 + 
 +DEFAULT_I2C_ADDR = 0x27 
 + 
 +i2c = I2C(scl=Pin(22), sda=Pin(21), freq=400000)  
 +lcd = I2cLcd(i2c, DEFAULT_I2C_ADDR, 2, 16) 
 + 
 +messages = ["Out temp: 22C\nIn temp: 20C", "Next Stop: Kauppatori C"] 
 +message_counter = 0 
 + 
 +# Max characters around 40 
 +# Message can be split using \n 
 +def write_message(message : str): 
 +    lcd.clear() 
 +    lcd.move_to(0,0) 
 +    if "\n" in message: 
 +        message_sections = message.split("\n"
 +         
 +        lcd.putstr(message_sections[0]) 
 +        lcd.move_to(0,1) 
 +        lcd.putstr(message_sections[1]) 
 +    else: 
 +        lcd.putstr(message) 
 + 
 + 
 +def force_message(message : str): 
 +    write_message(message) 
 +     
 + 
 +def rolling_message(): 
 +    global message_counter 
 +    write_message(messages[message_counter]) 
 +     
 +    message_counter += 1 
 +    if message_counter >= len(messages): 
 +        message_counter = 0 
 + 
 + 
 + 
 + 
 +# The following line of code should be tested 
 +# using the REPL: 
 + 
 +# 1. To print a string to the LCD: 
 +#    lcd.putstr('Hello world'
 +# 2. To clear the display: 
 +#lcd.clear() 
 +# 3. To control the cursor position: 
 +# lcd.move_to(2, 1) 
 +# 4. To show the cursor: 
 +# lcd.show_cursor() 
 +# 5. To hide the cursor: 
 +#lcd.hide_cursor() 
 +# 6. To set the cursor to blink: 
 +#lcd.blink_cursor_on() 
 +# 7. To stop the cursor on blinking: 
 +#lcd.blink_cursor_off() 
 +# 8. To hide the currently displayed character: 
 +#lcd.display_off() 
 +# 9. To show the currently hidden character: 
 +#lcd.display_on() 
 +# 10. To turn off the backlight: 
 +#lcd.backlight_off() 
 +# 11. To turn ON the backlight: 
 +#lcd.backlight_on() 
 +# 12. To print a single character: 
 +#lcd.putchar('x'
 +# 13. To print a custom character: 
 +#happy_face = bytearray([0x00, 0x0A, 0x00, 0x04, 0x00, 0x11, 0x0E, 0x00]) 
 +#lcd.custom_char(0, happy_face) 
 +#lcd.putchar(chr(0)) 
 + 
 + 
 + 
 +combine_btn_motion.py 
 + 
 +from time import sleep_ms, ticks_ms 
 +from machine import Pin, PWM 
 +import neopixel 
 +import time 
 + 
 +# Initialize PIR sensor (motion detector) 
 +PIR = Pin(19, Pin.IN) 
 + 
 +# Initialize Button (Emergency Stop) on Pin 16 
 +button1 = Pin(16, Pin.IN, Pin.PULL_UP) 
 + 
 +# Initialize RGB LED (Brake light) 
 +pin = Pin(14, Pin.OUT) 
 +np = neopixel.NeoPixel(pin, 4) 
 + 
 +# RGB colors (Red for brake light) 
 +brightness = 100 
 +colors = [ 
 +    [brightness, 0, 0],  # Red (Brake light) 
 +    [0, brightness, 0],  # Green 
 +    [0, 0, brightness],  # Blue 
 +    [brightness, brightness, brightness],  # White 
 +    [0, 0, 0]  # Off 
 +
 + 
 +# Initialize Buzzer 
 +buzzer = PWM(Pin(25)) 
 + 
 +# Function to activate brake light (Red) and buzzer 
 +def activate_brake_and_warning(): 
 +    # Turn on red brake light 
 +    for i in range(4): 
 +        np[i] = colors[0]  # Set all LEDs to red (brake light) 
 +    np.write() 
 +     
 +    # Activate buzzer warning sound 
 +    buzzer.duty(1000) 
 +    buzzer.freq(294)  # Start sound 
 +    time.sleep(0.25) 
 +    buzzer.freq(440) 
 +    time.sleep(0.25) 
 +    buzzer.freq(392) 
 +    time.sleep(0.25) 
 +    buzzer.freq(532) 
 +    time.sleep(0.25) 
 +    buzzer.duty(0)  # Stop sound 
 + 
 +# Function to clear brake light (turn off LEDs) 
 +def clear_brake_light(): 
 +    for i in range(4): 
 +        np[i] = colors[4]  # Turn off all LEDs 
 +    np.write() 
 + 
 +# Initialize counter and last PIR value 
 +count = 0 
 +last_value = 0 
 + 
 +# Main loop to detect motion or button press and activate brake and buzzer 
 +def detect_alert_state(): 
 +    # Read button state (Emergency Stop) 
 +    btnVal1 = button1.value()  # Button press state 
 + 
 +    # Check for motion detection or button press 
 +    if PIR.value() == 1 and last_value == 0:  # Motion detected (new motion event) 
 +        print(f"Motion detected! Count: {count + 1}") 
 +        count += 1  # Increment people count 
 +         
 +        # Activate brake light and buzzer 
 +        return true, 5 
 +         
 +    elif btnVal1 == 0:  # Emergency stop button pressed (active low) 
 +        print("Emergency Stop Activated!"
 +         
 +        # Activate brake light and buzzer 
 +        return true, 5 
 + 
 +    else: 
 +        last_value = PIR.value()  # Update PIR last value 
 +        clear_brake_light()  # Turn off brake light if no motion and no button press 
 + 
 +    time.sleep(0.1)  # Small delay for debounce 
 + 
 + 
 +light_control.py 
 + 
 +mport time 
 +import math 
 +from machine import Pin, PWM 
 + 
 +PWM_PIN = 12   
 +PWM_FREQ = 10000  # PWM frequency in Hz 
 +MIN_BRIGHTNESS = 0   
 +MAX_BRIGHTNESS = 1023  
 + 
 +# Time-based irradiance simulation parameters 
 +DAWN_HOUR = 6   
 +SUNRISE_HOUR = 7   
 +NOON_HOUR = 12   
 +SUNSET_HOUR = 19   
 +DUSK_HOUR = 20  
 + 
 +led_pwm = PWM(Pin(PWM_PIN, Pin.OUT), PWM_FREQ) 
 + 
 + 
 +def get_current_hour(): 
 +    cycle_minutes = (time.time() % (24 * 60))  
 +    current_hour = (cycle_minutes / 60) % 24 
 +    return current_hour 
 + 
 + 
 +def simulate_irradiance(): 
 +    hour = get_current_hour() 
 +     
 +    # Night (before dawn or after dusk) 
 +    if hour < DAWN_HOUR or hour > DUSK_HOUR: 
 +        return 0.0 
 +     
 +    # Dawn (gradual increase from dark to daylight) 
 +    elif DAWN_HOUR <= hour < SUNRISE_HOUR: 
 +        dawn_progress = (hour - DAWN_HOUR) / (SUNRISE_HOUR - DAWN_HOUR) 
 +        return dawn_progress * 0.5  
 +     
 +    # Morning (increasing to noon) 
 +    elif SUNRISE_HOUR <= hour < NOON_HOUR: 
 +        morning_progress = (hour - SUNRISE_HOUR) / (NOON_HOUR - SUNRISE_HOUR) 
 +        return 0.5 + (morning_progress * 0.5)   
 +     
 +    # Afternoon (decreasing from noon) 
 +    elif NOON_HOUR <= hour < SUNSET_HOUR: 
 +        afternoon_progress = (hour - NOON_HOUR) / (SUNSET_HOUR - NOON_HOUR) 
 +        return 1.0 - (afternoon_progress * 0.5)   
 +     
 +    # Dusk (gradual decrease from daylight to dark) 
 +    else:   
 +        dusk_progress = (hour - SUNSET_HOUR) / (DUSK_HOUR - SUNSET_HOUR) 
 +        return 0.5 - (dusk_progress * 0.5)   
 + 
 + 
 +def calculate_light_brightness(irradiance): 
 +    # Threshold above which no artificial light is needed 
 +    DAY_THRESHOLD = 0.7 
 +     
 +    if irradiance >= DAY_THRESHOLD: 
 +        return 0 
 +    else: 
 +        brightness_factor = 1.0 - (irradiance / DAY_THRESHOLD) 
 +         
 +        brightness_factor = math.pow(brightness_factor, 0.8) 
 +         
 +        brightness = int(brightness_factor * MAX_BRIGHTNESS) 
 +        return max(MIN_BRIGHTNESS, min(brightness, MAX_BRIGHTNESS)) 
 + 
 + 
 +def print_debug_info(irradiance, brightness): 
 +    hour = get_current_hour() 
 +    print(f"Time: {hour:.2f}h | Irradiance: {irradiance:.2f} | Light brightness: {brightness} ({brightness/MAX_BRIGHTNESS*100:.1f}%)"
 + 
 + 
 +try: 
 +    print("Smart Tram Light Control - Demo Mode"
 +    print("------------------------------------"
 +    print("Light will adjust automatically based on simulated time of day"
 +    print("Press Ctrl+C to exit"
 +    print() 
 +     
 +    # For demo purposes, we'll speed up time 
 +    demo_time_factor = 60  # 1 minute = 1 hour 
 +    last_time = time.time() 
 +     
 +    while True: 
 +        irradiance = simulate_irradiance() 
 +         
 +        brightness = calculate_light_brightness(irradiance) 
 +         
 +        led_pwm.duty(brightness) 
 +         
 +        print_debug_info(irradiance, brightness) 
 +         
 +        time.sleep(1) 
 +         
 +        current_time = time.time() 
 +        time_diff = current_time - last_time 
 +        last_time = current_time 
 +        time.sleep_ms(int(time_diff * demo_time_factor * 1000)) 
 +         
 +except KeyboardInterrupt: 
 +    print("\nExiting program"
 +finally: 
 +    led_pwm.deinit() 
 +    print("PWM resource released"
 + 
 + 
 + 
 +fan.py 
 + 
 +from machine import Pin, PWM 
 +import machine 
 +import time 
 +import dht 
 + 
 +# Initialize Fan Control Pins 
 +INA = PWM(Pin(27, Pin.OUT), 10000)  # INA corresponds to IN+ 
 +INB = PWM(Pin(18, Pin.OUT), 10000)  # INB corresponds to IN- 
 + 
 +# Initialize Button for door control 
 +button1 = Pin(26, Pin.IN, Pin.PULL_UP)  # Button for opening/closing the door 
 + 
 +# Initialize PWM for Servo (Door control) 
 +pwm = PWM(Pin(5))   
 +pwm.freq(50) 
 + 
 +#Associate DHT11 with Pin(17). 
 +DHT = dht.DHT11(machine.Pin(17)) 
 + 
 + 
 +# RGB colors (Red for brake light, for indication when door is open) 
 + 
 + 
 +# Fan control functions 
 +def activate_fan(): 
 +    INA.duty(0)   # Fan control forward direction 
 +    INB.duty(700) # Set duty cycle to rotate the fan 
 + 
 +def deactivate_fan(): 
 +    INA.duty(0)   # Stop fan 
 +    INB.duty(0)   # Stop fan 
 + 
 +# Function to simulate door control with PWM (servo motor) 
 +def control_door(open_door): 
 +    if open_door: 
 +        pwm.duty(77)  # Door open (90 degrees) 
 +        print("Door opened."
 +    else: 
 +        pwm.duty(25)  # Door closed (0 degrees) 
 +        print("Door closed."
 + 
 +# Main loop to toggle door and control fan 
 +door_open = False  # Initially, door is closed 
 + 
 +while True: 
 +    btnVal1 = button1.value()  # Read the button value (active low) 
 +    DHT.measure() 
 +     
 +    if btnVal1 == 0:  # Button pressed (active low) 
 +        time.sleep(0.01)  # Delay to debounce the button 
 +        while btnVal1 == 0: 
 +            btnVal1 = button1.value()  # Wait for button release 
 +        door_open = not door_open  # Toggle door state 
 +         
 +        # Control the door based on the state 
 +        control_door(door_open) 
 +         
 +        # Control the fan based on door state 
 +        if door_open: 
 +            deactivate_fan()  # Turn off fan if door is open 
 +        else: 
 +            activate_fan()  # Turn on fan if door is closed 
 + 
 +    time.sleep(0.1)  # Short delay to prevent rapid toggling 
 + 
 + 
 +testwebsite.html 
 + 
 +  <!DOCTYPE html> 
 +  <html> 
 +  <head> 
 +  </head> 
 +  <body>
   <h3>Daily passenger count:</h3><!--Motion detector detects how many people used the tram-->   <h3>Daily passenger count:</h3><!--Motion detector detects how many people used the tram-->
   <h3>Tram is moving: [yes/no]</h3> <!--Motion detector can automatically stop tram before collision - activates RGB light in red as brake light, buzzer as warning sound-->   <h3>Tram is moving: [yes/no]</h3> <!--Motion detector can automatically stop tram before collision - activates RGB light in red as brake light, buzzer as warning sound-->
Line 78: Line 512:
   <h3>Display information: [temperature outside/time until tram arrives at the next stop] </h3> <!--Passenger information system via display- cycling through info e.g. temp, next tramp stop, alert (if sudden stop)-->   <h3>Display information: [temperature outside/time until tram arrives at the next stop] </h3> <!--Passenger information system via display- cycling through info e.g. temp, next tramp stop, alert (if sudden stop)-->
   <h3></h3> <!--Data sent to website e.g. log of actions, passenger numbers, alerts, temperature on tram-->   <h3></h3> <!--Data sent to website e.g. log of actions, passenger numbers, alerts, temperature on tram-->
-</body> +  <script> 
-</html> +    // Refresh the page every 1000 milliseconds (1 second) 
- +    setInterval(function () { 
 +      location.reload(); 
 +    }, 1000); 
 +  </script> 
 +  </body> 
 +  </html>