BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Dalek

Wed Apr 23, 2014 8:14 am

Edit: I'm updating this post with my latest update at the bottom of the post:

Latest Update:

After much playing around with code on my pocketPi I decided it was really time to prove that my web-interface works on the Dalek. (especially as I plan to take it along to the Croydon Jam with me this Saturday)

I still haven't sorted out the battery so I had to find a dc power supply
I connected everything up and tried my web interface. Right forwards and left forwards were reversed, a simple fix by changing the PHP script (or so I thought). Reversing proved to be more problematic, the Dalek is so top heavy that when I reversed it fell over. I think I'll need to add speed control to the reverse options but I'm not sure if I'll have time to before Saturday.

I have added servos for the turret rotation and eyestalk inclination/declination but haven't tried to program them yet.
Last edited by BMS Doug on Wed Oct 22, 2014 11:33 am, edited 14 times in total.
Doug.
Building Management Systems Engineer.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Wed Apr 23, 2014 8:14 am

Progress so far: (I'm keeping this post updated with all of my posts)

The Pi arrived on Monday, I spent Monday night setting it up and playing with LEDs and my Tablet.

Connected Pi to TV, picked Raspbian from NOOBS install list (a NOOBS card was £1 extra on purchase price of Pi) and ran thru options, installed OK. Found IP address of Raspberry pi.

checked SSH, turned Pi off remotely with raspi-r.
turned Pi on and off a few times, panicked a bit when I couldn't see HDMI output, turned Pi off remotely with raspi-r, realised that TV had to be looking at the HDMI input when the Pi turns on, stopped panicking.

Setup i2c connection to slice of Pi/o and setup a LED (+1k resistor) on I/O a0

Turned LED on and OFF using ConnectBot
Updated pi

Downloaded a bunch of android apps for connecting to raspberry pi:
ConnectBot
Raspi-R
Raspi SSH
GPIO tool for Raspberry Pi

Installs onto raspberry pi:
adafruit webIDE

ConnectBot: connected OK, Default font size was very small, found option to make it readable.

Raspi-R: Connected OK, sends commands only. fixed list of commands.

Raspi SSH: Didn't connect: sends commands only. user has to create commands which are then available to re-send as desired.

GPIO tool for Raspberry Pi: connected OK, didn't seem to work with slice of pi/o (no i2c support)

adafruits webIDE: doesn't work well with the tablet, some functionality but terminal tasks suffer.
Works nicely from the laptop (but not as convenient)

<Thu May 01, 2014 4:02 pm >
Thanks BBUK,

That will be very useful.

Status update: waiting on parts still.

I'm still waiting on my L298N H-Bridge before I can get the wheels rolling on this (pun intended)

I've been trying to get my slice of Pi/o working with my Ultrasonic detector without much progress (or much effort put in, too much going on unfortunately). I can use it to turn LED's on and off so It'll be fine for controlling the L298N (I'm a bit worried after reading the post about the guy blowing up his Pi after following the u-tube video so the Slice of Pi is a nice protection).
Edit: all working now but I2C communication is too slow for great accuracy with the ultrasonic rangerfinder (it works, as long as you aren't close and don't need pinpoint accuracy).

My UBEC arrived so I'll probably load test it at the weekend (I'm all for cheap electronics, until they blow up my cheap computer). Edit: load test Complete, 3 hrs at 9 supply running 2 motors, not a flicker, stable 5.227v constantly.

My Wifi dongle showed up and took all of 5 minutes to setup (much of which was spent locating the WIFI passcode).
I've now only got one wire connected to the Pi (power) and I'll be able to drop that out after I'm convinced the UBEC will hold.
(I have a 4 Amp hour, 7V2 battery that used to be an emergency light battery, and a charger from the same source, recycling may be our friend, if the battery is any good).

<Sat May 03, 2014 8:44 pm >
Struggling a bit with getting the HC-SR04 working with the slice of Pi/O...

I can't tell why but it throws up an error but only when the input is connected to the echo output from the HC-SR04

it doesn't give this error when the echo pin is disconnected and a pushbutton is connected in the same location.
I have tried this with a 10K resistor pulling the Echo pin to ground and also with the resistor disconnected.
I have run the program with the pushbutton already pressed and then released once the program is running. (still doesn't replicate error)

<Sat May 03, 2014 9:23 pm>
Ok, thats pinned it down, thanks. confirmed by adding a delay between the two loops and testing with a push button.
Good to know that the reason I haven't been able to get this to work is the bus speed and not my programming.
I'll attach any Ultrasonic sensors I use direct to the GPIO pins instead of the slice of Pi/O

note: yes this does work with objects further away, just not close objects
so this setup is not suitable for collision avoidance application but might work in an application that can tolerate a greater distance, but accuracy may suffer due to communication delays.

<Mon Jun 02, 2014 2:07 pm >
Its been awhile since I've had anything to write (waiting on parts and some re-decorating at home) but I've actually made good progress recently.

I was waiting for some female to female wires to arrive but got tired of waiting (due next week) so I ordered some female crimp pins, connector housings and ribbon cable. most of my order arrived OK but Relchron aren't talking to me about the item that didn't arrive are sending out as replacement for the incorrect item (5 pin connector housing, they sent a servo connection lead instead).


I can now make ribbon cables as desired to the length I want and connect them to my devices as desired.

I have currently got my Pi connected to an i2c 16 channel PWM breakout board and have been playing with getting it to drive around a bit.

currently it is driving around via keyboard commands from my laptop, no speed control implemented yet.

remaining tasks:
(in order of priority)
communicate from android device
switch to battery power
connect turret servo
fit it into the (dalek) case - underway
add speed control
add sounds / voice
add ultrasonic distance measurement
add magnetometer
add gyroscope accelerometer
configure for autonomous mapping

<Sun Jun 08, 2014 7:21 am>
I dug into the loft last night and found my Dalek shell, then i went mad with the Stanley knife and glue gun and have now mounted my wheels inside the base of the dalek shell.

I tried to consolidate all my power using the L298N's on board 5v output but it wasn't able to hold the load so I wired in the UBEC that I had previously tested.
This still couldn't hold the load (possibly a power supply issue) when I changed motors from forward to reverse the pi momentarily dropped out. Slowing the motors, adding a stop position and a time delay between each command resolved this.

I should probably start a blog site to host all the pictures I took.

<Sun Jun 08, 2014 12:22 pm>
OK Blog post made, lots of pictures and a short video clip there.
Last edited by BMS Doug on Sun Jun 08, 2014 12:25 pm, edited 13 times in total.
Doug.
Building Management Systems Engineer.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Wed Apr 23, 2014 8:15 am

Reserved for future updates
Doug.
Building Management Systems Engineer.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Wed Apr 23, 2014 8:15 am

reserved for more updates
Doug.
Building Management Systems Engineer.

User avatar
DougieLawson
Posts: 39563
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Dalek

Wed Apr 23, 2014 8:19 am

Here's one to play with while you're pondering.

Code: Select all

#!/bin/bash

clear

function colour () {
   echo "\e[$1m$2\e[0m"
}


colourBlue=34
colourYellow=33
colourWhite=37
colourReset=0

dalek=$(colour $colourYellow "        ___\n")
dalek=$dalek$(colour $colourBlue "D")
dalek=$dalek$(colour $colourWhite ">=G===")
dalek=$dalek$(colour $colourYellow "'   '\n")
dalek=$dalek$(colour $colourYellow "      /_____\\\\\n")
dalek=$dalek$(colour $colourYellow "     |=======|\n")
dalek=$dalek$(colour $colourYellow "     |=======|\n")
dalek=$dalek$(colour $colourWhite " )--/")
dalek=$dalek$(colour $colourYellow "]IIIIIII[\n")
dalek=$dalek$(colour $colourYellow "     |_______|\n")
dalek=$dalek$(colour $colourYellow "     C O O O D\n")
dalek=$dalek$(colour $colourYellow "    C O  O  O D\n")
dalek=$dalek$(colour $colourYellow "   C O   O   O D\n")
dalek=$dalek$(colour $colourYellow "  C_O_ __O____O_D\n")
dalek=$dalek$(colour $colourWhite "  [_____________]\n")
dalek=$dalek$(colour $colourReset " ")

echo -e "$dalek"
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All fake doctors are on my foes list.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Wed Apr 23, 2014 8:59 am

DougieLawson wrote:Here's one to play with while you're pondering.
:D Thanks,

I'll run that tonight, once I get access to the TV (but I can see what you've done there).

I'm mostly running headless at the moment.
Doug.
Building Management Systems Engineer.

User avatar
DougieLawson
Posts: 39563
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: Dalek

Wed Apr 23, 2014 9:10 am

I've also got the Dalek's arch enemy's transporter.

Code: Select all

#!/bin/bash

clear

function colour () {
   echo "\e[$1m$2\e[0m"
}


colourBlue=34
colourWhite=37
backBlue="5;34;44"
colourReset="0"

tardis=$(colour $colourBlue "  ____[")
tardis=$tardis$(colour $backBlue ".")
tardis=$tardis$(colour $colourBlue "]____\n")
tardis=$tardis$(colour $colourBlue " [")
tardis=$tardis$(colour $colourWhite "POLICE  BOX")
tardis=$tardis$(colour $colourBlue "]\n")
tardis=$tardis$(colour $colourBlue "  |¯¯¯¯¯¯¯¯¯|\n")
tardis=$tardis$(colour $colourBlue "  |[")
tardis=$tardis$(colour $colourWhite "##")
tardis=$tardis$(colour $colourBlue "] [")
tardis=$tardis$(colour $colourWhite "##")
tardis=$tardis$(colour $colourBlue "]|\n")
tardis=$tardis$(colour $colourBlue "  |---------|\n")
tardis=$tardis$(colour $colourBlue "  |[  ] [OO]|\n")
tardis=$tardis$(colour $colourBlue "  |---------|\n")
tardis=$tardis$(colour $colourBlue "  |[  ] [  ]|\n")
tardis=$tardis$(colour $colourBlue "  |---------|\n")
tardis=$tardis$(colour $colourBlue "  |[  ] [  ]|\n")
tardis=$tardis$(colour $colourBlue "  |_________|\n")
tardis=$tardis$(colour $colourBlue " /___________\\\\\n")
tardis=$tardis$(colour $colourBlue "[_____________]")
tardis=$tardis$(colour $colourReset " ")

echo -e "$tardis"
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All fake doctors are on my foes list.

BBUK
Posts: 142
Joined: Tue Dec 18, 2012 10:34 am

Re: Dalek

Thu May 01, 2014 11:09 am

Howdy.

A co-incidence but I am working on a TTS dalek voice for a bit of fun (and for one of my wife's kids in her primary school class).

It uses espeak (but modified to have a digital implementation of the 30hz ring modulation and diode clipping of the BBC analogue device). I can best describe the resulting voice as passably dalek-y(!) I am working on further improvements on the sound (probably by forcing phoneme translation for certain key words).

I'll drop the code off on this thread when I have finished.

BBUK

@DougieLawson: We appear to be posting on many of the same threads. Not stalking you, honest!

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Thu May 01, 2014 4:02 pm

Thanks BBUK,

That will be very useful.

Status update: waiting on parts still.

I'm still waiting on my L298N H-Bridge before I can get the wheels rolling on this (pun intended)

I've been trying to get my slice of Pi/o working with my Ultrasonic detector without much progress (or much effort put in, too much going on unfortunately). I can use it to turn LED's on and off so It'll be fine for controlling the L298N (I'm a bit worried after reading the post about the guy blowing up his Pi after following the u-tube video so the Slice of Pi is a nice protection).
Edit: all working now but I2C communication is too slow for great accuracy with the ultrasonic rangerfinder (it works, as long as you aren't close and don't need pinpoint accuracy).

My UBEC arrived so I'll probably load test it at the weekend (I'm all for cheap electronics, until they blow up my cheap computer). Edit: load test Complete, 3 hrs at 9 supply running 2 motors, not a flicker, stable 5.227v constantly.

My Wifi dongle showed up and took all of 5 minutes to setup (much of which was spent locating the WIFI passcode).
I've now only got one wire connected to the Pi (power) and I'll be able to drop that out after I'm convinced the UBEC will hold.
(I have a 4 Amp hour, 7V2 battery that used to be an emergency light battery, and a charger from the same source, recycling may be our friend, if the battery is any good).
Last edited by BMS Doug on Tue May 06, 2014 10:28 am, edited 2 times in total.
Doug.
Building Management Systems Engineer.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Sat May 03, 2014 8:44 pm

Struggling a bit with getting the HC-SR04 working with the slice of Pi/O...

I can't tell why but it throws up an error but only when the input is connected to the echo output from the HC-SR04

Code: Select all

webide@raspberrypi /usr/share/adafruit/webide/repositories/my-pi-projects/Adafruit_MCP230xx $ sudo python Slice_USonic.py                   
Ultrasonic Measurement                                                                                                                      
Traceback (most recent call last):                                                                                                          
  File "Slice_USonic.py", line 233, in <module>                                                                                             
    elapsed = stop-start                                                                                                                    
NameError: name 'stop' is not defined 
it doesn't give this error when the echo pin is disconnected and a pushbutton is connected in the same location.
I have tried this with a 10K resistor pulling the Echo pin to ground and also with the resistor disconnected.
I have run the program with the pushbutton already pressed and then released once the program is running. (still doesn't replicate error)

any thoughts?

Code: Select all

#!/usr/bin/python

# USonic echo on I/O 3
# USonic Trigger on I/O 1

# Slice of Pi/O info
# Copyright 2012 Daniel Berlin (with some changes by Adafruit Industries/Limor Fried)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of
# this software and associated documentation files (the "Software"), to deal  MCP230XX_GPIO(1, 0xin
# the Software without restriction, including without limitation the rights to
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
# of the Software, and to permit persons to whom the Software is furnished to do
# so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

# Ultrasonic info
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
#|R|a|s|p|b|e|r|r|y|P|i|-|S|p|y|.|c|o|.|u|k| 
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
# 
# ultrasonic_1.py 
# Measure distance using an ultrasonic module 
# 
# Author : Matt Hawkins 
# Date : 09/01/2013 



from Adafruit_I2C import Adafruit_I2C
import smbus
import time

MCP23017_IODIRA = 0x00
MCP23017_IODIRB = 0x01
MCP23017_GPIOA  = 0x12
MCP23017_GPIOB  = 0x13
MCP23017_GPPUA  = 0x0C
MCP23017_GPPUB  = 0x0D
MCP23017_OLATA  = 0x14
MCP23017_OLATB  = 0x15
MCP23008_GPIOA  = 0x09
MCP23008_GPPUA  = 0x06
MCP23008_OLATA  = 0x0A

class Adafruit_MCP230XX(object):
    OUTPUT = 0
    INPUT = 1

    def __init__(self, address, num_gpios):
        assert num_gpios >= 0 and num_gpios <= 16, "Number of GPIOs must be between 0 and 16"
        self.i2c = Adafruit_I2C(address=address)
        self.address = address
        self.num_gpios = num_gpios

        # set defaults
        if num_gpios <= 8:
            self.i2c.write8(MCP23017_IODIRA, 0xFF)  # all inputs on port A
            self.direction = self.i2c.readU8(MCP23017_IODIRA)
            self.i2c.write8(MCP23008_GPPUA, 0x00)
        elif num_gpios > 8 and num_gpios <= 16:
            self.i2c.write8(MCP23017_IODIRA, 0xFF)  # all inputs on port A
            self.i2c.write8(MCP23017_IODIRB, 0xFF)  # all inputs on port B
            self.direction = self.i2c.readU8(MCP23017_IODIRA)
            self.direction |= self.i2c.readU8(MCP23017_IODIRB) << 8
            self.i2c.write8(MCP23017_GPPUA, 0x00)
            self.i2c.write8(MCP23017_GPPUB, 0x00)

    def _changebit(self, bitmap, bit, value):
        assert value == 1 or value == 0, "Value is %s must be 1 or 0" % value
        if value == 0:
            return bitmap & ~(1 << bit)
        elif value == 1:
            return bitmap | (1 << bit)

    def _readandchangepin(self, port, pin, value, currvalue = None):
        assert pin >= 0 and pin < self.num_gpios, "Pin number %s is invalid, only 0-%s are valid" % (pin, self.num_gpios)
        #assert self.direction & (1 << pin) == 0, "Pin %s not set to output" % pin
        if not currvalue:
             currvalue = self.i2c.readU8(port)
        newvalue = self._changebit(currvalue, pin, value)
        self.i2c.write8(port, newvalue)
        return newvalue


    def pullup(self, pin, value):
        if self.num_gpios <= 8:
            return self._readandchangepin(MCP23008_GPPUA, pin, value)
        if self.num_gpios <= 16:
            lvalue = self._readandchangepin(MCP23017_GPPUA, pin, value)
            if (pin < 8):
                return
            else:
                return self._readandchangepin(MCP23017_GPPUB, pin-8, value) << 8

    # Set pin to either input or output mode
    def config(self, pin, mode):
        if self.num_gpios <= 8:
            self.direction = self._readandchangepin(MCP23017_IODIRA, pin, mode)
        if self.num_gpios <= 16:
            if (pin < 8):
                self.direction = self._readandchangepin(MCP23017_IODIRA, pin, mode)
            else:
                self.direction |= self._readandchangepin(MCP23017_IODIRB, pin-8, mode) << 8

        return self.direction

    def output(self, pin, value):
        # assert self.direction & (1 << pin) == 0, "Pin %s not set to output" % pin
        if self.num_gpios <= 8:
            self.outputvalue = self._readandchangepin(MCP23008_GPIOA, pin, value, self.i2c.readU8(MCP23008_OLATA))
        if self.num_gpios <= 16:
            if (pin < 8):
                self.outputvalue = self._readandchangepin(MCP23017_GPIOA, pin, value, self.i2c.readU8(MCP23017_OLATA))
            else:
                self.outputvalue = self._readandchangepin(MCP23017_GPIOB, pin-8, value, self.i2c.readU8(MCP23017_OLATB)) << 8

        return self.outputvalue


        self.outputvalue = self._readandchangepin(MCP23017_IODIRA, pin, value, self.outputvalue)
        return self.outputvalue

    def input(self, pin):
        assert pin >= 0 and pin < self.num_gpios, "Pin number %s is invalid, only 0-%s are valid" % (pin, self.num_gpios)
        assert self.direction & (1 << pin) != 0, "Pin %s not set to input" % pin
        if self.num_gpios <= 8:
            value = self.i2c.readU8(MCP23008_GPIOA)
        elif self.num_gpios > 8 and self.num_gpios <= 16:
            value = self.i2c.readU8(MCP23017_GPIOA)
            value |= self.i2c.readU8(MCP23017_GPIOB) << 8
        return value & (1 << pin)

    def readU8(self):
        result = self.i2c.readU8(MCP23008_OLATA)
        return(result)

    def readS8(self):
        result = self.i2c.readU8(MCP23008_OLATA)
        if (result > 127): result -= 256
        return result

    def readU16(self):
        assert self.num_gpios >= 16, "16bits required"
        lo = self.i2c.readU8(MCP23017_OLATA)
        hi = self.i2c.readU8(MCP23017_OLATB)
        return((hi << 8) | lo)

    def readS16(self):
        assert self.num_gpios >= 16, "16bits required"
        lo = self.i2c.readU8(MCP23017_OLATA)
        hi = self.i2c.readU8(MCP23017_OLATB)
        if (hi > 127): hi -= 256
        return((hi << 8) | lo)

    def write8(self, value):
        self.i2c.write8(MCP23008_OLATA, value)

    def write16(self, value):
        assert self.num_gpios >= 16, "16bits required"
        self.i2c.write8(MCP23017_OLATA, value & 0xFF)
        self.i2c.write8(MCP23017_OLATB, (value >> 8) & 0xFF)

# RPi.GPIO compatible interface for MCP23017 and MCP23008

class MCP230XX_GPIO(object):
    OUT = 0
    IN = 1
    BCM = 0
    BOARD = 0
    def __init__(self, busnum, address, num_gpios):
        self.chip = Adafruit_MCP230XX(busnum, address, num_gpios)
    def setmode(self, mode):
        # do nothing
        pass
    def setup(self, pin, mode):
        self.chip.config(pin, mode)
    def input(self, pin):
        return self.chip.input(pin)
    def output(self, pin, value):
        self.chip.output(pin, value)
    def pullup(self, pin, value):
        self.chip.pullup(pin, value)


if __name__ == '__main__':
    # ***************************************************
    # Set num_gpios to 8 for MCP23008 or 16 for MCP23017!
    # ***************************************************
    # mcp = Adafruit_MCP230XX(address = 0x20, num_gpios = 8) # MCP23008
    mcp = Adafruit_MCP230XX(address = 0x20, num_gpios = 16) # MCP23017

    # Set pins 0, 1 and 2 to output (you can set pins 0..15 this way)
    mcp.config(0, mcp.OUTPUT)
    mcp.config(1, mcp.OUTPUT)
    mcp.config(2, mcp.OUTPUT)

    # Set pin 3 to input with the pullup resistor disabled 
    # HC-SR04 sensor pulls the echo pin high
    mcp.config(3, mcp.INPUT)
    mcp.pullup(3, 0)

    print "Ultrasonic Measurement" 

    # Set trigger to False (Low) 
    mcp.output(1, 0)  # Pin 0 Low 

    # Allow module to settle 
    time.sleep(0.5) 

    # Send 10us pulse to trigger 
    mcp.output(1, 1)  # Pin 0 High
    # time.sleep(1.00001) # while testing with LED
    time.sleep(0.00001) 
    mcp.output(1, 0)  # Pin 0 Low  
    start = time.time() 
    while mcp.input(3) >> 3 == 0: 
        start = time.time() 
    while mcp.input(3) >> 3 == 1: 
        stop = time.time() 

    # Calculate pulse length 
    elapsed = stop-start 

    # Distance pulse travelled in that time is time # multiplied by the speed of sound (cm/s) 
    distance = elapsed * 34000 

    # That was the distance there and back so halve the value 
    distance = distance / 2 
    print "Distance : %.1f" % distance 
Doug.
Building Management Systems Engineer.

User avatar
joan
Posts: 14995
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Dalek - help needed with USonic and I2C error

Sat May 03, 2014 8:59 pm

Code: Select all

   ...
    while mcp.input(3) >> 3 == 0:
        start = time.time()
    while mcp.input(3) >> 3 == 1:
        stop = time.time()

    # Calculate pulse length
    elapsed = stop-start
    ...
For stop not to be defined it means that the second while loop found the input to be low as soon as it was started.

That means the first while loop noticed the pulse start but by the time the second while loop had started the pulse had finished. A close object? Possibly not helped by having to go over a slow I2C bus to get the readings.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek - help needed with USonic and I2C error

Sat May 03, 2014 9:23 pm

joan wrote:

Code: Select all

   ...
    while mcp.input(3) >> 3 == 0:
        start = time.time()
    while mcp.input(3) >> 3 == 1:
        stop = time.time()

    # Calculate pulse length
    elapsed = stop-start
    ...
For stop not to be defined it means that the second while loop found the input to be low as soon as it was started.

That means the first while loop noticed the pulse start but by the time the second while loop had started the pulse had finished. A close object? Possibly not helped by having to go over a slow I2C bus to get the readings.
Ok, thats pinned it down, thanks. confirmed by adding a delay between the two loops and testing with a push button.
Good to know that the reason I haven't been able to get this to work is the bus speed and not my programming.
I'll attach any Ultrasonic sensors I use direct to the GPIO pins instead of the slice of Pi/O

note: yes this does work with objects further away, just not close objects
so this setup is not suitable for collision avoidance application but might work in an application that can tolerate a greater distance, but accuracy may suffer due to communication delays.
Doug.
Building Management Systems Engineer.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Sat May 03, 2014 9:43 pm

Reliability feedback:

Sample of 20 (sensor wasn't moving, tape measure says that the distance is 114cm)

Code: Select all

webide@raspberrypi /usr/share/adafruit/webide/repositories/my-pi-projects/Adafruit_MCP230xx $ sudo python Usonic_slice_2.py                 
Ultrasonic Measurement                                                                                                                      
Distance : 106.3                                                                                                                            
Distance : 104.5                                                                                                                            
Distance : 105.9                                                                                                                            
Distance : 106.6                                                                                                                            
Distance : 105.7                                                                                                                            
Distance : 105.3                                                                                                                            
Distance : 106.6                                                                                                                            
Distance : 105.5                                                                                                                            
Distance : 106.2                                                                                                                            
Distance : 105.5                                                                                                                            
Distance : 105.8                                                                                                                            
Distance : 105.3                                                                                                                            
Distance : 104.0                                                                                                                            
Distance : 105.5                                                                                                                            
Distance : 106.2                                                                                                                            
Distance : 109.0                                                                                                                            
Distance : 108.8                                                                                                                            
Distance : 105.6                                                                                                                            
Distance : 108.5                                                                                                                            
Distance : 106.3   
I increased the module settle time to give a better result as I had one very low reading.

Code: Select all

# repeat readings
        samplesize = 0
    while samplesize < 20:
        # Allow module to settle 
        time.sleep(2) 

        # Send 10us pulse to trigger 
        mcp.output(1, 1)  # Pin 0 High
        # time.sleep(1.00001) # while testing with LED
        time.sleep(0.00001) 
        mcp.output(1, 0)  # Pin 0 Low  
        start = time.time() 
        while mcp.input(3) >> 3 == 0: 
            start = time.time()  
        while mcp.input(3) >> 3 == 1: 
            stop = time.time() 

        # Calculate pulse length 
        elapsed = stop-start 

        # Distance pulse travelled in that time is time # multiplied by the speed of sound (cm/s) 
        distance = elapsed * 34000 

        # That was the distance there and back so halve the value 
        distance = distance / 2 
        print "Distance : %.1f" % distance 

        samplesize += 1
Doug.
Building Management Systems Engineer.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Mon Jun 02, 2014 2:07 pm

Update:

Its been awhile since I've had anything to write (waiting on parts and some re-decorating at home) but I've actually made good progress recently.

I was waiting for some female to female wires to arrive but got tired of waiting (due next week) so I ordered some female crimp pins, connector housings and ribbon cable. most of my order arrived OK but Relchron aren't talking to me about the item that didn't arrive are sending out as replacement for the incorrect item (5 pin connector housing, they sent a servo connection lead instead).

I can now make ribbon cables as desired to the length I want and connect them to my devices as desired.

I have currently got my Pi connected to an i2c 16 channel PWM breakout board and have been playing with getting it to drive around a bit.

currently it is driving around via keyboard commands from my laptop, no speed control implemented yet.

remaining tasks:
(in order of priority)
  • communicate from android device
    switch to battery power
    connect turret servo
    fit it into the (dalek) case
    add speed control
    add sounds / voice
    add ultrasonic distance measurement
    add magnetometer
    add gyroscope accelerometer
    configure for autonomous mapping

Code: Select all

from Adafruit_PWM_Servo_Driver import PWM
import sys, tty, termios, time

# code borrowed from below sources.
# adafruit PWM example
# http://www.instructables.com/id/Controlling-a-Raspberry-Pi-RC-Car-With-a-Keyboard/step5/Software/

# The getch method can determine which key has been pressed
# by the user on the keyboard by accessing the system files
# It will then return the pressed key as a variable
def getch():
    fd = sys.stdin.fileno()
    old_settings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        ch = sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    return ch

pwm = PWM(0x40, debug=True)

servoMin = 150  # Min pulse length out of 4096
servoMax = 600  # Max pulse length out of 4096

def setServoPulse(channel, pulse):
  pulseLength = 1000000                   # 1,000,000 us per second
  pulseLength /= 60                       # 60 Hz
  print "%d us per period" % pulseLength
  pulseLength /= 4096                     # 12 bits of resolution
  print "%d us per bit" % pulseLength
  pulse *= 1000
  pulse /= pulseLength
  pwm.setPWM(channel, 0, pulse)

def forward():
    print "forward"
    pwm.setPWMFreq(50)
    pwm.setPWM(0, 0, 0)
    pwm.setPWM(1, 0, 4095)
    pwm.setPWM(2, 0, 4095)
    pwm.setPWM(3, 0, 0)
  
def backward():
    print "backward"
    pwm.setPWMFreq(50)
    pwm.setPWM(0, 0, 4095)
    pwm.setPWM(1, 0, 0)
    pwm.setPWM(2, 0, 0)
    pwm.setPWM(3, 0, 4095)
  
def stop():
    print "stop"
    pwm.setPWMFreq(50)
    pwm.setPWM(0, 0, 0)
    pwm.setPWM(1, 0, 0)
    pwm.setPWM(2, 0, 0)
    pwm.setPWM(3, 0, 0)
  
def turnRight():
    print "turnRight"
    pwm.setPWMFreq(50)
    pwm.setPWM(0, 0, 0)
    pwm.setPWM(1, 0, 0)
    pwm.setPWM(2, 0, 4095)
    pwm.setPWM(3, 0, 0)
  
def turnLeft():
    print "turnLeft"
    pwm.setPWMFreq(50)
    pwm.setPWM(0, 0, 0)
    pwm.setPWM(1, 0, 4095)
    pwm.setPWM(2, 0, 0)
    pwm.setPWM(3, 0, 0)

  
def spinRight():
    print "spinRight"
    pwm.setPWMFreq(50)
    pwm.setPWM(0, 0, 4095)
    pwm.setPWM(1, 0, 0)
    pwm.setPWM(2, 0, 4095)
    pwm.setPWM(3, 0, 0)
    
def spinLeft():
    print "spinLeft"
    pwm.setPWMFreq(50)                        # Set frequency to 50 Hz
    pwm.setPWM(0, 0, 0)
    pwm.setPWM(1, 0, 4095)
    pwm.setPWM(2, 0, 0)
    pwm.setPWM(3, 0, 4095)

# Setting the PWM pins to false so the motors will not move
# until the user presses the first key
pwm.setPWM(0, 0, 0)
pwm.setPWM(1, 0, 0)
pwm.setPWM(2, 0, 0)
pwm.setPWM(3, 0, 0)

# Instructions for when the user has an interface
print("w/s: acceleration")
print("q/e/a/d: steering")
print("x: exit")

# Infinite loop that will not end until the user presses the
# exit key
while True:
    # Keyboard character retrieval method is called and saved
    # into variable
    char = getch()

    # The car will drive forward when the "w" key is pressed
    if(char == "w"):
        forward()

    # The car will reverse when the "s" key is pressed
    if(char == "s"):
        backward()
        
    # The "q" key will toggle the steering turn left
    if(char == "q"):
        turnLeft()

    # The "e" key will toggle the steering turn right
    if(char == "e"):
        turnRight()
        
    # The "a" key will toggle the steering to spin left
    if(char == "a"):
        spinLeft()

    # The "d" key will toggle the steering to spin right
    if(char == "d"):
        spinRight()

    # The "x" key will break the loop and exit the program
    if(char == "x"):
        print("Program Ended")
        break

    # The keyboard character variable will be set to blank, ready
    # to save the next key that is pressed
    char = ""

# Program will cease all PWM activity before terminating
stop()
Doug.
Building Management Systems Engineer.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Sun Jun 08, 2014 7:21 am

I dug into the loft last night and found my Dalek shell, then i went mad with the Stanley knife and glue gun and have now mounted my wheels inside the base of the dalek shell.

I tried to consolidate all my power using the L298N's on board 5v output but it wasn't able to hold the load so I wired in the UBEC that I had previously tested.
This still couldn't hold the load (possibly a power supply issue) when I changed motors from forward to reverse the pi momentarily dropped out. Slowing the motors, adding a stop position and a time delay between each command resolved this.

I should probably start a blog site to host all the pictures I took.
Doug.
Building Management Systems Engineer.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Sun Jun 08, 2014 12:22 pm

OK Blog post made, lots of pictures and a short video clip there.
Doug.
Building Management Systems Engineer.

User avatar
Paul Webster
Posts: 822
Joined: Sat Jul 30, 2011 4:49 am
Location: London, UK
Contact: Twitter

Re: Dalek

Sun Jun 08, 2014 2:40 pm

The best bit is the admission that you first bought the remote control Daley for your wife.
Not many wives would have appreciated that gesture!

User avatar
rpdom
Posts: 17424
Joined: Sun May 06, 2012 5:17 am
Location: Chelmsford, Essex, UK

Re: Dalek

Sun Jun 08, 2014 4:00 pm

Paul Webster wrote:The best bit is the admission that you first bought the remote control Dalek for your wife.
Not many wives would have appreciated that gesture!
Mine would. She's obsessed. She has daleks and sonics and minifigures and all sorts of things everywhere. We even put a TARDIS on top of our christmas tree every year - the light on the top pulses at random intervals controlled by PWM from a Pi :-)

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Sun Jun 08, 2014 4:02 pm

Her sister has a full sized (old movie prop) dalek in her garage.
Doug.
Building Management Systems Engineer.

User avatar
mikronauts
Posts: 2803
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: Dalek

Sun Jun 08, 2014 6:26 pm

Great project Doug!

You can use the HC-SR04 with just one Pi GPIO pin - I really don't recommend trying to use it on an I/O expander.

GPIO --> Trig pin

Divide the 5V output of the echo pin as follows:

echo pin ---> 2k4 ---- (*** Trig Pin & GPIO ***) ---- 4k7 ---> GND

Regards,

Bill
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Sun Jun 08, 2014 9:55 pm

mikronauts wrote:Great project Doug!

You can use the HC-SR04 with just one Pi GPIO pin - I really don't recommend trying to use it on an I/O expander.

GPIO --> Trig pin

Divide the 5V output of the echo pin as follows:

echo pin ---> 2k4 ---- (*** Trig Pin & GPIO ***) ---- 4k7 ---> GND

Regards,

Bill
Hi Bill,

I have plenty of GPIO's for now, I'm currently only using the i2c bus as I have a 16 channel PWM board running the L298N board. I do have 3 HC-SR04 available to use, I can spare 2 GPIO for each if I decide fit them all.
Running the HC-SR04 from the I/O expander did work, fairly reliably, as long as the wall wasn't too close but I'll attach them to the GPIO when / if I add them.

I've done a small amount of cosmetic work, I took the casing off the wifi dongle and dremelled out a space for it in the blue hemisphere, then glued it in, so my wifi is disguised but external (still removable).

I'm seriously considering a new power supply, possibly a 10Ah 5v one (saw one for £15 on amazon).

I'm probably going to rewire the 2 LEDs, they are currently wired in parallel and I have plenty of potential connection points to add them individually.

I'm eventually going to get a short HDMI extender and two short USB extenders, basically make all of the important pi connection points externally accessible by pulling open blue hemispheres, so it could be connected to a TV and USB hub and used as a desktop pi in a fancy case.
Doug.
Building Management Systems Engineer.

dom
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 5572
Joined: Wed Aug 17, 2011 7:41 pm
Location: Cambridge

Re: Dalek

Sun Jun 08, 2014 11:01 pm

BMS Doug wrote:Her sister has a full sized (old movie prop) dalek in her garage.
Surely that must be stage 2 of your project?

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Mon Jun 09, 2014 5:10 am

dom wrote:
BMS Doug wrote:Her sister has a full sized (old movie prop) dalek in her garage.
Surely that must be stage 2 of your project?
Stage 5 or 6 maybe, the cost of scaling up that far may be prohibitive.
Doug.
Building Management Systems Engineer.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Mon Jun 09, 2014 1:12 pm

I had a mad idea and have now ordered a bunch of short cable extenders, I'll move the pi to a less space hogging position inside the dalek and make the other usb port and the HDMI port accessible by removable blue spots.

Then if I ever want to use the Pi as a computer I can drive it over to the TV and pull out the blue plug stops and connect the HDMI and USB Hub mounted keyboard / mouse combo.

I also ordered a 10000mah powerbank, that should work as a battery for the Dalek.
Doug.
Building Management Systems Engineer.

BMS Doug
Posts: 3823
Joined: Thu Mar 27, 2014 2:42 pm
Location: London, UK

Re: Dalek

Mon Jun 16, 2014 9:34 am

BMS Doug wrote:I also ordered a 10000mah powerbank, that should work as a battery for the Dalek.
It works, but its slooooooowwwwww, I'd rather have more speed available so a higher voltage is required. I guess I could get a step up regulator but I'll probably just source a higher voltage battery. (the powerbank can be a charger for our tablets and phones, so its not a wasted purchase).

Space inside the Dalek chassis is at a premium, I'm shuffling bits around while deciding final locations.
the PWM board is probably going to end up in the neck of the Dalek (I've removed the original angled I2C connectors and fitted straight ones, to give me space to put it there).

the power connector on the L298N board snapped (because of changing the wiring too often) so I fitted a removable one, sadly I had to spend some time filing the through hole connectors down a bit to get them to fit.

I think I'll probably need to re-do all my connecting cables a little bit longer, to give myself space to move stuff around. I'm going to hold off on that for now as I only want to do it once.
Doug.
Building Management Systems Engineer.

Return to “Automation, sensing and robotics”