Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Alex Glow
Published © CC BY-NC-SA

Nikola: Privacy-Focused Camera Bot

A cute little companion bot for media excursions! With a smart, consent-based camera, high-quality microphone, and cute wiggly ears.

IntermediateWork in progress10 hours2,650
Nikola: Privacy-Focused Camera Bot

Things used in this project

Hardware components

Nicla Vision
Arduino Nicla Vision
×1
Adafruit Gemma M0
×1
LED (generic)
LED (generic)
×1
SG90 Micro-servo motor
SG90 Micro-servo motor
×2
USB-A to Micro-USB Cable
USB-A to Micro-USB Cable
×1

Software apps and online services

OpenMV IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

Mic holder block

Sits below the servo head in the camera holder; has a divot for the lavalier mic head.

Camera aperture fixture

Attaches to the fabric, to hold open a hole for the camera. I ended up gluing AND sewing it down – the black thread kinda looks like the lines in an iris. :)

Code

Single-ear servo flick (for Gemma M0)

JavaScript
Created in MakeCode drag-and-drop interface... I've only got one ear working, so far! Edit at: https://makecode.com/_h0Xb4o2vJhU7
No preview (download only).

QR code-based camera with indicator LED

MicroPython
When the camera sees the QR code that links to this project, it will take a photo, while illuminating a GPIO-connected indicator LED.
# Adapted from: https://pyimagesearch.com/2018/03/19/reading-barcodes-with-python-and-openmv
# And: https://docs.arduino.cc/tutorials/nicla-vision/getting-started#using-the-nicla-vision-camera
# by Alex Glow for Hackster.io, 2022
# for F3NR1R: http://bit.ly/fenrir2

# import necessary packages
import sensor
import time
import image
import pyb

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.RGB565) # Sets the sensor to RGB
sensor.set_framesize(sensor.QVGA) # Sets the resolution to 320x240 px
sensor.set_vflip(True) # Flips the image vertically
sensor.set_hmirror(True) # Mirrors the image horizontally

# initialize the clock
clock = time.clock()

redLED = pyb.LED(1) # built-in red LED
blueLED = pyb.LED(3) # built-in blue LED

ledPin = pyb.Pin(pyb.Pin.board.PG1, pyb.Pin.OUT_PP)
ledPin.on()
pyb.delay(500)
ledPin.off()

redLED.on()
sensor.skip_frames(time = 2000) # Skip some frames to let the image stabilize  about 4 sec
redLED.off()
blueLED.on()

snapno = 0

# barcode type lookup table
barcode_type = {
    image.EAN2: "EAN2",
    image.EAN5: "EAN5",
    image.EAN8: "EAN8",
    image.UPCE: "UPCE",
    image.ISBN10: "ISBN10",
    image.EAN13: "EAN13",
    image.ISBN13: "ISBN13",
    image.I25: "I25",
    image.DATABAR: "DATABAR",
    image.DATABAR_EXP: "DATABAR_EXP",
    image.CODABAR: "CODABAR",
    image.CODE39: "CODE39",
    image.PDF417: "PDF417",
    image.CODE93: "CODE93",
    image.CODE128: "CODE128"
}

def barcode_name(code):
    # if the code type is in the dictionary, return the value string
    if code.type() in barcode_type.keys():
        return barcode_type[code.type()]
    # otherwise return a "not defined" string
    return "NOT DEFINED"

# def ninety()
#    pyb.udelay(1500)

# loop over frames and detect + decode barcodes
while True:

    # tick the clock for our FPS counter
    clock.tick()

    # grab a frame
    img = sensor.snapshot()

    # loop over standard barcodes that are detected in the image
    for code in img.find_barcodes():

        # draw a rectangle around the barcode
        img.draw_rectangle(code.rect(), color=127)

        # print information in the IDE terminal
        print("type: {}, quality: {}, payload: {}".format(
            barcode_name(code),
            code.quality(),
            code.payload()))

        # draw the barcode string on the screen similar to cv2.putText
        img.draw_string(10, 10, code.payload(), color=127)

    # loop over QR codes that are detected in the image
    for code in img.find_qrcodes():
        # draw a rectangle around the barcode
        img.draw_rectangle(code.rect(), color=127)
        # print information in the IDE terminal
        print("type: QR, payload: {}".format(code.payload()))
        # draw the barcode string on the screen similar to cv2.putText
        img.draw_string(10, 10, code.payload(), color=127)
        # save pic & delay 2s if our QR code is detected

        if (str(code.payload()) == "https://bit.ly/furrybot"):
            blueLED.off()
            redLED.on()
            ledPin.on()
            print("code found! saving photo: ")
            imgname = str(snapno) + "-qr.jpg"
            sensor.snapshot().save(imgname)
            snapno = snapno + 1
            sensor.skip_frames(time = 2000) # Skip some frames to debounce
            redLED.off()
            ledPin.off()
            blueLED.on()

Credits

Alex Glow

Alex Glow

149 projects • 1593 followers
The Hackster team's resident Hardware Nerd. I love robots, music, EEG, wearables, and languages. FIRST Robotics kid.

Comments