Hello RS485 with Arduino

Nothing fancy here, just trying to get started with RS485 and Arduino. So here we go for a basic setup with one master that only emits and one slave that just listens. See the comments for the wiring:

/* RS 485 V1 Master, using a SN75176BP

                              -------
                          RO -|     |- VCC [connect to 5v]
                              |     |
                          RE -|     |- B-------------->   [connect to Slave's B]
                              |     |        | 120R (parallel resistor)
          connect to 5V   DE -|     |- A-------------->   [connect to Slave's A]
                              |     |
   connect to pin 1 (TX)  DI -|     |- GND [connect to GND]
                              -------

*/
const int ledPin = 13;      // the pin that the LED is attached to

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {

  byte b = 0;

  Serial.write(b);
  analogWrite(ledPin, b);
  delay(1000);

  b=255;

  Serial.write(b);
  analogWrite(ledPin, b);
  delay(1000);
}

And now for the slave:

/* RS 485 V1 SLAVE, using a SN75176BP

                              -------
   connect to pin 0 (RX)  RO -|     |- VCC [connect to 5v]
                              |     |
          connect toGND   RE -|     |- B-------------->   [connect to Master's B]
                              |     |        | 120R (parallel resistor)
                          DE -|     |- A-------------->   [connect to Master's A]
                              |     |
                          DI -|     |- GND [connect to GND]
                              -------

YOU'LL HAVE TO DISCONNECT RO DURING UPLOAD TO I/O BOARD!!!!!!!!!                          

*/
const int ledPin = 13;      // the pin that the LED is attached to

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  byte brightness;

  if (Serial.available()) {// check if data has been sent from the computer:

    brightness = Serial.read(); // read the most recent byte (which will be from 0 to 255):

    analogWrite(ledPin, brightness); // set the brightness of the LED:
  }
}

If all goes according to the plan, you should see something like this:



Sierpinsky triangle python script for blender

After printing a sierpinsky triangle on Theo’s makerbot, I thought it might interest some of you to see how I generated the geometry in blender.

However, before starting I should warn you that my knowledge of Blender is virtually non-existent. The blender specific code used here to generate faces is probably not ideal and you’re very welcome to improve that part.

So, what do we want to do? Make triangles, lots of them. We probably need a function to generate triangles. Let’s stay simple and assume that a triangle is composed of 3 points. We are in a 3d space so each point will have 3 components. We shall refer to these points as Vertices. There are many ways to represent this type of data in Python. For something different, let’s try namedtuples. They provide an elegant extension to the base tuple type. They work as follows:

from collections import namedtuple

Vertex = namedtuple('Vertex', 'x, y, z')  # define vertex 'type'

v1 = Vertex(0.0, 0.0, 0.0) # define a Vertex tuple, with positional arguments

v2 = Vertex(x=0.0, y=0.0, z=0.0) #define a Vertex with named arguments

x, y, z = v2    # unpack as regular tupple

x = v.x   # accessible with named parameter

We can now define our triangle function


#import blender bindings
import Blender
from Blender import NMesh
from Blender.BGL import *
from Blender.Draw import *


def triangle(a, b, c):
    """generate triangle geometry
       we expect a b c to be namedtuples of type Vertex"""
    
    ######### Creates a new mesh
    poly = NMesh.GetRaw()
    
    ### fill vertices 
    v = NMesh.Vert(a.x, a.y, a.z)
    poly.verts.append(v)
    
    v = NMesh.Vert(b.x, b.y, b.z)
    poly.verts.append(v)
    
    v = NMesh.Vert(c.x, c.y, c.z)
    poly.verts.append(v)
    
    ## create a face
    f = NMesh.Face()
    f.v.append(poly.verts[0])
    f.v.append(poly.verts[1])
    f.v.append(poly.verts[2])
    poly.faces.append(f)
    
     ######### Creates a new Object with the new Mesh
    polyObj = NMesh.PutRaw(poly)

    Blender.Redraw()

My poor knowledge of blender doesn’t allow me to say much about this code. We basically use the api to generate a three point polygon. As said, please improve or correct this part.
Time for a first test!

#define the three vertices of a triangle
a = Vertex(0.0, 0.0, 0.0)
b = Vertex(25.0, 50.0, 0.0)
c = Vertex(50.0, 0.0, 0.0)

triangle(a, b, c)

We define three vertices for our test triangle and call the triangle function. The next step is to load the code in Blender’s text editor and to press Alt-p to run the code.

(sorry for the crappy window in the middle)

Ok, so let’s get to the meat of the problem, i.e. the recursive subdivision. I use the basic algorithm from here, and adapted it to python:

def divideTriangle(a, b, c, step):
    """ recursive divide until step == 0"""
    
    if step > 0:
        #compute midpoints of sides
        
        midpointof = lambda v1, v2: Vertex(x = (v1.x + v2.x) * 0.5,
                                           y = (v1.y + v2.y) * 0.5,
                                           z = (v1.z + v2.z) * 0.5)
        
        ab = midpointof(a, b)
        ac = midpointof(a, c)
        bc = midpointof(b, c)
        
        
        # divide all but center triangle
        
        divideTriangle(a, ab, ac, step - 1)
        divideTriangle(c, ac, bc, step - 1)
        divideTriangle(b, bc, ab, step - 1)
    else:
        #stop recursion and generate geometry
        triangle(a, b, c)

I tried to be as expressive as possible, but I have the feeling that there is something fishy in the midpoint lambda. I guess it could be simplified. But it will do for now. Let’s put it all together, and see what we get in blender.

from collections import namedtuple

import Blender
from Blender import NMesh
from Blender.BGL import *
from Blender.Draw import *


Vertex = namedtuple('Vertex', 'x, y, z')  


def triangle(a, b, c):
    """a b c are of type Vertex"""
    
    ######### Creates a new mesh
    poly = NMesh.GetRaw()
    
    ### fill vertices
    
    v = NMesh.Vert(a.x, a.y, a.z)
    poly.verts.append(v)
    
    v = NMesh.Vert(b.x, b.y, b.z)
    poly.verts.append(v)
    
    v = NMesh.Vert(c.x, c.y, c.z)
    poly.verts.append(v)
    
    ## create a face
    f = NMesh.Face()
    f.v.append(poly.verts[0])
    f.v.append(poly.verts[1])
    f.v.append(poly.verts[2])
    poly.faces.append(f)
    
     ######### Creates a new Object with the new Mesh
    polyObj = NMesh.PutRaw(poly)

    Blender.Redraw()
    
    
def divideTriangle(a, b, c, step):
    """ recursive divide until step == 0"""
    
    if step > 0:
        #compute midpoints of sides
        
        midpointof = lambda v1, v2: Vertex(x = (v1.x + v2.x) * 0.5,
                                           y = (v1.y + v2.y) * 0.5,
                                           z = (v1.z + v2.z) * 0.5)
        
        ab = midpointof(a, b)
        ac = midpointof(a, c)
        bc = midpointof(b, c)
        
        
        # divide all but center triangle
        
        divideTriangle(a, ab, ac, step - 1)
        divideTriangle(c, ac, bc, step - 1)
        divideTriangle(b, bc, ab, step - 1)
    else:
        triangle(a, b, c)


#main

a = Vertex(0.0, 0.0, 0.0)
b = Vertex(25.0, 50.0, 0.0)
c = Vertex(50.0, 0.0, 0.0)

divideTriangle(a, b, c, 5)

and in blender:

Sierpinsky triangle with 5 levels of subdivision

All done : )
I leave the extruded version as an exercise for the reader.

Labo workbench light, a bit more clever than a switch

Using an old Arduino, a MosFet transistor, 5m of led strip and an old alarm detector (SIEMENS IR100B), I built an interesting little lighting set up.
The idea is that the leds switch on as you approach the desk.
The detector is a bit sensitive, but it does the job ok.
I was curious about the free run consumption when the leds are turned off.
Doing this project I got my answer: it’s very little. Less than 100mW according the wattmeter.

In attachment, code, schematics and video for reuse and improvement.

thanks to fritzing
/* Theo Reichel, Reichel Complex AI, 02/2010 */

int sensorPin = 2; // interrupt 0
int sensorAlimPin = 4;
int ledArrayPin = 9; // PWM
int buttonPin = 3; // interrupt 1
int ledPin = 11; // PWM

volatile bool sensor_status = LOW;
volatile bool button_pressed = LOW;

volatile unsigned int light_power;

unsigned long sensor_millis_diff = 0;
unsigned long sensor_status_age = 0;

volatile int menu;
int i;

void setup()   {
  Serial.begin(19200);
  Serial.println("Labo desk light with detector started");

  pinMode(ledArrayPin, OUTPUT);
  pinMode(sensorAlimPin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);

  digitalWrite(sensorAlimPin, HIGH);

  attachInterrupt(0, sensor_trigger, CHANGE);
  attachInterrupt(1, user_button, FALLING);
}

void loop()
{
// menu
  while (menu == 0)
    detector();

  while (menu == 1)
    always_on();

  while (menu == 2)
    always_off();
}

void fadein()
{
  for (light_power; light_power<255; light_power++)
  {
    analogWrite(ledArrayPin, light_power);

    if (button_pressed) // button can interrupt fade
    {
      button_pressed = LOW;
      break;
    }

    delay(5);
  }
  if (light_power == 255) // electrical workaround
    digitalWrite(ledArrayPin, HIGH);
}

void fadeout()
{
  for (light_power; light_power > 0; light_power--)
  {
    analogWrite(ledArrayPin, light_power);

    if (sensor_status) // sensor can interrupt during fadeout.
      break;

    if (button_pressed) // button can interrupt fade
    {
      button_pressed = LOW;
      break;
    }

    delay(10);
  }
  if (light_power == 0) // electrical workaround
    digitalWrite(ledArrayPin, LOW);
}

/////////// programs /////////////

void detector()
{
  digitalWrite(ledPin, 50);

  if ( sensor_status )
  {
    Serial.print("update sensor_status_age: ");
    Serial.println(sensor_status_age);
    sensor_status_age = millis();  

    if (light_power < 255)
    {
      Serial.print("fadein from light power: ");
      Serial.println(light_power);

      fadein();
    }
  }
  else
  {
    sensor_millis_diff = millis() - sensor_status_age;

    if ( light_power > 0 && sensor_millis_diff > 60000 )
    {
      Serial.print("fadout from light power:");
      Serial.print(light_power);
      Serial.print(", duration without motion");
      Serial.println(sensor_millis_diff);

      fadeout();
    }
  }
}

void always_on()
{
  digitalWrite(ledPin, HIGH);

  if (light_power < 255)
    fadein();
}

void always_off()
{
  analogWrite(ledPin, LOW);

  if (light_power > 0)
    fadeout();
}

/////////// interrupts /////////////

void sensor_trigger()
{
  sensor_status = !digitalRead(sensorPin);
}

void user_button()
{
  button_pressed = HIGH;

  if (menu == 2)
    menu = 0;
  else
    menu++;
}

The next project in the same wave is to make a nice PCB, arduino compatible with FET and detector on board.
Adding some nice little things like RTC, light sensor and a little led display, I plan to build a better light management.
For instance, if the room is bright enough the leds stays off.
If the time is far in the night, meaning that I’m not supposed to be awake, the light is faded to keep it soft for my eyes.
And of course a single push button to iterate different modes.

There is probably a lot more to do to make “clever” lights.
Feel free to share your ideas, I’m very interested.
But please, don’t mention clapping in the hand like in SF movie. I believe the light is improved if it adapts to our presence without our explicit will or interaction.

3D printing Thursday

OK.
You don’t know it yet because I haven’t bloged it, but I received a nice cupcake from Makerbot industries yesterday. The box is already built and it prints pretty well.
This post proudly announces the 3D printing thursday.
I believe people who don’t have access to 3D printer but have ideas that need to be solidified should come and see the revolution in motion.

So, it’s every thursday from tomorrow to infinity, Complex ai, 5 Rue des Maraîchers, 1205 Genève, Suisse.
It starts at 19:00
If you want to print stuff (I hope so), you are invited to come with .stl file (USB, internet, whatever) instead of just ideas. I don’t know much about 3D and I’m not able to realize phantasms with modeling software. So please, bring them with you otherwise than in your head. Make it REAL, tangible, touchable, usable !

fire to the makerbot !“. Many thanks to MakerBot Industries to 3D printing and happiness that comes along.

See ya.

‘tain le temps passe vite.

David et moi, on a été très occupé ces temps.
Si occupé qu’aucun de nous deux n’a commenté le workshop du 15.
On était moins, mais c’était intense. Plein de petits projets on vu le jour.

Dans les grandes lignes :
– Un groupe de Russe a débarqué. Ils étaient bien équipés. Arduino, Elphel, licoboard (le réalisateur lui-même, Constantin nous à fait l’honneur d’une démonstration de soudure à 5 mains)
– Rachid nous a montré sa persévérance et une matrice de diode dont il était le seul à connaître la logique du clignotement. Il est le vainqueur officiel du CD Elton John, bravo !
Monsieur Rubik s’est déplacé de Lausanne pour suivre le workshop.
– Un waveshield arduino faisait peur. Je l’ai transformé en machine à dérouter.

Bref, que du bon.
Merci encore mille fois à Amira et au Zoo de nous avoir accueilli.

Et pour finir, voici encore quelques pics pour la joie des petits et des grands:

resistance_15nov_01

resistance_15nov_02

resistance_15nov_03

resistance_15nov_04

Arduino Workshop 15 octobre 2009

Le programme du Workshop Arduino de ce Dimanche 15 octobre prend forme, au sens figuré comme au sens propre.

David nous prépare quelques démonstrations pour brancher un Arduino à toute sortes de logiciels amusants. Openframeworks, Processing, et qui sait puredata.

Philippe présentera comment quelques lignes de C peuvent foutre la migraine et les fonctions panadol(); aspegic(); aspirine(2). Il nous présentera également comment tirer profit du langage au domaine spécifique, en faisant une petite revue des fonctions référencées. Le fonctionnement des interruptions, des timers, peut-être une ou deux struct rigolotes…

Renaud nous expliquera le fonctionnement du vortex sociaux-artsitique, avec la théorie en métaphase des protons anti-synthétique. La version longue. Et s’il lui reste du temps, peut-être passera-t-il dans les rangs pour donner quelques coups de main.

Moi j’ai trouvé 10 mètres de fibre optique, un vieux scanner, un waveshield et un motorshield qui fonctionne, trois-quatre bouts de Chatterton et je ferais une ou deux démonstration de récupérations amusantes. Ensuite deux palabres théoriques “comment obtenir de l’aide?” et “comment prototyper un projet Arduino”.

Dans les rubriques “comment détourner des objets”, “faire de la récup”, “trouver des idées” et “j’ai pas de thune pour construire ma fusée”, vous êtes évidemment toujours invité à passer aux puces ce samedi 14, 10h devant la roulotte.

Si vous êtes intéressés, n’hésitez pas à vous inscrire : Resistance is futile (mais vachement utile)

PS: Argh, il n’y a plus de kit Arduino ! Ils ont tous déjà été attribués. Nous en avons une bonne dixaine à prêter donc c’est pas la misère non plus. Mais pour assouvir vos pulsion matérialiste il faut acheter ailleurs.

A tout de suite pour de nouvelles aventures.