Tornio Digitale

Idea

Al fablab volevamo creare qualcosa per dare la possibilità a chiunque di produrre in maniera autonoma un'oggetto, e lo volevamo fare cercando di scavalcare le conoscenze di un qualsivoglia software di modellazione 3d.

Abbiamo quindi creato un'interfaccia meccanica che permette di modellare un semplice vasetto.

Dei cerchi collassabili ispirati alla sfera di Hoberman vanno a ruotare semplici potenziometri che vengono letti da Arduino, il quale invia i dati a Blender che li legge in realtime e modifica la forma del vasetto.

Lo Script in Blender va a creare una curva planare che si modifica in base ai valori dei potenziometri; una volta creata la curva vengono applicati due modifier:

-uno Screw per effettuare la rotazione . -e uno di thickness per dare uno spessore al vaso e far si che sia subito stampabile.

i 5 potenziometri sono collegati ai primi 5 pin analogici di Arduino:

-i primi 4 sono utilizzati per modificare la forma del vaso. -mentre il quinto serve per cambiare il numero di step della risoluzione e quindi la risoluzione.

immagini

Patch di Arduino

/*
  Analog input, serial output

 Reads an analog input pin, maps the result to a range from 0 to 255 and prints the results to the serial monitor.

 The circuit:
 * potentiometers connected to analog pin 0,1,2,3,4.
   Center pin of the potentiometer goes to the analog pin.
   side pins of the potentiometer go to +5V and ground

 This example code is in the public domain.

 */


// These constants won't change.  They're used to give names
// to the pins used:
const int analogInPin1 = A0;  // Analog input pin that the potentiometer is attached to
const int analogInPin2 = A1;  // Analog input pin that the potentiometer is attached to
const int analogInPin3 = A2;  // Analog input pin that the potentiometer is attached to
const int analogInPin4 = A3;  // Analog input pin that the potentiometer is attached to
const int analogInPin5 = A4;  // Analog input pin that the potentiometer is attached to


const int analogOutPin = 11; // Analog output pin that the LED is attached to

int sensorValue1 = 0;        // value read from the pot
int sensorValue2 = 0;
int sensorValue3 = 0;
int sensorValue4 = 0;
int sensorValue5 = 0;


int outputValue=0;

void setup() {
  // initialize serial communications at 9600 bps:
  Serial.begin(9600);
}

void loop() {
  // read the analog in value:
  sensorValue1 = analogRead(analogInPin1);
  sensorValue2 = analogRead(analogInPin2);            
  sensorValue3 = analogRead(analogInPin3);            
  sensorValue4 = analogRead(analogInPin4);  
 sensorValue5 = analogRead(analogInPin5);  

  // map it to the range of the analog out:
  outputValue = map(sensorValue1, 0, 1023, 0, 255);  
  // change the analog out value:
  analogWrite(analogOutPin, outputValue);          

  // print the results to the serial monitor:
  Serial.print(sensorValue1);      
  Serial.print(" ");      
  Serial.print(sensorValue2);      
  Serial.print(" ");  
  Serial.print(sensorValue3);      
  Serial.print(" ");  
  Serial.print(sensorValue4);      
  Serial.print(" ");
  Serial.print(sensorValue5);      
  Serial.print(" ");
  Serial.println();  

  // wait 10 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:
  delay(10);                    
}

script di Blender

import bpy
import time
import serial

steps=0 #steps variable
screw=0 #screw variable (in progress)

#variables of each of the four knob
dist1=1
dist2=1
dist3=1
dist4=1

val=0 #the value read from the serial port
start=True

#create a curve object
path =bpy.data.curves.new('MyPath','CURVE')
pathOb=bpy.data.objects.new('Path',path)
pathOb.location=(0,0,0)


scn=bpy.context.scene
scn.objects.link(pathOb)

path.dimensions='3D'

spline=path.splines.new('NURBS')

scn.objects.active = pathOb


#add a list of points to the curve
pointList=[(0,0,0,6),(0,30,0,6),(0,30,0,6),(0,30,30,6),(0,30,60,6),(0,30,90,6)]
nPoints=len(pointList)
print (nPoints)
spline.points.add(nPoints-1)

for n in range(nPoints):
    spline.points[n].co=pointList[n]

spline.use_endpoint_u=True

#add the srew mofifier to the curve to make a vase      
screwMod=pathOb.modifiers.new(type="SCREW",name="screw")
screwMod.steps=5

#solidify the mesh to make the object ready to be printed
solidMod=pathOb.modifiers.new(type="SOLIDIFY",name="Solidify")
solidMod.thickness=3


for i in range(len(spline.points)):
    print ("****")
    print (spline.points[i].co)

#spline.points[1].co=(-2.0,-1.0,-8.0,6)


#change "/dev/tty.usbmodemfa141" with the serial port wich Arduino is connected to
ser = serial.Serial("/dev/tty.usbmodemfa141",9600)  # open first serial port
print (ser.portstr)       # check which port was really used


#create a modal timer to make possible to see the changes in real time
class ModalTimerOperator(bpy.types.Operator):
    '''Operator which runs its self from a timer.'''
    bl_idname = "wm.modal_timer_operator"
    bl_label = "Modal Timer Operator"

    _timer = None

    def modal(self, context, event):
        if event.type == 'ESC': #when clic esc button the script stops and close the serial port
            return self.cancel()
            ser.close()   #cloese serial port

        if event.type == 'TIMER':
            line=ser.readline() #read a line from the serial port

            #print(line)
            l=len(line.split()) #check how many splitted values there are on the line read
            print(l)
            if(nPoints==l+1): #check if it is the correct number of values(this is needed to avoid  out of bounds excemptions)
                for i in range(l-1):
                    val=(float)(line.split()[i])#read each value of a line
                    print(i)
                    print(spline.points[i].co)
                    spline.points[i+2].co=(spline.points[i+2].co[0],val,spline.points[i+2].co[2],6) #modify the y coord of each point of the curve except the first point
                val=(float)(line.split()[4])#read the value of the steps
                var=(int)(val/51.2)
                screwMod.steps=var+3#update the steps value

            # change theme color, silly!
            color = context.user_preferences.themes[0].view_3d.back
            color.s = 1.0
            color.h +=0.01

            #spline.points[1].co=(-2.0,spline.points[1].co[1]+0.1,-8.0,6)
            bpy.ops.transform.rotate(value=(0.01,),axis=(0,0,1))

        return {'PASS_THROUGH'}

    def execute(self, context):
        context.window_manager.modal_handler_add(self)
        self._timer = context.window_manager.event_timer_add(0.0001, context.window)
        return {'RUNNING_MODAL'}

    def cancel(self, context):
        context.window_manager.event_timer_remove(self._timer)
        return {'CANCELLED'}


def register():
    bpy.utils.register_class(ModalTimerOperator)


def unregister():
    bpy.utils.unregister_class(ModalTimerOperator)


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.wm.modal_timer_operator()

files

tornio digitale.blend

ruota di hoberman.dxf