What is it? : A method to use a PIR sensor connected to MCU to wake or turn on the LattePanda
Scenario: Use a PIR motion sensor connected to the MCU to detect motion and start the CPU Turn on from OFF or Wake from Sleep if its not already running
How to use:
Here’s a detailed description of its components and functionality:
 
  const int PIR_Pin = 0; // PIR DATA is connected to D0 via Green wire
  const int pinS0 = 1;   // S0 CPU state pin connected to D1 via Yellow wire
  const int pinSW = 2;   // SW CPU switch pin connected to D2 via Black wire
  
  bool motionDetected = false; // State-tracking variable for motion detection
  
  void setup() {
      pinMode(LED_BUILTIN, OUTPUT);
      pinMode(PIR_Pin, INPUT);
      pinMode(pinSW, INPUT);    // Default state, SW pin is high impedance input
      pinMode(pinS0, INPUT);    // Default state, S0 pin is high impedance input
      Serial.begin(9600);       // Initialize serial communication at 9600 bps
      delay(1000);              // After power up, delay for 1 second before detection
  }
  
  void startmeup() {
      while (digitalRead(pinS0) == 0) { // If S0 pin is low, the board is not powered on
          // Blink a "dot dot dot" pattern when S0 is LOW
          dot();
          dot();
          dot();
  
          pinMode(pinSW, OUTPUT); // Switch to output mode, ready to pull SW pin low
          digitalWrite(pinSW, LOW); // Pull SW pin low to simulate pressing the power switch
          blinkLED(LED_BUILTIN, 5, 300); // Visual feedback during the power-on process
  
          pinMode(pinSW, INPUT); // Restore high impedance input
  
          dash();
          dash();
          dash();
          delay(2000); // Wait a while to let the board fully start
      }
  }
  
  void dot() {
      digitalWrite(LED_BUILTIN, HIGH);
      delay(200); // Dot duration
      digitalWrite(LED_BUILTIN, LOW);
      delay(200); // Space after dot
  }
  
  void dash() {
      digitalWrite(LED_BUILTIN, HIGH);
      delay(600); // Dash duration
      digitalWrite(LED_BUILTIN, LOW);
      delay(200); // Space after dash
  }
  
  void blinkLED(int pin, int times, int speed) {
      pinMode(pin, OUTPUT); // Set the LED pin as an output
      for (int i = 0; i < times; i++) {
          digitalWrite(pin, HIGH); // Turn the LED on
          delay(speed); // Wait for the specified time
          digitalWrite(pin, LOW); // Turn the LED off
          delay(speed); // Wait for the specified time
      }
  }
  
  void loop() {
      if (digitalRead(PIR_Pin) == HIGH) {
          motionDetected = true; // Update state to avoid re-sending the message
          digitalWrite(LED_BUILTIN, HIGH); // Turn on LED to indicate motion
  
          if (digitalRead(pinS0) == LOW) {
              startmeup(); // Ensure the PC is powered on
          }
  
          Serial.println("MOTION DETECTED"); // Send motion detection event to the CPU
      } else if (digitalRead(PIR_Pin) == LOW && motionDetected) {
          motionDetected = false; // Reset state when motion stops
          Serial.println("NTD"); // Send NOTHING TODO NTD motion detection event to the CPU
          digitalWrite(LED_BUILTIN, LOW); // Turn off LED
      }
  }
Optional: Python Script Example:
/*
import serial
import time
import ctypes
def is_screen_on():
    """
    Checks if the screen is awake by using Windows API to detect idle time.
    Returns True if the screen is likely on; otherwise, False.
    """
    class LASTINPUTINFO(ctypes.Structure):
        _fields_ = [("cbSize", ctypes.c_uint), ("dwTime", ctypes.c_uint)]
    
    lii = LASTINPUTINFO()
    lii.cbSize = ctypes.sizeof(LASTINPUTINFO)
    
    if ctypes.windll.user32.GetLastInputInfo(ctypes.byref(lii)):
        current_time = ctypes.windll.kernel32.GetTickCount()
        idle_time = (current_time - lii.dwTime) / 1000  # Idle time in seconds
        return idle_time < 300  # If idle time is less than 5 minutes, screen is likely on
    return False
def wake_up_screen():
    """
    Wakes up the screen if it is off.
    """
    if not is_screen_on():
        # Get a handle to the console window
        hWnd = ctypes.windll.kernel32.GetConsoleWindow()
        # Define constants
        WM_SYSCOMMAND = 0x0112
        SC_MONITORPOWER = 0xF170
        # Send the message to turn on the screen
        ctypes.windll.user32.SendMessageW(hWnd, WM_SYSCOMMAND, SC_MONITORPOWER, -1)
        print("Screen has been woken up!")
    else:
        print("Screen is already on.")
# Configure the serial connection
ser = serial.Serial('COM5', 9600, timeout=1)  # Replace 'COM5' with your serial port
last_motion_time = time.time()  # Track the last time motion was detected
motion_detected = False  # Track the motion state
while True:
    line = ser.readline().decode('utf-8').strip()  # Read a line from the serial port
    current_time = time.time()  # Get the current time
    
    if line == "MOTION DETECTED":
        # Motion detected, print a message and update state
        print("Motion detected by Arduino!")
        last_motion_time = current_time  # Update the last motion time
        motion_detected = True
        # Call the function to wake up the screen
        wake_up_screen()
    elif current_time - last_motion_time > 5:  # 5 seconds of no motion
        if motion_detected:
            print("No motion detected...")  # Notify only once when switching to no motion state
            motion_detected = False
*/