Monday, July 23, 2018

119: Raspberry Pi Camera Exposure

I've tried 3 cameras: the V1 (5mpix), V2 (8mpix) and a wide-angle (5mpix). I've had trouble with exposure with all of them.

One small gripe: the raspistill command --help arg lists a zillion options without a clue about what the default values are.

But that's not my story. I want to take snaps from before dawn till after dusk and I found that the many exposure-related arguments seemed to be ineffective. But I finally discovered the silver bullet. Shutter speed (-ss microseconds). That one works.

So, I average B/W pixel values in python and adjust shutter speed accordingly. My current -ss range is (bright to dark) 500 to 4000000 microseconds (1/2000th to 4 seconds).

Tuesday, July 10, 2018

118: A Problem with Insulation

I have several IoT systems installed in farm hoophouses (used to be called "greenhouses"). Each configuration is housed in a (mostly) waterproof plastic container -- about 12" x 18" x 8". The hoophouses are environmental trouble -- often high humidity and the daily temperature can range 50F to 120F. Processors are either Particle Photons or Raspberry Pi Zero-W and nearly all include relay boards. E.g.:

6-port relay

The boards are screwed down (loosly) to 1/4" plywood -- non-conductive, but I didn't like the back side of the boards:

many nasty soldered pins

So I decided to stick masking tape on the back of the boards. At least they ere easier to handle. Like so:

Don't do this!

At least, in the case of the particular product I used and/or the temperature range, that tape was NOT an effective insulator. I've had a few "relay board failures". But today (belatedly) I proved to myself that it was the stupid masking tape. When I replaced the tape with the black electrical type my failing relay board was fixed.

Wednesday, July 4, 2018

117: Overheating: The Pi's Internal Temperature Sensor

I currently have a Pi Zero W mounted inside a farm hoophouse (i.e., one of the new plastic film greenhouses). Unless the sides get rolled-up it can get over 120F in a hoophouse on a summer day. Yesterday my Pi Zero reported 154F from inside it's sealed case -- very close to the max 70C/158F for the Arm processor spec. Anyway, I protect my Pis as folows:

In cputemp.sh
h=`hostname` # I have several Pis
while true ;
do
 a=`/opt/vc/bin/vcgencmd measure_temp`
 b=`expr "$a" : '.*=\([0-9][0-9]*\)'`
 if [ $b -gt "70" ] ;
 then
  echo $h HOT | mail -s 'Rpi-HOT HALTED' some@gmail.com
  sudo halt # must power off/on to restart
 fi
 if [ $b -lt "55" ] ;
 then
  sleep 300
 else
  sleep 60
 fi
done


And in crontab
@reboot bash ...(your path).../cputemp.sh

Which means the above shell file will be executed whenever the Pi restarts.

P.S.: About overheating -- while my Pi Zero seemed to be working up to 70C, it became erratic at 66C/150F. while it still sent data to a web page, it stopped being able to snap a new image with the PiCamera/raspistill.

Monday, April 30, 2018

116: Python Threads

This isn't my usual sort of interest. And I'm not very fond of Python -- too many ways of doing the same thing (Go golang!). Anyway. I wanted to program an async task that accepts input that might modify what's happening in the main loop. I'm only posting this code snippet because it took me 20-ish Googles and a dozen source tweaks to get this to work. And the posted examples are way more arcane.


# Simple Python Threading example that puts blocking 
# I/O in its own asynchronous thread
import os, time
import threading

rv = '' # to pass data to the loop

def ck_file() : # the I/O thread
    global rv

    while True :
        if os.path.exists('cmd') :
            f = open('cmd', 'r')
            rv = f.readline()
            f.close()
            os.remove('cmd') # so it's only reported once
        time.sleep(5)

t = threading.Thread(target=ck_file) # black magic!
t.daemon = True # needed to cause the thread to exit

t.start()       # never runs without this

# main loop
ct = 0
while True :  # where you'd do something useful
    time.sleep(10)
    ct += 1
    print "ct=", ct
    if rv != '' : #data entered
        print "RV:", rv
        rv = ''   
    if ct == 10 : break # it's just an example, after all


Note: the daemon line is important. Probably should be the default. Otherwise the thread never exits.

So, in the spirit of an oyster turning a grain of sand into a pearl I have posted this pearl (?) caused by my aggravation.

Monday, April 9, 2018

115: SSH over the Internet!
(why didn't I find this sooner?)

There are several services available. I chose remot3.it. Their web page leaves certain info gaps (duh) but with my daughter's help I got 3 Pi Zeros connected. Just like local SSH! Unlike just replacing files you can interactively update cron or edit a file with nano. And the "private" account is free (so far). Unfortunately, you have to go through several web clicks to get a sort-of "session ID number" (my term) to do a remote SSH connection. Still, very nice.

Tuesday, March 6, 2018

114: A Better Pi Zero W (IMHO)

114: A Better Pi Zero W (IMHO)

So far I've purchased 3 Pi Zero Ws and will doubtless buy more. But this doesn't mean that I like everything about their physical layout. Here's a picture contrasting the Zero with a Particle Photon (which is very similar to an Arduino Nano or Micro).

Photon on left, Zero on right

Obviously, the Zero has to be bigger. I accept that (sort of). But I prefer the Arduino/Photon layout for 2 main reasons:

a. The GPIO pins straddle the breadboard halves. Very handy. No stiff ribbon cable required.

b. Instead of the side mount, the micro USB points out the end so a compact enclosure (e.g., hand-held) setup is possible. As is, the minimum inside width of a Pi Zero case is 2.5".

Here's my layout plan:


Note that I've left off the 2nd USB and HDMI plugs. They could be added via a daughter board connected through the above "accessories" slot. For the daughter board I'd provide a full-sized HDMI and 2 USBs.

Comments?

Re: living with current reality— Anyone know of a compact/right angle micro USB plug?


Monday, January 29, 2018

113: Better Breadboard? See post 62 at http://dicks-photon-arduino.blogspot.com/

Just pie-in-the-sky, of course.

Sunday, December 31, 2017

112: Display Pi Camera Image over Mac Terminal/SSH
(simpler would be nice)

On the Pi install the feh command:


pi$ sudo apt-get update
pi$ sudo apt-get install feh

In Mac Terminal:

Find the name of your Pi with something like the "Ip Scanner" app.

mac$ ssh -X pi@yourPiName.local # Connect to the Pi using X11

Enable X11 file transfer on the Pi:

pi$ sudo nano /etc/ssh/ssh_config

Change this line:

#  ForwardX11 no
to:
ForwardX11 yes

Save and reboot the Pi.

Be sure XQuartz is running on the Mac -- then in Terminal (SSH as above) do:

pi$ feh yourImageFile

The image will display in a new Mac window. To get rid of it, type ESC. 

pi$ man feh

Will hint at how the feh command works.



Tuesday, April 4, 2017

111: Particle Pi Bugs, Reprise

I've been working on other things and have ignored the Pi lately. But today (Apr 4) I decided to see if Particle's Pi interface had changed (i.e., was fixed). Spoiler! This is long and ugly.

So I logged into my Pi.

1. According to the "ps" command the Particle device process was running.
2. So I went to the WebIDE (https://build.particle.io/build/...) and tried to recompile a simple test sketch.
3. As I expected, this returned a "request timed out" error message.
4. So on my Pi I executed "sudo particle-agent restart". Ps now lists (the "?" stands for the device ID):

13591 ?        S     11:30 /var/lib/particle/devices/?/firmware.bin -v 70
30494 ?        Sl     0:00 /usr/bin/ruby /usr/bin/particle-agent-service (...)
30498 ?        S      0:00 /var/lib/particle/devices/?/firmware.bin -v 70

So now I appear to have 2 copies of this old firmware.bin running:

-rwxr--r-- 1 root root 664576 Mar 10 19:00 /var/lib/particle/devices/?/firmware.bin

So I do "kill -9 13591". That worked.
5. Then I tried another WebIDE compile. Same error.
6. Still wasting my time, I try this:
root@myPi:/home/pi# particle-agent setup
Let's connect your Raspberry Pi to the Particle Cloud!

You are already logged in as xyz@abc.com.

Do you want to stay logged in as this user? |yes| yes
How do you want your device to be labeled in the Particle tools?
Name: |pi4| 
Generating RSA private key, 1024 bit long modulus
...++++++
.......++++++
e is ??? (0x10001)
writing RSA key
writing RSA key
⠏  Claiming the device to your Particle account 
Particle cloud error. Name already in use

That ended in an error message but -- wait for it -- it worked. Well, not quite. I have 2 processes again:
30498 ?        S      0:00 /var/lib/particle/devices/?/firmware.bin -v 70
...
30583 ?        S      0:00 /var/lib/particle/devices/?/firmware.bin -v 70

So? kill -9 30498. Worked. And I got sensible output to a file.
7. So, I try another compile. Timed out.
8. Back to "particle-agent stop" . Which stops the Ruby process but not the firmware.bin.
9. What else is left? Oh, yes: reboot!
10. After reboot a new compile works. Worked several times. But for how long?
11. Not long if you try to "fix" Particle's problem (my view) with running as root. I first tried this added above setup():

void uid_fix() {
    setuid(SAFE_UID); // don't be ROOT!
    setgid(SAFE_UID);
    chdir(MY_PATH);
}

STARTUP( uid_fix() );

Didn't work. Output file (written by my program) still belonged to root.
12. So, I move the setuid/setgid into setup(). That's when firmware.bin stopped being changed when I recompiled -- though the WebIDE thought it worked.
-rwxr--r-- 1 root root 648192 Apr  4 11:24 /var/lib/particle/devices/?/firmware.bin

Flashed new code at 11:36, file is still the 11:24 compile.
13. So, now I suppose I have to go through process kill, "particle-agent setup" or reboot to get a WebIDE "flash" to actually work again. And the "root" problem hangs on.

Friday, December 16, 2016

110: More about Particle-Agent

Particle got back to me. You can see the conversation at 

https://community.particle.io/t/linux-versus-particle-agent/27984/7
and later--
https://community.particle.io/t/feedback-raspberry-pi-particle-agent-structure-complaint/28124

Turns out an empty loop() function loops as fast as it can -- 100% of one core (in a 4-core RPi Bv3). And also, my RPi might have been fried except for the code below.


This file is started at system boot by this line in crontab:

@reboot sh bin/cputemp.sh
==================
while true ;
do
 a=`/opt/vc/bin/vcgencmd measure_temp` # returns Celsius
 b=`expr "$a" : '.*=\([0-9][0-9]*\)'`
 if [ $b -gt "70" ] ; # 160F
 then
  echo 'CPU HOT!' | mail -s 'DicksRpi4-HOT' myemail@gmail.com
  sudo halt # NOTE: have to restrart manually
 fi
 if [ $b -lt "55" ] ; # 130F
 then
  sleep 300 # sleep longer if under 130F
 else
  sleep 60
 fi
done
===============
Also, I changed the Particle code, mainly to add a delay inside the loop function. Plus I got rid of most of the C++ crap.

// Danger! This thing is running as super-user (root)
#include <stdio.h>
#include <unistd.h>

#define SAFE_UID 1000 // i.e., the "pi" user built into RPi Linux
#define MY_PATH "/home/pi"
char Rstr[100];
int Ct = 0;

void setup() {
    Particle.variable("dhpi1v", Rstr, STRING);
    Particle.function("dhpi1f", pifunc);
}

void loop() {
    delay(10); // kludge to keep the empty loop from being a cpu hog
}

int pifunc(String cmd) {
    int arg = cmd.toInt();
    char file[100];
    FILE *fp;
    
    ++Ct;
    sprintf(Rstr, "Call count = %d, Arg = %d\n", Ct, arg);
    sprintf(file, "%s/pi_out.txt", MY_PATH);
    fp = fopen(file, "w");
    fputs(Rstr, fp);
    fclose(fp);
    chown(file, SAFE_UID, SAFE_UID); // otherwise belongs to root
    return Ct;
}

The delay(10) was supposed to reduce CPU load to about "1%" but my tests show 12%.
Before I added the delay statement particle-agent was raising my RPi's temperature about 1C every 3 minutes. Maybe I need heat sinks (I had some but can't find the tiny package). And maybe when an RPi gets too hot it halts by itself. Anyone know?

NOTE: I have since changed the loop delay to 25ms. Even so, my (modified) sketch above has used 192 minutes of CPU time in ~3 days.

Thursday, December 15, 2016

109: RPi Linux vs. Particle-Agent
(there's a culture clash)

When I installed particle-agent on 2 of my RPis I didn't realize that they would run in the background as "root" (superuser). I suppose the rationale is so an Arduino-like sketch program could access the GPIO pins. However, there is a better way: google "raspberry pi /dev/gpiomem".

I had no problem installing their particle-agent package. I did on 2 RPis: a Bv2 (40 pins) and a Bv3 (quad processor). I thought I could just use gcc to compile, but how to get to Particle libraries? Turns out you can just use the "Web IDE" -- like for a Particle Photon. Once you install and run particle-agent your RPi devices will show up on the web page like other devices. Anyway, I then wrote the following simple program:

#include <iostream>
#include <fstream>
using namespace std;

char Rstr[100];
int Ct = 0;

void setup() {
    Particle.variable("dhpi1v", Rstr, STRING);
    Particle.function("dhpi1f", pifunc);
}

void loop() {
}

int pifunc(String cmd) {
    int arg = cmd.toInt();
    ++Ct;
    sprintf(Rstr, "Call count = %d, Arg = %d\n", Ct, arg);
    ofstream pifile;
    pifile.open ("/home/pi/pi_out.txt"); // belongs to "root"
    pifile << Rstr;
    pifile.close();
    return Ct;
}

Note the fully qualified path for the output file. Particle-agent doesn't know about your home directory.  Here's my shell script to get results (from my Mac Terminal app):

id=???
ac=???
var=dhpi1v
fun=dhpi1f
arg=123
echo Call Pi function:
curl https://api.particle.io/v1/devices/$id/$fun -d access_token=$ac -d args=$arg
echo
echo Get Pi variable:
curl  https://api.particle.io/v1/devices/$id/$var?access_token=$ac
echo

Shell results:
$ sh pitest
Call Pi function:
{
  "id": "???",
  "last_app": "",
  "connected": true,
  "return_value": 6
}
Get Pi variable:
{
  "cmd": "VarReturn",
  "name": "dhpi1v",
  "error": null,
  "result": "Call count = 6, Arg = 123",
  "coreInfo": {
    "last_app": "",
    "last_heard": "2016-12-13T16:35:58.241Z",
    "connected": true,
    "last_handshake_at": "2016-12-13T16:03:52.588Z",
    "deviceID": "???",
    "product_id": 31
  }
}

Note: I don't think much of Particle's inconsistently formatted output. And yipe! As I mentioned above, the file I wrote should not belong to root.

$ ls -l:

-rw-r--r--  1 root root     26 Dec 13 17:08 pi_out.txt

So I added the following to my sketch:

#include <sys/types.h>
#include <unistd.h>

#define SAFE_UID 1000 // i.e., the "pi" user built into RPi Linux
. . .
int Euid;
int SetRet;

void setup() {
    SetRet = setuid(SAFE_UID); // don't be ROOT!
    Euid = geteuid();
. . .
// in pifunc

sprintf(Rstr, "SetRet = %d, Euid = %d, Call count = %d, Arg = %d\n", SetRet, Euid, Ct, arg);

Anyway, you'd think that setuid() would have fixed the permissions problem. But no such luck. Still belongs to root.

Two other problems (yes, I know the "Particle Pi" is beta):
1. When I changed the source program (as above), downloaded it and ran it the output message didn't change. After much useless retrying I went looking for the files the Particle installed (good old Unix/Linux, everything is a file). So I found a directory whose name is my Pi's ID# and that contains a file named firmware.bin.

/var/lib/particle/devices/7ab...MyID/firmware.bin

And the directory permissions were rwx------.

So, apparently, the downloader can install a firmware.bin but can't over-write it afterwards. So I unilaterally changed them to rwxrwxrwx (probably not optimal). Now I could recompile.

2. While flailing about with the above problem I decided to download the sample program on my RPi Brev3. I got the same results except the up-to-date output was displayed. But then it got interesting. This RPi is 50 miles away at the moment. I use it to monitor Particle Photons installed at my granddaughter's farm. It runs off UPS and hasn't been down in months. But I try to be careful so I have a crontab task that checks the RPi's on-chip temperature sensor every few minutes. The sustem generally runs at about 110F. If it gets to 130F the RPi sends me an email warning. And at 140F it executes halt. Guess what? 20 minutes after running my test program I got the "RPi HOT!" email and it has been down ever since. I can't blame particle-agent just yet, but one thing I know: CPU load raises the sensor's temperature. I have a favorite test program that I have used for 30 years. It is now in Python and it computes PI to as many places as you specify. So PI to 10,000 places raises the temp a few degrees. That only uses a single processor (probably). Anyway, this weekend I will visit this RPi and find out.

Friday, November 11, 2016

108: Particle.io Cloud Interface for Raspberry Pi
-- Revised 12/10/2016 --

Among my "IoT computers" or "smart controllers"* (needs a better name) aI have 7 processors from Particle: 1 Core (now superseded by Photons), 5 Photons and 1 Electron.  Particle Photons are rather like souped-up Arduinos with built-in WIFI and cloud services. This cloud provides not only the expected variable/function and publish/subscribe services but other handy UNIX-like functions like date/time. Since the summer of 2015, I have had 2 Photons operating in the real-world in my farmer granddaughter's semi-automated hoop house. I had planned to use Raspberry Pi's for this but the Photon/cloud was just too handy. However, an RPi keeps track of things from 100 miles distance.

Anyway, back in August, I emailed Particle.io support that they should provide their cloud interface for the Raspberry Pi. I was probably not alone in this. And now, I just signed up for their beta-test RPi cloud interface. It should be very convenient for me and even if 1% of the 10M RPi's sign on, it should be a good deal for Particle.

REVISION: Well, it's been a month+. Particle has yet to provide the obvious (to me) cloud interfaces for the RPi that match what I can do with a Particle Photon. Like, how to publish to the cloud, subscribe to the cloud, call a cloud function, read a cloud variable? Disappointing! But see post 109.

---------
* I also have 4 Raspberry Pi model B (from earlyish to most recent) and 4 Arduino Nanos. To those not in-the-know, an RPi B is $35 (well, $50 with flash card, etc.); my Nanos cost $7 and Photons are $19. My Particle Electron (Photon with built-in cell modem) was time and $ wasted, for me.

Wednesday, October 26, 2016

107: Controlling a Relay Switch

In the previous post (106), I mentioned using a relay to reduce power drain when operating a stepper motor with the EasyDriver. I covered switches before in post 94. There is yet more at http://dicks-photon-arduino.blogspot.com/, post 45.

There are a couple confusing things about these relays:

1. These devices are "normally open". Pin settings are backwards:
      GPIO.output(Relay, GPIO.HIGH) # turn OFF
      GPIO.output(Relay, GPIO.LOW) # turn ON

2. On the Raspberry Pi there is a second gotcha. See image:

Note that I used the upper 2 of the 3 relay connectors (explained in previous posts). Yesterday, I connected a relay like the picture above. But instead of switching, it was always ON! I tried it with an Arduino -- worked fine. Then I realized that I had connected my breadboard's 5V rail to VCC on the relay instead of 3.3V. The GPIO pin only does 3.3. A dumb, but easily made mistake. When I changed to the 3.3V rail everything worked.

Note: I used the cheap non-opto-isolated relay in this case because I was only switching 5V/.5amp.

Wednesday, October 12, 2016

106: EasyDriver + Linear Stepper Motor
-- Finally --

I've long lost track of how many failed attempts I've made to get this to work. Here's my successful EasyDriver wiring:
The messy setup

Here's some Python code that works for me.
Note: I had to install PWM -- see
http://raspi.tv/2013/rpi-gpio-0-5-2a-now-has-software-pwm-how-to-use-it

import RPi.GPIO as GPIO
import time, sys
GPIO.setmode(GPIO.BCM)
STEP = 22
DIR = 17
GPIO.setup(STEP, GPIO.OUT)
GPIO.setup(DIR, GPIO.OUT)

sp = GPIO.PWM(STEP, 800)# 800 seems faster than 500 ???

# usage: sudo python this_file.py direction steps
dir = sys.argv[1]        # f or b -- forward or back
steps = int(sys.argv[2]) # max on my linear screw about 700

def spin(dir, steps):
  GPIO.output(DIR, dir)
  while steps > 0:
    sp.start(1)
    time.sleep(0.005) # smaller delay looses steps ???
    steps -= 1
  sp.stop()
  return True

if dir == "f":  # i.e., "forward" away from the motor 
  dir = False
else:
  dir = True
spin(dir, steps)
print "Done"
GPIO.cleanup()

More about the linear motor, see:
http://dicks-photon-arduino.blogspot.com/, post 46.

Not represented in the above code: I added a relay switch for the 5v power to the motor. Otherwise steppers draw current constantly (and the motor housing can get hot). Too bad that the EasyDriver doesn't work like the ULN2003 -- which allows you to turn the 4 motor leads off without an added switch. Re relays: I got 5 single-relay devices on the cheap from Amazon; they lack opto-isolation and have no mounting holes -- but cheap.

Sunday, October 9, 2016

105: RPi Stepper Motor
-- revised sleep time --

After much pain (read: time wasted) I have a half-assed program that runs the cheapo 28BYJ-48 motor (5V DC with ULN2003 Driver Board).

Here's some Python:


import RPi.GPIO as pin, time, sys

pin.setmode(pin.BCM)

Cpin = [6,13,19,26] # to UNL2003 in1, in2, in3, in4; external 5v/GND

pin.setup(6,pin.OUT)
pin.setup(13,pin.OUT)
pin.setup(19,pin.OUT)
pin.setup(26,pin.OUT)

# rotate clockwise
Cw = [[1,0,0,0],[1,1,0,0],[0,1,0,0],[0,1,1,0],[0,0,1,0],[0,0,1,1],[0,0,0,1],[1,0,0,1]]
# counterclockwise
Ccw = [[0,0,0,1],[0,0,1,1],[0,0,1,0],[0,1,1,0],[0,1,0,0],[1,1,0,0],[0,0,0,1],[1,0,0,1]]

def motorOff(): # so it stops drawing current
pin.output(Cpin[0], 0)
pin.output(Cpin[1], 0)
pin.output(Cpin[2], 0)
pin.output(Cpin[3], 0)

def moveCw(steps):
for i in range(steps):
for j in range(8):
for k in range(4):
pin.output(Cpin[k], Cw[j][k])
time.sleep(0.002) ### Changed! .001 caused missed steps

def moveCcw(steps):
for i in range(steps):
for j in range(8):
for k in range(4):
pin.output(Cpin[k], Ccw[j][k])
time.sleep(0.002)
s = int(sys.argv[1])
print s

# Full rotation approx. 128.3. How do you get an exact number?

print "cw"
moveCw(s)
time.sleep(2)

print "ccw"
moveCcw(s)

motorOff()

pin.cleanup()

The following bits also work for counterclockwise. But which (if either) is better?
[[1,0,0,1],[0,0,0,1],[0,0,1,0],[0,1,1,0],[0,1,0,0],[1,1,0,0],[0,0,0,1],[1,0,0,0]]

I spent even more time trying to get a linear stepper motor with the (so-called) EasyDriver to work. No luck. I have 2 sets of this stuff and both work with an Arduino. See http://dicks-photon-arduino.blogspot.com/, posts 43 and 46.

Thursday, September 22, 2016

104: Can't Get Pi to Control a Stepper Motor with Easydriver.

There are examples on the Internet claiming to make this work, but my attempts have not. I got the setup to work with an Arduino without horrible effort. See my blog entry—

http://dicks-photon-arduino.blogspot.com/

Post 46.

Help!

Friday, August 26, 2016

103: Keeping a Rpi Up and On Line!
-- 3 Weeks Later --

What I've learned since this post:
1. When I thought my Pi was down it was only the WIFI that had stopped working (and no blinking of the USB WIFI dongle).
2. The steps I outlined below didn't work, longer term.
3. I swapped my generation 1 Pi B to my new gen 3. Still up: 2 weeks without a failure and without the steps listed below. However, its WIFI dongle is different. I need to swap them to see whether the problem is the dongle.

This didn't help (nor hurt):
I have a Pi powered through UPS that is programed through cron to monitor 2 Particle Photons that are doing real work. But, even though scheduled tasks happen every few minutes the dumb Pi seemed to go off line (sleep?) after a day or so. So I went looking for voodoo incantations to correct this problem. Here are 2 that I tried:

In /etc/kbd/config changed the line--
POWERDOWN_TIME=30 to value 0 (= never)

In /etc/lightdm/lightdm.conf after [SeatDefaults] added--
xserver-command=X -s 0 -dpms

One (both?) of these seems to have worked. 'No idea which -- or if they are black magic.

Pssst! Linux is a mess.

Friday, August 5, 2016

102: About My Grayscale Image Blog Page (#34)

The raspistill command for the Pi camera has 100-ish command line options but (oddly) no way to produce a black and white image file. It took me about 10 minutes to come up with a kludge to convert RGB to grayscale. Then I made a blog post about it.

Here's the mystery: With over 100 posts in this blog what is the enduring allure of post #34? Over 6% of my page views still go to that 2 year old entry. And here I thought I'd written about seemingly more important issues.

Anyway, here's a more interesting snippet of Python for a security cam app:

import subprocess
import os
import StringIO
from PIL import Image

threshold = 10 # interesting pixel value diff
numDiffs = 20  # number of diff pixels to assume motion
wide = 120     # size of test images (arbitrary)
high = 90

# Capture a small test image (for motion detection)
def captureImage():
  command = "raspistill -w %s -h %s -t 5 -e bmp -o -" % (wide, high)
  imageData = StringIO.StringIO()
  imageData.write(subprocess.check_output(command, shell=True))
  imageData.seek(0)
  im = Image.open(imageData).convert("L") # convert to B/W!
  buffer = im.load()
  imageData.close()
  return im, buffer

def compareImage(buff1, buff2): # latest vs. previous image
  changedPixels = 0
  for x in xrange(0, wide):
    for y in xrange(0, high):
      pixdiff = abs(buffer1[x,y] - buffer2[x,y])
      if pixdiff > threshold:
        changedPixels += 1
  return (changedPixels > numDiffs) # True return indicates motion

... (code that calls captureImage & compareImage)



Tuesday, July 5, 2016

101: My New Raspi Model B 3 -- and a Gotcha!
-- revised again --

Back at post 2 of this blog I told about running pi.py -- my little Python program that computes Pi to 10,000 places. My first April, 2013 model B took 4 seconds. The new one: 1.4. That timing is for the 2nd execution (with the Python app already loaded in memory). Same deal on my new-ish iMac (quad 3.1ghz, i5): 0.17 seconds.

Nice. However, I've been bitten by the increased power requirement of this (release 3) model. I fired it up with a 2.1 Amp power source, 32GB micro SD and with the following attached: HDMI cable to 7" monitor, USB wifi dongle and USB keyboard. In this configuration the red light comes on but the SD is never accessed (green LED stays dark). It boots OK with any of the plug-ins removed. After initial power-up the removed device can be added. I failed to read about the need for a 2.5 Amp source.

Later: I got the 2.5amp converter. Better. It not only boots up with everything connected, it stays up, too (accessing the new Raspi via ssh always failed after an hour or so with the 2.1 amp supply -- I didn't get why).

Later: just got a new power strip that besides "surge protection" has 4 USB power outlets rated at 2.4 amps each. Guess what? My new Pi appears to not quite require 2.5 amps.

Monday, June 13, 2016

100: Avoiding Solder
-- revised, again --

This is a recurring theme with me. I hate soldering, especially teenie-tiny, close together connections. So I keep looking for alternatives -- like screw-down connectors, circuit paint -- and just now "Wire Glue." See my posts 59, 93 and 96.

What's wrong with Wire Glue? a) it was hard to mix up (settled in the bottom), b) very weak "glue"; but here's the real problem:

Here's the test: I measure a known resistor. In my test below, a reading on a 220 Ohm resistor.
Big surprise, it reads .220k Ohms

And here's a reading for a heavy 3/4" line of Wire Glue (on inkjet printer paper):
Wow! 611 Ohms

This stuff should be called "liquid resistor." You will add resistance even if you glue 2 wires together with no apparent gap. PS: a foot long jumper wire reads .0.

Meanwhile, on the insulation front I have tried a couple glue/caulk products. 

Above, the glued wire-ends are both about 1mm apart and after 24 hours curing there is no current leaking between them. I made this test because I felt that red tube was the better insulator (they are the same). The main problem involves the tubes both drying out so that the screw top is plugged within a week or so. Also, the green tube goop sets harder.

More about glue:
My experience with "super glue": not an insulator. And about epoxy: probably not surprising is only a little stronger resistor than the above Wire Glue (and much stronger glue).

black tube 'contains metal'