Category Archives: coding

Raspberry Pi: how to read pin status without shutting it down in Python

From now on, sometimes I would like to publish results of internet searching… that I did NOT find. The results I wanted and I found after just after a long wandering.


 

Raspi-PGB001_reasonably_small When you work with Raspberry Pi, and you are controlling something via output port, say a relay, you can have set a status on it, i.e. you can have put it HIGH, with the usual

import RPi.GPIO as GPIO
GPIO.setmode(GPIO.GPM)
GPIO.setup(25, GPIO.OUT)
GPIO.output(25, HIGH)

Then, some times after, you are willing to know if pin 25 is HIGH o LOW. You have forgot it, or you are not you, but another person willing to know that. Problem: if you set pin 25 as input, you suddenly switch off it. So DO NOT DO this, in the same or another program:

GPIO.setup(25, GPIO.IN)
print GPIO.input(25)

because you will always get a False, at least with default pullups.

Fortunately the answer is simple: just set that pin as output… but read it!

GPIO.setup(25, GPIO.OUT)
print GPIO.input(25)

and you will get a True or a False depending on the real status.

Pomodoro pauses

pomodoro_techniqueSome time ago I stumbled across this interesting column. The conclusion is:

Of course, not every mental activity can or should be performed while walking, but this new research reinforces anecdotal evidence and other research findings that suggest being too tightly chained to our desks is bad for our minds as well as our physical health. Science shows we often have creative breakthrough when our minds are disengaged from the problem we’re wrestling with, hence the common experience of getting great ideas while relaxing in the shower.

Getting up for a walk or a jog is another way to achieve this sort of head space–after all, it worked for Einstein and Charles Darwin

It seems to me a strong reinforcement of the importance of pomodoro technique. I make use of this technique quite often, and – al least in my case – I find that its usefulness is strongly linked to the necessity to break your activity after at most 25 minutes. In fact I find it difficult to stop my task(s) and I end up getting too tired and not productive.

Posting 1-wire/RasPi data to Xively without third-party libraries – the simple way

Recently I connected to Xively (you know, the site accepting your environmental data, keeping it and letting you manage it for free – roughly speaking) with Raspberry. I just wanted to send some temperature data with the very famous  1-wire solution. Other help here.

There is a plenty of info about what software to use. I lately fell in love with python, so the language had to be that. If you look for help, you will find that Xively itself and Tinkerforge gives you some handy… pieces of python, and the same with the library owfs  but:

  • Xively gives a library with a full API, very useful but too large for my needs
  • Tinkerforge’s library is based – obviously and rightly – on the hardware they sell. Too large again.
  • OWFS shares – IMHO – the same problems as the Xively one: too large
  • all of them need to be downloaded, installed, etc.
  • really do we need a library? At the end of the day we just must send a PUT call to the HTTP(S) server

So I ended up with a personal version based on the – anyway well done – Tinkerforge version. Mine is “pure python”, using just and only the normal python installation. Probably you still will want to work to refine the code, but that could be considered a good starting point. Here it is:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket
import sys
import time
import math
import logging as log
import httplib
import json
import threading

log.basicConfig(level=log.INFO)

MIN_TEMP = -100

def read_temperature():
    # the following code will be different in your case
    tfile = open("/sys/bus/w1/devices/28-0000046ca58d/w1_slave") 
    text = tfile.read()
    tfile.close()

    lines = text.split("\n")

    if lines[0].find("YES") > 0:
        temp = float(lines[1].split(" ")[9][2:])
        temp /= 1000
        return temp
    return MIN_TEMP - 1

class Xively:
    HOST = 'api.xively.com'
    AGENT = "my-agent"
    FEED = 'FEED-ID'
    API_KEY = 'unreadeable-code-given-by-xively'

    def __init__(self):
        self.items = {}
        self.headers = {
            "Content-Type"  : "application/x-www-form-urlencoded",
            "X-ApiKey"      : Xively.API_KEY,
            "User-Agent"    : Xively.AGENT,
        }
        self.params = "/v2/feeds/" + str(Xively.FEED)

        self.upload_thread = threading.Thread(target=self.upload)
        self.upload_thread.daemon = True
        self.upload_thread.start()

    def put(self, identifier, value):
        try:
            _, min_value, max_value = self.items[identifier]
            if value < min_value:                 
                min_value = value             
            if value > max_value:
                max_value = value
            self.items[identifier] = (value, min_value, max_value)
        except:
            self.items[identifier] = (value, value, value)

    def upload(self):
        while True:
            time.sleep(10 * 60) # Upload data every ... min
            if len(self.items) == 0:
                continue

            stream_items = []
            for identifier, value in self.items.items():
                stream_items.append({'id': identifier,
                                     'current_value': value[0],
                                     'min_value': value[1],
                                     'max_value': value[2]})

            data = {'version': '1.0.0',
                    'datastreams': stream_items}
            self.items = {}
            body = json.dumps(data)

            try:
                http = httplib.HTTPSConnection(Xively.HOST)
                http.request('PUT', self.params, body, self.headers)
                response = http.getresponse()
                http.close()

                if response.status != 200:
                    log.error('Could not upload to xively -> ' +
                              str(response.status) + ': ' + response.reason)
            except Exception as e:
                log.error('HTTP error: ' + str(e))

#========================
if __name__ == "__main__":

    log.info('Start')

    xively = Xively()
    i = 0
    while True:
        i += 1
        print('reading ' + str(i))
        temp = read_temperature()
        xively.put('temperature', temp)

        time.sleep(60)

    log.info('End')

Going to Arduino from C#, Java, … string trouble

As I posted some weeks ago, if you need to work with strings (or, better, character arrays) in Arduino’s C++, coming from a friendlier development environment, things reveal to be quite hard.
There are anyway two approaches that can relief the pain:
1) An F() procedure exists, moving every declared string from the highly expensive SRAM (in Arduino UNO 2kB) to flash memory (32 kB). I used this method and solved my intermitting (and making me crazy…) problems
2) Using PString library, added by NewSoftSerial and put in official version of Arduino. It is very handy: it hands you a nice object managing a char array and allowing you to modify and search your string

Going to Arduino from C#, Java, …

So far I have spent several hours programming Arduino. It has been a very pleasant experience, because, as for many other programmers, seeing things changing behaviour after your code is an exciting sensation. Usually you just see something happening on the screen.

Anyway, first times were sometimes hard: Arduino seemed sometimes doing weird things: stopping, ignoring your code, and so on.

Arduino is programmed in C (ok, C++ if you prefer, at least in theory). As a friend of mine says: “C is well-camouflaged assembler”. So, if you are coming from languages like Java, C#, FORTRAN, Python you likely are not used to think about, for example, array length, You create new arrays, delete them, assign them to variables without any trouble. You don’t know that here in C language everything can hide a trap. In short, arrays are not dynamically managed: you must take charge of their dimension. For instance, if you write:

char arr[2];
arr = "abcdefg";

your code compiles smoothly… and at runtime your last letters will go wandering lost in space somewhere… but surely where they are not allowed to 😉

Is American DoD getting Agile?

“The purpose of theory is to predict future observations”

Martino Vallara sent me an interesting link about recent rules inside Department of Defense in the USA. In section 804 (implementation of new acquisition process for information technology systems) they state:
(2) be designed to include—
  (A) early and continual involvement of the user;
  (B) multiple, rapidly executed increments or releases of capability;
  (C) early, successive prototyping to support an evolutionary approach; and
  (D) a modular, open-systems approach.

These are hardly far  from Agile principles. You can say they are Agile principles. This new approach is interesting because DoD is [supposed to be] a quite factual institution. This lead me to think that – frequently – discussions about Agile / no Agile are a little bit abstract. An expert of practical thinking is likely teaching us something.

Uncle Bob hits

Bob Martin had published a very direct, questionable, and witty post about database history… until now. You may agree or disagree, but you cannot ignore him. It makes you think, anyway. Nowadays readings seldom do it.