Show Posts
Pages: [1] 2 3 4
1  General Category / General Discussion / Re: Proposal for workshopping with Python and Firmata on: April 22, 2014, 08:15:04 am
@Chagrin Sorry for not replying. Posts here don't seem to subscribe you to replies by default and the checkbox is in a hidden menu.

The python 'import' line certainly needs explaining, but I believe I'm being fair. We can contrast the use of void and the use of import quite strongly I believe, and I'm quite surprised to hear your point of view that they are similarly problematic from a comprehension or functionality point of view in an educational setting.

void...
* does literally nothing
* is a placeholder to do with the parsing of the language
* can only be explained by reference to return values, types, function calls, none of which are needed for a simple program, effectively meaning all novice Arduino programmers must mentally begin at http://arduino.cc/en/Reference/FunctionDeclaration rather than (my personal preference) http://arduino.cc/en/Reference/digitalWrite
* plays a part in a structure which is mandatory (for Arduino programs) but isn't fundamentally required

import
* is fundamental to the program
* contains no spurious terms - it "imports" functionality used later with the name "Arduino" from a library (provided by someone else) called "pyfirmata"
* introduces python as a simple, minimal interpreter which can be used for Arduino, but not only for Arduino (you might choose to import other things), which is a key educational objective. You can do preparatory work with arithmetic and text printout before you introduce Arduino at all.

From a purely practical point of view, I find that the import statement is not only comprehensible to people, but is functional and introduces important and relevant concepts for their learning about an interpreted programming environment, and python in particular.

By contrast I find myself apologising for the void setup() {} void loop() {} boilerplate - a slight embarrassment when saying of Blink 'this is your first, simple program' in workshops. Even an empty program which does nothing is hard to explain. It may be literally their first encounter with code, and for many that moment can determine their expectations for a good while.

We could agree to differ on which is easier to understand, more useful or more meaningful. I think the more important contrast is between the interpreted approach and the compiled approach, with the interpreted code offering much more opportunity for reflective processes of learning and experimentation in atomic chunks. The import statement, once entered, can essentially be forgotten as you simply proceed to make calls to the 'Arduino' object, which have immediate, visible effect in your circuit and can be understood in a standalone fashion, without thinking about flow control, stacks or forms of indirection..

Exposing people to void could easily be avoided if the maintainers of the Arduino program treated top level statements as implicitly within a setup() function, as the makers of Processing do (I believe, though it's a bit buggy from experience). Then you could just write code which turned on and off LEDs directly, while moving towards a setup() and loop() convention after explaining the basics, and only when it's needed.
2  Using Arduino / Programming Questions / Re: Diagnosing interference between pulseIn and (interrupt-based) HL1606PWM library? on: November 03, 2013, 04:49:03 pm
In the end, a resolution became possible using Hugokernel's latest commit to PaintYourDragon's HL1606 (PWM) library.
https://github.com/hugokernel/HL1606-LED-Strip-PWM/commits/master

This was combined with some hit-and-hope testing around the maximum LED update rate which the ATMEGA could handle at the same time as the slowest available Serial connection and alongside the Ultrasonic Ping logic. Finally I had some stable code I could deploy, although using the HC-SR04 at the same time as the HL1606 strip seemed impossible, using Hugokernel's end() method it was at least possible to turn off the strip and suspend interrupts (using noInterrupts wasn't equivalent) when I wanted to use the Ultrasonic, then toggle back to using the LED strip when I needed.

However, even with this intervention, I had to carefully select LED library parameters to avoid HC-SR04 non-responsiveness and other hangs.
3  Using Arduino / Programming Questions / Re: Diagnosing interference between pulseIn and (interrupt-based) HL1606PWM library? on: October 31, 2013, 08:02:52 pm
As a workaround, I'm trying to reimplement pulseIn and delayMicroseconds from scratch, as these are the only invocations which are needed to use the HC-SR04 although it's weird that I can't figure out how it's not working, these functions use some fairly fancy shortcuts and difficult for me to know if there's a negative interaction between these and the Interrupt logic of the HL1606 PWM library.
4  Using Arduino / Programming Questions / Re: Diagnosing interference between pulseIn and (interrupt-based) HL1606PWM library? on: October 31, 2013, 01:49:19 pm
Ah I think I understand schema, now - a wiring diagram, sorry.

The circuit currently has only those pins indicated in the sketch. VCC and GND is provided to power the HC-SR04 and Trigger and Echo pins on the HC-SR04 are attached to digital pins 12 and 9 respectively. That's the entire circuit.

I haven't detailed the wiring as it seems so innocuous and unlikely to be this, given the difference in behaviour between commenting and uncommenting the strip.begin() behaviour.

I'm imagining it's something to do with HL1606 use of timers, interrupts, and the use of delayMicroseconds and pulseIn (which may implicitly depend on some timer configuration). However, I can't see anything online which indicates an issue of this kind, hence wondering if an expert eye could help.
5  Using Arduino / Programming Questions / Re: Diagnosing interference between pulseIn and (interrupt-based) HL1606PWM library? on: October 31, 2013, 01:42:11 pm
Yes, I can recreate the problem with and without the LED strip entirely detached using the minimal code below.

This code is functional (reports varying distances as you put your hand in front of the sensor) unless the strip.begin() line is uncommented to enable the SPI and Interrupt code of the LED strip with the Adafruit library, and then it fails (always reporting 0 as a result from pulseIn, and hence always reporting 0 distance).

Code:
#include "HL1606stripPWM.h"

int triggerPin = 12;
int echoPin = 9;
long maxDuration = 16000; //longest time a pulse might take in microseconds

int latchPin = 10;
HL1606stripPWM strip = HL1606stripPWM(2, latchPin);

void setup(){
 
  Serial.begin(115200);
 
  //configure pins for Ultrasonic sensor
  pinMode(triggerPin,OUTPUT);
  pinMode(echoPin,INPUT);
 
  //configure strip
  strip.setPWMbits(3);
  strip.setSPIdivider(16);
  strip.setCPUmax(10);
  strip.begin();
 
}

void loop(){
  digitalWrite(triggerPin,LOW);
  delayMicroseconds(2);
  digitalWrite(triggerPin,HIGH);
  delayMicroseconds(10);
  digitalWrite(triggerPin,LOW);
 
  //wait on response
  long duration, distance;
  duration = pulseIn(echoPin, HIGH, maxDuration);
  distance = (duration/2) / 29.1;
  Serial.println(distance);
}
6  Using Arduino / Programming Questions / Diagnosing interference between pulseIn and (interrupt-based) HL1606PWM library? on: October 31, 2013, 01:00:02 pm
I have a sketch at...
https://github.com/cefn/ReadingLights/blob/d6486f0508f7d6267057b8ee86f44750152859a5/lightUpLancaster/rainbowOnMovementHL1606/rainbowOnMovementHL1606.ino
...which _successfully_ detects nearby objects and reports distances from the sensor over serial, so long as strip.begin() is commented out (as per the github version).

However, the moment strip.begin() is uncommented, and the interrupt- and SPI- logic of the Adafruit library is allowed to run, then the sensor always reports 0 distance and pulseIn never detects the sensor pulse, even when objects are placed directly in front of the distance sensor.

I'm using Adafruit's HL1606PWM library for full color control of a strip of 32 LEDs, which works well. I'm also using a HC-SR04 ultrasonic sensor to detect movement using pulseIn, and this works well. However, combining them in a sketch seems to be very bad news, even if the LEDs are off, and therefore drawing minimal power, so I'm assuming it's a software issue and really need to work out how to get them to play nicely. I gave up using NewPing because it depended on interrupts and could conflict through shared use of the same Timer but using pulseIn to detect the ultrasonic sensor shouldn't have this dependency I think, so it's really blind-sided me with very little time left to go before an installation.

Because of the nature of the project, it's _not_ needed to run both the ultrasonic and the LEDs at the same time, so if I need to deactivate one in order to run the other, that's fine, but currently if the LED strip is _ever_ activated, the pulseIn invocation then always returns 0 from the echo pin of the ultrasonic sensor for the lifetime of the sketch.

The sensor fails to detect  even if I bracket the pulsein(...) invocation with noInterrupts() then interrupts(), which I think should prevent the strip library from taking over the processor in the middle of a pulseIn. The sensor fails to detect even if I remove the maxDuration value which determines the maximum wait time from pulseIn.

Can anyone suggest a software issue which would mean that pulsein stops working correctly when using the (Timer2 interrupt-based) HL1606 library (which you can see at https://github.com/adafruit/HL1606-LED-Strip-PWM ). Are there sensible workarounds in rewiring or reprogramming to be able to have them both attached and functioning (even at different times)?
7  Using Arduino / Motors, Mechanics, and Power / Minimise power draw from Steppers OR New battery+motor choice for Robot on: May 05, 2013, 08:37:10 pm
I've been building an Arduino-compatible two-wheeled robot based on the @ShrimpingIt circuit and 28-BYJ-48 motors with a JY-MCU Bluetooth Serial Module. Progress had stalled as I was experiencing Bluetooth brownouts over and over again. Having followed a million dead ends on what was going on with Bluetooth and serial, this now seems to be because the battery packs are going flat super-quick, but so fast that I couldn't really believe that was the real issue.

The robot is only designed to carry the weight of its own breadboard, but it can take a 4xAAA battery pack (with cheap alkalines) from 6.5V to 5V within just over a minute of unloaded rotation (even with the axles running free).

Now I desperately need to come up with something which will keep the robots going on a battery pack for at least 10 minutes or more else they won't be any use in the classroom they're destined for. Various alternatives to address the crazy power draw;

To drive the robot, I currently have two 28-BYJ-48 stepper motors which are being driven by the Accelstepper library. Are these motors even realistic to use on battery? I'm wondering what possible circuit changes or software controls might change their power demands, or whether they are inherently unbelievably inefficient and I should give up. If so, what motor options have people had success with, (I'm hoping to be able to count rotations for control purposes, though, hence the steppers, so something which can do this would be great).

On the battery front, what sort of plan makes sense. For example can I hope to use cheap Alkaline batteries, or is this a fool's game? Do I have to go all the way to something high-end like LiPo? Anything in the middle which could be cheap? I'm aiming at sub-£10 all-in which I'd pretty-much achieved with the prototype, so it would be a shame to have super-expensive batteries in the design.

Overall, what kind of motor and battery configuration should I expect to be able to get a 10 minute-plus run time from breadboarded-ATMEGA-based two-wheeled robots, even if the robots are fairly slow-moving (i.e. not bombing around like remote-controlled cars)?

FOR REFERENCE

You can see the Accelstepper config in...
https://github.com/cefn/blueshrimp/blob/master/Code7/lib/arduino/Code7/examples/StandardFirmataRobot/StandardFirmataRobot.ino
...which can be diffed against the StandardFirmata distributed with Arduino.

I'm basing the core serial protocol on Firmata, and then just extending it to be able to send Stepper positions and get back Ultrasonic pings. The 'client-side' control of the robot takes place using a python script, building on pyFirmata, allowing me to access any sensors on the robot, and also control its Robot-specific capabilities on top...
https://github.com/cefn/blueshrimp/blob/master/Code7/examples/robot/robot.py
8  Using Arduino / Programming Questions / Re: Help with bytes, ints, longs on: January 26, 2013, 01:46:58 pm
Thanks, everyone

I can confirm that I've been able to serve up my magic value of 324, finally, using the code inlined below, which simply reorders the bytes {68,1,0,0} and assumes all values use the leftmost bytes first. I'm sure there will be more interesting complexities as I'm trying to communicate python 'longs' using "7-bit bytes" over serial from Python - the reason for all this bitwise shenanigans in the first place, but I have a start.

I suspect if I'd fully reversed the transform from the desktop code (which uses left and right shifting on whole-numbered values to derive individual bytes), then I would be in the clear as this would have seamlessly hidden the architectural differences which I had misunderstood.

Code:
//I would expect having the leftmost bytes {68,1} would
//map to an integer value of 324 (e.g. 68 + 256) for both
//int and long. Both the long and the int should start at byteArray[0]
byte byteArray[] = {68,1,0,0};
static char stringBuffer[50];

void setup(){
  Serial.begin(9600);
}

void loop(){
  delay(1000);
  long *longPointer = (long*)byteArray;
  int *intPointer = (int*)byteArray;
  sprintf (stringBuffer, "Long, Int, Bytes: %ld, %i, %i %i %i %i --- ;) \r\n", *longPointer, *intPointer, byteArray[0], byteArray[1], byteArray[2], byteArray[3]);
  Serial.print(stringBuffer);
  Serial.println();
}
9  Using Arduino / Programming Questions / Help with bytes, ints, longs on: January 26, 2013, 11:07:19 am
Hello all,

I consider myself a pretty solid programmer but I've hit a brick wall on a simple problem. Don't know if there's something major I'm missing, possibly to do with endianness or memory allocation.

My understanding of C representation of whole numbers is that it's binary with the least significant bit on the right, and the most significant bit on the left. For signed values, the most significant bit being set indicates a negative number, and the remaining bits of the number are set according to twos complement.

I would therefore expect positive bytes, ints and longs to behave pretty much the same, and negative numbers would differ only in the selection of where the most significant bit is.

In particular I would expect the number 324 stored in a 4-byte long value to have exactly the same lower bytes as the number 324 stored in a 2-byte int value - the bytes being 1 and 68. The long value would just have two extra zero bytes on the left.

I ran into an issue when writing code based on this assumption and I've summarised the problem into a minimal sketch below. Can anyone explain to me why when this sketch is run, the long value and the int value aren't being reported as 324. How do I have to marshall the bytes into a long or int in order to get the value 324 reported? I may be failing to understand sprintf also.

What I actually see reported is...

Long, Int, Bytes: 1140916224, 17409, 0 0 1 68

Code:
//I would expect having the rightmost bytes {1,68} would
//map to an integer value of 324 (e.g. 256 + 68) for both
//int and long. The long starts at byteArray[0] and the int starts at byteArray[2]
byte byteArray[] = {0,0,1,68};
static char stringBuffer[50];

void setup(){
  Serial.begin(9600);
}

void loop(){
  delay(1000);
  long *longPointer = (long*)byteArray;
  int *intPointer = (int*)(byteArray+2);
  sprintf (stringBuffer, "Long, Int, Bytes: %ld, %i, %i %i %i %i --- ;) \r\n", *longPointer, *intPointer, byteArray[0], byteArray[1], byteArray[2], byteArray[3]);
  Serial.print(stringBuffer);
  Serial.println();
}
10  Using Arduino / Programming Questions / Re: POV for Beginners. on: January 25, 2013, 07:04:40 pm
I've been running workshops with people to build POV specifically, working with 11-14 year olds making the electronics, and also designing their own icons like this...



I'd say first of all get the idea of how to write a sketch which flashes LEDs, like Blink

Then move onto blinking an LED with non-blocking timing, like BlinkWithoutDelay. This will turn out to be important later on when you want to, for example, include a tilt switch to control the flashing sequence, though you don't need this to begin with.

Next, understand how bytes are made out of bits. This will be important when trying to record the pixels which make up your font in an efficient way.

In my case, for an 8-led column I use a single byte to represent each column of lights, with each bit of the byte determining whether that pixel is on or off in the specific column. I use variable size characters, so that an exclamation mark can be represented in a single byte, whereas a 'W' character is made of many columns. I therefore need to not only record the bytes in a big byte array, but keep track of which characters start at which point in the array.

You can see the data structures I use at...
http://shrimping.it/shrimp/project/pov/font/fonts.h
...and how I did it at...
http://stackoverflow.com/questions/12988915/how-to-extract-bitmap-data-from-ttf-bitmap-typeface-for-a-pov-display
...with more up-to-date source for font extraction and encoding at...
http://shrimping.it/shrimp/project/pov/font/

There's a step-by-step build for Blink based on our @ShrimpingIt circuit - a minimal Arduino compatible which you can build in minutes on breadboard - at
http://shrimping.it/workshops/madlab/pov/teacher_guide.pdf
...which leads you towards this circuit, which just has an extra 7 LEDs...
http://shrimping.it/workshops/madlab/pov/pov.svg

The handout we use at...
http://shrimping.it/workshops/madlab/pov/student_guide.pdf
...has some general information including a page at the back, covering the task of designing your own characters for the POV and encoding them in binary.

I know you didn't want it, but there's code at http://shrimping.it/shrimp/project/pov/shrimPov.zip which works with the circuit at http://shrimping.it/shrimp/project/pov/pov.pdf

If you need to translate between Shrimp world and Arduino world then take a look at http://arduino.cc/en/Hacking/PinMapping

Good luck.
11  Using Arduino / Project Guidance / Re: Serial Encoding to 7-bit using Base85 or anything else - your thoughts? on: January 21, 2013, 01:27:43 pm
This strategy has developed into a proprietary, but probably more elegant approach, to avoid the overengineering of Base85.

Essentially, I've written a routine which pushes the extra bit per byte into an overflow byte which is then written (at most) every 8th byte. This is immediately more efficient and comprehensible than Base85.

You can see some more discussion at the relevant issue on PyFirmata github, with some example (untested) code...
https://github.com/tino/pyFirmata/issues/12#issuecomment-12509900
12  Using Arduino / Project Guidance / Re: Serial Encoding using Git's Base85 - your thoughts? on: January 20, 2013, 09:32:57 am
Particularly worrying in the compiler warnings is...
"warning, right shift count >= width of type"
...which I guess comes from the assumption of at least 32-bit-width data structures built into the base85 logic in the git code I'm using from https://github.com/git/git/blob/master/base85.c.

I think I have to go back to the drawing board.

I still like the idea of base85 (especially given python support for decoding it) but would struggle to implement a solid, conformant implementation. Perhaps a subset...?

Any other ideas how to tackle encoding multiple-of-8-bit data types into 7-bit bytes in simple to manage, easy to understand, debuggable ways.
13  Using Arduino / Project Guidance / Re: Encoding Sysex Firmata Messages using Git's Base85 on: January 20, 2013, 08:53:06 am
The code I'm proposing to use to wrap the base85 invocations from git would look like this (I'm now back on the machine with the code).

Hopefully the example code using these wrappers (also inlined below) underlines the simplicity of the approach for users.

I've copied the base85 encoding and decoding functions from the git source https://github.com/git/git/blob/master/base85.c unmodified. These are just the wrapper functions intended to call those functions.

Code:
//CH generic function to write 4 bytes (an unsigned long) as 5 7-bit bytes using Base85
void writeBase85Long(long toencode){
    byte encodedBytes[5];
    encode_85(((char*)&encodedBytes), (const unsigned char*)&toencode, 4);
    Serial.write(encodedBytes[0]);
    Serial.write(encodedBytes[1]);
    Serial.write(encodedBytes[2]);
    Serial.write(encodedBytes[3]);
    Serial.write(encodedBytes[4]);
 }
 
 //CH: Just read one long (4 bytes) from base85 encoded source (5 bytes)
long readBase85Long(byte* src){
  long decodedLong;
  decode_85((char*)&decodedLong,((char*)src),4);
  return decodedLong;
}

//CH: Read a series of longs (4 bytes) from base85 encoded source (5 bytes), returning number of source bytes read
int readBase85Longs(byte* src, long* dst, int numLongs){
  for(int count = 0; count < numLongs; count++){
    dst[count]=readBase85Long(src);
    src+=5; //reading 4 bytes, but will consume 5 src bytes to do it
  }
  return numLongs * 5;
}

...and a typical invocation of this wrapper code in the context of decoding/encoding a Sysex message within the standard switch of Firmata's sysexCallback function might look like this...

Code:
  case STEPPER_MESSAGE:
    byte *stepperSide = argv;
    long stepperTarget = readBase85Long(++argv);
    long stepperCurrent = -1;
    if(stepperSide == STEPPER_LEFT){
      //left motor control
      leftStepper.moveTo(stepperTarget);
      stepperCurrent = leftStepper.currentPosition();
    }
    else if(stepperSide == STEPPER_RIGHT){
      //right motor control
      rightStepper.moveTo(stepperTarget);
      stepperCurrent = rightStepper.currentPosition();
    }
    //always report back current position
    Serial.write(START_SYSEX);
    Serial.write(STEPPER_MESSAGE);
    Serial.write(*stepperSide);
    writeBase85Long(stepperCurrent);
    Serial.write(END_SYSEX);
    break;
14  Using Arduino / Project Guidance / Serial Encoding to 7-bit using Base85 or anything else - your thoughts? on: January 20, 2013, 08:17:25 am
I'd like to develop a generic strategy for specialising Firmata sketches for bespoke circuits. The aim is to preserve all the functionality of StandardFirmata whilst also permitting build-specific messages to be sent. I have a strategy in mind, building on the Base85 C code distributed as part of the code-versioning tool 'git' which I think should permit the easy encoding of arbitrary multi-byte data into 7-bit data space of Firmata Sysex messages. I'd like to get feedback on the feasibility and possible beartraps of the proposed approach, as well as preferred alternatives.

An example which requires this approach is a two-wheeled robot platform. The proposed Arduino sketch code should support the sending of messages to control the two stepper motors. It should also permit the requesting of measured distances from an ultrasonic sensor. However, students experimenting with the robot may also wish to attach arbitrary other analog sensors or digital components to the robot, which they should be able to query over bluetooth serial as part of control logic in python through pyFirmata. Building on StandardFirmata, changing the Serial data rate (to be consistent with Arduino code upload) and adding messages to support the extra hardware seems natural to serve all these needs.

However, it's hard to, for example, encode a 'long' integer value using the recommended Firmata approach. The Accelstepper library I'm using employs a 'long' as its representation of stepper position.

FIrmata recommends the use of the Sysex extension to achieve build-specific messaging, but data must be sent in a 7-bit encoding, as one of the bits is used to flag Firmata control messages (including the start and end of Sysex). With a 4-byte 'long' it's hard to know exactly how to shove it into 7-bits in a comprehensible and debuggable way.

Enter base85 (http://en.wikipedia.org/wiki/Ascii85). This has a canonical (and efficient) implementation as part of the git version control utility. The code is accessible at https://github.com/git/git/blob/master/base85.c The transform can be reversed using mainstream utilities for debugging.

I would like to know if there are any reasons why the git code for base85 linked above should not be ported to Arduino in order to facilitate the encoding of arbitrary bytestreams (including the 4 bytes of my long) into the 7-bit data space of Firmata Sysex messages. This would mean that generic sendInt, sendFloat, receiveInt, receiveFloat operations could be defined on each side of the Firmata link, using the base85 encoding on the component bytes of each type to create a straightforward wrapper for data.

I've arrived at code which almost compiles, but hoping to get insights from others on the practicality of the approach. Also there may be a much easier model of encoding and decoding bytes into a 7-bit transport, or a better base85 code reference which I should adopt instead.
15  Topics / Education and Teaching / Re: What are some unconventional ways to start teaching? on: December 09, 2012, 06:08:43 am
I started out doing a degree in Artificial Life and got a post exploring commercial exploitation of ALife techniques at BT's R&D labs. Over the ten years I was there, my role increasingly focused on rapid prototyping of new inventions, alongside the making of interactive art constructions in my spare time.

Gradually I got drawn into workshopping the digital prototyping techniques I've been using for my day job and the arts (lots of open source, Arduino, Processing), initially with adults for tinker.it in London. More recently I was invited to do this with kids at a local school and since then, a lot of my effort has been diverted towards education, both hands on and via the site at http://shrimping.it. The work is also increasingly steering the PhD I just started at Highwire, Lancaster University.

Last week, for example, I led the construction and programming of Arduino-compatible Persistence of Vision circuits on breadboard in a 3 hour workshop format, leading to 40 kids taking @ShrimpingIt POV circuits home to show their friends and family, and hopefully repurpose and hack for more crazy things.

For those interested, some of the resources which I used to support this work are available under CC licence at http://shrimping.it/shrimp/project/pov/
Pages: [1] 2 3 4