Virtual 3D Device Port – SU08-22-Accelerometer (ADXL345)
In het vorige hoofdstuk heb je gezien hoe we een virtuele potmeter kunnen maken in google sketchup als je de basis onder de knie hebt, we gaan nu een stapje verder door een accelerometer (ADXL345) te koppelen met SketchUp waarbij 2 gegevens nodig zijn, te weten de X en Y coördinaten, ik heb er een “doolhof” spel van gemaakt.
Sluit de accelerometer aan volgens onderstaand schema:
De Arduino programmeren
Het voorbeeld script genereert deze gegevens in STABIELE horizontale ligging:
En als je de module beweegt:
Wat moeten we doen?
1) We hebben in dit geval niets aan de Z coördinaat, dus die coderegels kunnen we eruit halen.
2) In stabiele horizontale ligging, staan de getallen niet op 0, hier moeten we dus een autocorrectie op doen, dit doen we door de allereerste coördinaten op te slaan en later van de gemeten waarde af te trekken.
1 2 3 4 5 |
if (a < 1) { xc = (((int)_buff[1]) << 8) | _buff[0]; yc = (((int)_buff[3]) << 8) | _buff[2]; a = 1; } else { |
3) We hebben getallen nodig van 0.00 tot 1.00, deze kunnen we MAPPEN via de Arduino code, de waarde om te MAPPEN kun je zelf uitlezen door de module 90 graden te kantelen aan de 4 zijden.
1 2 |
float xval = map(x - xc, -160, 160, 0, 1000); float yval = map(y - yc, -150, 150, 0, 1000); |
Ik heb het script omgebouwd tot deze variant, waar nodig de code aan je eigen situatie aanpassen!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
#include <Wire.h> #define DEVICE (0x53) // Device address as specified in data sheet byte _buff[6]; char POWER_CTL = 0x2D; //Power Control Register char DATA_FORMAT = 0x31; char DATAX0 = 0x32; //X-Axis Data 0 char DATAX1 = 0x33; //X-Axis Data 1 char DATAY0 = 0x34; //Y-Axis Data 0 char DATAY1 = 0x35; //Y-Axis Data 1 char DATAZ0 = 0x36; //Z-Axis Data 0 char DATAZ1 = 0x37; //Z-Axis Data 1 int xc = 100; int yc; int a=0; void setup() { Wire.begin(); // join i2c bus (address optional for master) Serial.begin(9600); // start serial for output. Make sure you set your Serial Monitor to the same! //Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register. writeTo(DATA_FORMAT, 0x01); //Put the ADXL345 into Measurement Mode by writing 0x08 to the POWER_CTL register. writeTo(POWER_CTL, 0x08); } void loop() { uint8_t howManyBytesToRead = 6; readFrom( DATAX0, howManyBytesToRead, _buff); //read the acceleration data from the ADXL345 // each axis reading comes in 10 bit resolution, ie 2 bytes. Least Significat Byte first!! // thus we are converting both bytes in to one int // Deze IF loop slaat de allereerste gemeten waarde van de coordinaten op, // om zo een correctie uit te voeren en in horizontale stand op 0 te beginnen. if (a < 1) { xc = (((int)_buff[1]) << 8) | _buff[0]; yc = (((int)_buff[3]) << 8) | _buff[2]; a = 1; } else { int x = (((int)_buff[1]) << 8) | _buff[0]; int y = (((int)_buff[3]) << 8) | _buff[2]; // MAP de getallen van X en Y MAX en MIN van 0 t/m 1000. float xval = map(x - xc, -160, 160, 0, 1000); float yval = map(y - yc, -150, 150, 0, 1000); // Deze correctie is nodig omdat de gegevens soms net // iets buiten het bereik kunnen komen. if (xval > 1000) {xval = 1000;} if (xval < 0) {xval = 0;} if (yval > 1000) {yval = 1000;} if (yval < 0) {yval = 0;} // Print de gegevens X en Y met als scheidingsteken een komma. // Ps. vergeet niet af te sluiten met een nieuwe lijn. Serial.print(xval / 1000); Serial.print(","); Serial.println(yval / 1000); // Lees de module uit elke 0,05 seconden. delay(50); } } void writeTo(byte address, byte val) { Wire.beginTransmission(DEVICE); // start transmission to device Wire.write(address); // send register address Wire.write(val); // send value to write Wire.endTransmission(); // end transmission } // Reads num bytes starting from address register on device in to _buff array void readFrom(byte address, int num, byte _buff[]) { Wire.beginTransmission(DEVICE); // start transmission to device Wire.write(address); // sends address to read from Wire.endTransmission(); // end transmission Wire.beginTransmission(DEVICE); // start transmission to device Wire.requestFrom(DEVICE, num); // request 6 bytes from device int i = 0; while(Wire.available()) {// device may send less than requested (abnormal) _buff[i] = Wire.read(); // receive a byte i++; } Wire.endTransmission(); // end transmission } |
Als we nu bovenstaande code opslaan in de Arduino en je opent de seriële monitor, dan zijn dit de gegevens bij stabiele horizontale ligging:
En als je de module beweegt:
Actie in SketchUp
Nu de Arduino haar data verzend via de seriële poort naar de computer toe, kunnen wij deze met een script voor SketchUp weer uitlezen, ik heb voor het testen een doolhofje gemaakt (onderaan te downloaden)
Voor het splijten van de seriële data (de waarden van X en Y), heb ik deze python code toegepast:
x, y = serialdata.split(',')
In het model vink je aan “scripted” en daar moet deze code worden geplaatst, er zijn commentaarregels toegevoegd:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# DomoticX Virtual 3D Device Port SU08 interface. # Wat moet er gebeuren bij het starten van de simulatie? onstart{ # Python commando om de seriele bibliotheek te importeren. Py.exec("import serial") # Python commando om de seriele poort te openen. Py.exec("ser = serial.Serial('COM8', 9600)") } # Wat moet er gebeuren tijdens de simulatie? ontick{ # Python commando om de seriele poort uit te lezen voor gegevens. Py.exec("serialdata = ser.readline()") # Python commando om de binnengekomen data in 2 variabelen te splitsen Py.exec("x, y = serialdata.split(',')") # Ruby commando om de gegevens van python om te zetten in variabelen. $x = Py.eval("x") $y = Py.eval("y") # Ruby commando om de data te printen in de Ruby console. logLine("Doolhof X: " + $x) logLine("Doolhof Y: " + $y) logLine("") logLine("") logLine("") logLine("") logLine("") logLine("") } # Wat moet er gebeuren als de de simulatie stopt? onend{ # Python commando om de seriele poort te sluiten. Py.exec("ser.close()") } |
De servo’s kunnen ingesteld worden met in de controllers de variabelen $x en $y:
De servo’s kunnen gekoppeld worden aan de “doolhof”:
Alles in actie
1) Sluit de Arduino aan met bovenstaand Arduino script geladen (pas eventueel de COM poort aan in het Python script).
2) Druk op de “play” knop om de simulatie te starten.
Nu zal het “doolhof” zich gaan bewegen, zoals je ook de accelerometer ADXL345 beweegt!
De gegevens X en Y worden aan de linkerkant weergegeven!
Hoe werkt het?
Dit werkt nu via een seriele verbinding tussen de Arduino en de computer, de arduino stuurt 2 getallen (FLOAT) voor de X en Y beweging tussen 0.00 en 1.00.
In Sketchup SketchyPhysics is:
– 0.00 de status van het object opgegeven bij de MIN waarde (bijvoorbeeld -135 graden)
– 1.00 de status van het object opgegeven bij de MAX waarde (bijvoorbeeld 135 graden)
Daaruit volgt dat tussen 0.00 en 1.00, 270 graden zit, omdat sketchup met stapjes van 0.01 werkt zijn er 100 stapjes dus 2,7 graden per stapje.
- SketchyPhysics - SU08-32-RGB LED aansturen (sketchup).7z 46,90 kb
- SketchyPhysics - SU08-32-RGB LED aansturen (ruby-python scripts).ino.7z 1,16 kb
- SketchyPhysics - SU08-32-RGB LED aansturen (arduino script).ino.7z 0,80 kb
- SketchyPhysics - SU08-31-Servo aansturen (SG90) (arduino script).ino.7z 0,82 kb
- SketchyPhysics - SU08-30-Hendel status voorbeeld compleet naar Arduino (sketchup 8).skp.7z 19,00 kb
- SketchyPhysics - SU08-30-Hendel status voorbeeld compleet naar Arduino (ruby-python script).rb.7z 0,93 kb
- SketchyPhysics - SU08-30-Hendel status voorbeeld compleet (sketchup 8).skp.7z 18,47 kb
- SketchyPhysics - SU08-30-Hendel status voorbeeld compleet (ruby-python script).rb.7z 0,75 kb
- SketchyPhysics - SU08-30-Hendel status voorbeeld (sketchup 2014).skp.7z 18,46 kb
- SketchyPhysics - SU08-30-Hendel orgineel voorbeeld omgezet (sketchup 8).skp.7z 17,68 kb
- SketchyPhysics - SU08-30-Hendel orgineel voorbeeld (sketchup 2013).skp.7z 24,89 kb
- SketchyPhysics - SU08-22-Accelerometer (ADXL345) (sketchup).skp.7z 53,98 kb
- SketchyPhysics - SU08-22-Accelerometer (ADXL345) (ruby-python script).rb.7z 0,67 kb
- SketchyPhysics - SU08-22-Accelerometer (ADXL345) (arduino script).ino.7z 1,52 kb
- SketchyPhysics - SU08-21-Virtuele Potmeter (sketchup).skp.7z 34,45 kb
- SketchyPhysics - SU08-21-Virtuele Potmeter (ruby-python script).rb.7z 0,56 kb
- SketchyPhysics - SU08-21-Virtuele Potmeter (arduino script).ino.7z 0,60 kb
- SketchyPhysics - SU08-21-Potmeter orgineel model (sketchup).skp.7z 91,66 kb
- SketchyPhysics - SU08-20-Communicatie naar SU (sketchup).skp.7z 14,91 kb
- SketchyPhysics - SU08-20-Communicatie naar SU (ruby-python script).rb.7z 0,59 kb
- SketchyPhysics - SU08-20-Communicatie naar SU (arduino script).ino.7z 0,33 kb
- SketchyPhysics - SU08-12-Waarde uitlezen van object voorbeeld van forum (sketchup).7z 61,51 kb
- SketchyPhysics - SU08-10-Basis oefening (sketchup).skp.7z 14,31 kb