Windows IoT Core Insider Preview for Raspberry Pi 3

[Windows 10 IoT Core – The operating system built for your Internet of Things]

[Windows IoT Core Walkthrough]

Raspberry PI has two Windows IoT compatible Bluetooth dongles.

  • CSR Mini USB Bluetooth V4.0 Adapter – Class 2 Bluetooth 4.0 Smart Ready Adapter, low energy, dual power
  • ORICO BTA-403 Mini Bluetooth 4.0 USB Dongle – Low Energy Bluetooth 4.0 Adapter USB Micro Adapter Dongle [verified compatible]
  • [Download Windows 10 IoT Core Insider Preview]

    Download Windows 10 IoT Core Insider Preview – Build 16193 for RPI3 so that [Xamarin Forms BluetoothLE samples] work.

    The Windows 10 IoT Core files are installed under C:\Program Files (x86)\Microsoft IoT.

  • Build 14366 – Flashing the RPI2 build works on RPI3
  • The Windows IoT install creates a default user of `administrator` and default password of `p@ssw0rd`.
  • [Windows Insider Program]
    [Get Started]
    [Setup Visual Studio for IoT]
    [Enable your device for development]
    [Windows IoT Remote Client]
    [IoT Documentation and Samples]
    [Get started with your first Hello World IoT Windows Core App]
    [BTLE Samples]
    [Pairing a BLE Device and GATT Attribute Table Dump Tool]
    [How to: Enable Debugging of Unmanaged Code] (unfortunately Windows IoT Core doesn’t support debugging mixed mode yet…)
    [Audio Recorder App on Windows 10 IoT Core]
    [Bluetooth Programming with Windows Sockets]
    [Universal Windows app samples]

    Windows IoT Core provides a web interface accessible from the browser on port 8080. I.e. http://192.168.1.194:8080.

    Python Get Sunrise and Sunset

    Install the `astral` Python package.

    sudo pip install astral
    

    Display the sunrise and sunset.

    import datetime
    from astral import Location
    
    # Get sunrise and sunset for Monroe, WA
    l = Location()
    l.latitude = 47.887059
    l.longitude = -121.8792998
    l.timezone = 'US/Pacific'
    
    sunrise = l.sun()['dawn']
    sunriseHour = sunrise.strftime('%H')
    sunriseMinute = sunrise.strftime('%M')
    print 'sunrise hour='+str(sunriseHour)
    print 'sunrise minute='+str(sunriseMinute)
    
    sunset = l.sun()['sunset']
    sunsetHour = sunset.strftime('%H')
    sunsetMinute = sunset.strftime('%M')
    print 'sunset hour='+str(sunsetHour)
    print 'sunset minute='+str(sunsetMinute)
    

    Raspberry PI Set Time Zone

    After setting the time zone from the terminal, the Raspberry PI will report the correct time given an Internet connection.

    sudo dpkg-reconfigure tzdata
    

    The following code can read and print the hours, minutes, and seconds.

    import datetime
    
    hours = datetime.datetime.now().strftime('%H')
    minutes = datetime.datetime.now().strftime('%M')
    seconds = datetime.datetime.now().strftime('%S')
    print 'hours='+hours+' minutes='+minutes+' seconds='+seconds
    

    Python Get Internal IP Address

    import os
    import urllib
    
    # run command to get wlan0 internal IP address
    command = os.popen('ifconfig | grep -A1 wlan0')
    
    # ready the command data
    client_ip = command.read()
    
    # put the internal IP address into the query params
    query = { 'client_ip' : client_ip }
    url = "http://domain/path/to/some.php?"+urllib.urlencode(query)
    
    # print the final url
    print url
    

    Change Exposure Time

    Import the fraction library.

    from fractions import Fraction
    

    Setting a longer exposure is handy in low-light environments.

    camera.framerate = Fraction(1,6)
    camera.shutter_speed = 6000000
    camera.exposure_mode = 'off'
    camera.iso = 800
    

    Raspberry PI Security Camera

    To setup a Raspberry PI security camera.

    I flash the SD with the latest [NOOBS] after formatting the SD card with the [SDCard Formatter].

    Boot into the desktop and put the Raspberry PI on the wifi network.

    Enable the [camera interface] and reboot.

    Sudo edit the /boot/config.txt file. Disable the camera LED by adding the entry:

    disable_camera_led=1
    

    Install the [poster] module by running the command-line:

    sudo pip install poster
    

    Create the file: ~/superscript

    cd ~/Documents/PythonScripts/Camera/
    python capture_image.py
    

    Add execute permissions to superscript.

    chmod +x ~/superscript
    

    Create a folder for the Camera Python scripts.

    mkdir ~/Documents/PythonScripts
    mkdir ~/Documents/PythonScripts/Camera/
    

    Create the ~/Documents/PythonScripts/Camera/capture_image.py script. Rotate the camera as necessary.

    #get access to the camera
    from picamera import PiCamera
    
    #import so we can invoke another script
    import subprocess
    
    #get access to the clock
    import datetime
    
    # get access to sunrise and sunset
    from astral import Location
    
    #sleep so we can wait on the camera
    from time import sleep
    
    from fractions import Fraction
    
    # create a camera object
    camera = PiCamera()
    
    #set the image resolution
    camera.resolution = (640, 480)
    
    #rotate the camera if upside-down
    camera.rotation = 180
    
    #flip the camera on the horizontal
    camera.hflip = True
    
    i = 0;
    
    #record defaults
    framerate = camera.framerate
    shutter_speed = camera.shutter_speed
    exposure_mode = camera.exposure_mode
    iso = camera.iso
    
    while True:
    
      # Get sunrise and sunset for Monroe, WA
      l = Location()
      l.latitude = 47.887059
      l.longitude = -121.8792998
      l.timezone = 'US/Pacific'
    
      sunrise = l.sun()['dawn']
      sunriseHour = int(sunrise.strftime('%H'))
      sunriseMinute = int(sunrise.strftime('%M'))
      sunset = l.sun()['sunset']
      sunsetHour = int(sunset.strftime('%H'))
      sunsetMinute = int(sunset.strftime('%M'))
    
      hours = int(datetime.datetime.now().strftime('%H'))
      minutes = int(datetime.datetime.now().strftime('%M'))
      seconds = int(datetime.datetime.now().strftime('%S'))
    
      if (hours >= sunriseHour and hours <= sunsetHour):
        #print 'work in the light'
        camera.framerate = framerate
        camera.shutter_speed = shutter_speed
        camera.exposure_mode = exposure_mode
        camera.iso = iso
      else:
        #print 'work in the dark'
        camera.framerate = Fraction(1,6)
        camera.shutter_speed = 6000000
        camera.exposure_mode = 'off'
        camera.iso = 800
    
      #show preview with some transparency
      #camera.start_preview(alpha=200)
    
      #wait two seconds for camera lighting
      #sleep(2)
    
      filename = 'image'+str(i)+'.jpg'
    
      #save image locally
      camera.capture(filename)
    
      #invoke the script to upload the image
      subprocess.call('python save_image.py '+filename, shell=True)
    
      #stop the preview
      #camera.stop_preview()
    
      sleep(3)
    
      i = (i + 1) % 12
    

    Create the save_image.py script. Alter the domain and path to ~/Documents/PythonScripts/Camera/save_image.py.

    #!/usr/bin/env python
    
    import urllib, urllib2, os, os.path, sys
    from poster.encode import multipart_encode
    from poster.streaminghttp import register_openers
    
    command = os.popen('ifconfig | grep -A1 wlan0')
    client_ip = command.read()
    #print client_ip
    
    register_openers()
    
    if (len(sys.argv) > 1):
      filename = sys.argv[1];
    else:
      filename = 'image.jpg';
    
    query = { 'filename' : filename, 'client_ip' : client_ip }
    url = "http://domain/path/save_image.php?"+urllib.urlencode(query)
    
    print 'Saved: '+filename;
    if (os.path.isfile(filename)) :
      values = {'image':open(filename)}
      data, headers = multipart_encode(values)
      headers['User-Agent'] = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
      headers['filename'] = filename
      req = urllib2.Request(url, data, headers)
      req.unverifiable = True
      content = urllib2.urlopen(req).read()
      #print (content)
    else:
      print 'No image file found to upload\r\n';
    

    On your PHP server somewhere, make a new folder and create the page save_image.php.

    <?php
    
    $filename = "image.jpg";
    if ($_GET['filename'] != null) {
       $filename = $_GET['filename'];
    }
    
    if ($_GET['client_ip'] != null) {
       $clientip = $_GET['client_ip'];
       file_put_contents('client_ip.txt', $clientip);
    }
    
    $image = $_FILES["image"];
    
    if ($image == null) {
       echo "Missing image to save as: ";
       echo $filename;
    } else {
       echo "Saved image!";
       $tmp_name = $_FILES["image"]["tmp_name"];
       move_uploaded_file($tmp_name, $filename);
    }
    
    ?>
    

    On your PHP server somewhere, save the page images.php near your server image paths.

    <html>
    <?php
    function displayFirstImage($path) {
       $files = glob($path);
       usort($files, function($a, $b) {
          return filemtime($a) < filemtime($b);
       });
       foreach($files as $file){
          printf('<img src="%1$s"/>', $file);
          break;
       }
    }
    displayFirstImage('path/to/camera1/*.jpg');
    displayFirstImage('path/to/camera2/*.jpg');
    displayFirstImage('path/to/camera3/*.jpg');
    displayFirstImage('path/to/camera4/*.jpg');
    ?>
    <script>
    setTimeout("window.location.reload()", 30000);
    </script>
    </html>
    
    

    Edit ~/.bashrc and add the following to the end of the file.

    ~/superscript &
    

    Reboot the Raspberry PI and the security camera is ready to go!

    Lightweight python motion detection

    Brian Flakes posted an example script in the RPI forums for how to do [lightweight python motion detection] which is useful when taking pictures with the RPI camera module.

    Converted the example to work with PiCamera.

    #get access to the camera
    from picamera import PiCamera
    
    import picamera.array #want to do it in memory
    
    from PIL import Image
    import requests
    
    #import so we can invoke another script
    import subprocess
    
    #sleep so we can wait on the camera
    from time import sleep
    
    token = 'YOUR_SECURITY_TOKEN'
    selector = 'group_id:SEE_THE_SELECTOR_DOCS'
    threshold = 40
    sensitivity = 20
    firstRun = True
    lastPixels = []
    detected = False
    showPreview = False
    hidePreview = False
    waitRedlight = 600
    i = 0
    headers = {
        "Authorization": "Bearer %s" % token,
    }
    
    # create a camera object
    camera = PiCamera()
    
    #set the image resolution
    camera.resolution = (640, 480)
    
    #rotate the camera if upside-down
    #camera.rotation = 180
    
    def Greenlight():
      payload = {
        "power": "off",
        "color": "green saturation:0.9",
        "brightness": 1.0,
        "duration": 1
      }
      try:
        response = requests.put('https://api.lifx.com/v1/lights/'+selector+'/state', data=payload, headers=headers)
      except:
        pass
    
    def Redlight():
      payload = {
        "power": "on",
        "color": "white",
        "brightness": 1.0,
        "duration": 1
      }
      try:
        response = requests.put('https://api.lifx.com/v1/lights/'+selector+'/state', data=payload, headers=headers)
      except:
        pass
    
    Greenlight();
    
    while True:
    
      if (showPreview):
        showPreview = False
        #show preview with some transparency
        camera.start_preview(alpha=200)
        hidePreview = True
    
      filename = 'image'+str(i)+'.jpg'
    
      #save image locally
      camera.capture(filename)
    
      image = Image.open(filename)
      pixels = image.load()
    
      width, height = image.size
      #print ('width='+str(width)+' height='+str(height)+"\n");
    
      if (firstRun):
        firstRun = False
        lastPixels = pixels
    
      # Count changed pixels
      changedPixels = 0
      for x in range(width):
        for y in range(height):
          # Just check green channel as it's the highest quality channel
          pixdiff = abs(pixels[x,y][1] - lastPixels[x,y][1])
          if pixdiff > threshold:
            changedPixels += 1
    
      print ('changedPixels='+str(changedPixels))
      lastPixels = pixels
    
      if (changedPixels < 100):
        if (detected):
          detected = False
          Greenlight();
          firstRun = True
      else:
        if (detected == False):
          detected = True
          Redlight();
          sleep(waitRedlight)
          firstRun = True
          showPreview = True
    
      if (hidePreview):
        hidePreview = False
        #stop the preview
        camera.stop_preview()
        firstRun = True
    
      sleep(1)
    
      i = (i + 1) % 12
      
    

    RASPBIAN

    The Raspberry PI organization hosts [RASPBIAN] which comes pre-installed with plenty of software for education, programming and general use. It has Python, Scratch, Sonic Pi, Java, Mathematica and more. [Noobs] is a tool that can flash an SD card to install Raspbian. The SD card organization has a [SD Card Formatter] tool to format the SD card.

    Reminder: On RPI2 with Raspbian, the default user is pi with the password raspberry.