Thorsten Kimmeskamp
Published © GPL3+

Calliope mini Schwerelosigkeits-Detektor

Bringe deinem Calliope bei, zu erkennen, ob er schwerelos ist! Probier's aus, indem du ihn in die Luft wirfst und wieder auffängst!

IntermediateFull instructions provided1 hour105
Calliope mini Schwerelosigkeits-Detektor

Things used in this project

Hardware components

Calliope mini
Calliope mini
×1

Story

Read more

Code

gravity_3d

JavaScript
let milliGX = 0 // Beschleunigung x-Achse
let milliGY = 0 // Beschleunigung y-Achse
let milliGZ = 0 // Beschleunigung z-Achse

input.setAccelerometerRange(AcceleratorRange.TwoG) // Empfindlichkeit auf 2 g einstellen

function zeigeX(wert: number) {	
	// uebergebenen Wert auf der x-Achse darstellen
	// (horizontal in der Mitte des Bildschirms):
	//
	// +-------+-------+-------+-------+-------+
	// | <= -2 |  -1   |   0   |   1   |  >= 2 |
	// +-------+-------+------------------------
	// | ..... | ..... | ..... | ..... | ..... |
	// | ..... | ..... | ..... | ..... | ..... |
	// | ###.. | .##.. | ..#.. | ..##. | ..### |
	// | ..... | ..... | ..... | ..... | ..... |
	// | ..... | ..... | ..... | ..... | ..... |
    // +-------+-------+-------+-------+-------+
	
	// mittleres Pixel in jedem Fall setzen
	led.plot(2, 2)

	// den Rest der Zeile loeschen
    led.unplot(0, 2)
    led.unplot(1, 2)
    led.unplot(3, 2)
    led.unplot(4, 2)
    
	// weitere Pixel rechts der Mitte setzen,
	// falls uebergebener Wert >= 1 bzw. >= 2
    if (wert >= 1) {
        led.plot(3, 2)
    }
    if (wert >= 2) {
        led.plot(4, 2)
    }
    
	// weitere Pixel links der Mitte setzen,
	// falls uebergebener Wert <= -1 bzw. <= -2	
	if (wert <= -1) {
        led.plot(1, 2)
    }
    if (wert <= -2) {
        led.plot(0, 2)
    }
}

function zeigeY(wert: number) {
	// uebergebenen Wert auf der y-Achse darstellen
	// (diagonal von links unten nach rechts oben):
	//
	// +-------+-------+-------+-------+-------+
	// | <= -2 |  -1   |   0   |   1   |  >= 2 |
	// +-------+-------+------------------------
	// | ..... | ..... | ..... | ..... | ....# |
	// | ..... | ..... | ..... | ...#. | ...#. |
	// | ..#.. | ..#.. | ..#.. | ..#.. | ..#.. |
	// | .#... | .#... | ..... | ..... | ..... |
	// | #.... | ..... | ..... | ..... | ..... |
    // +-------+-------+-------+-------+-------+
	
	// mittleres Pixel in jedem Fall setzen
    led.plot(2, 2)

	// den Rest der Diagonale loeschen
    led.unplot(4, 0)
    led.unplot(3, 1)
    led.unplot(1, 3)
    led.unplot(0, 4)

	// weitere Pixel rechts oberhalb der Mitte setzen,
	// falls uebergebener Wert >= 1 bzw. >= 2
    if (wert >= 1) {
        led.plot(3, 1)
    }
    if (wert >= 2) {
        led.plot(4, 0)
    }
	
	// weitere Pixel links unterhalb der Mitte setzen,
	// falls uebergebener Wert <= -1 bzw. <= -2	
    if (wert <= -1) {
        led.plot(1, 3)
    }
    if (wert <= -2) {
        led.plot(0, 4)
    }
}

function zeigeZ(wert: number) {
	// uebergebenen Wert auf der z-Achse darstellen
	// (vertikal in der Mitte des Bildschirms):
	//
	// +-------+-------+-------+-------+-------+
	// | <= -2 |  -1   |   0   |   1   |  >= 2 |
	// +-------+-------+------------------------
	// | ..... | ..... | ..... | ..... | ..#.. |
	// | ..... | ..... | ..... | ..#.. | ..#.. |
	// | ..#.. | ..#.. | ..#.. | ..#.. | ..#.. |
	// | ..#.. | ..#.. | ..... | ..... | ..... |
	// | ..#.. | ..... | ..... | ..... | ..... |
    // +-------+-------+-------+-------+-------+
	
	// mittleres Pixel in jedem Fall setzen
    led.plot(2, 2)

	// den Rest der Spalte loeschen
    led.unplot(2, 0)
    led.unplot(2, 1)
    led.unplot(2, 3)
    led.unplot(2, 4)

	// weitere Pixel oberhalb der Mitte setzen,
	// falls uebergebener Wert >= 1 bzw. >= 2
    if (wert >= 1) {
        led.plot(2, 1)
    }
    if (wert >= 2) {
        led.plot(2, 0)
    }
	
	// weitere Pixel unterhalb der Mitte setzen,
	// falls uebergebener Wert <= -1 bzw. <= -2	
    if (wert <= -1) {
        led.plot(2, 3)
    }
    if (wert <= -2) {
        led.plot(2, 4)
    }
}

function zeige3D(x: number, y: number, z:number) {
	// uebergebenen Vektor (x, y, z) im Koordinatensystem zeichnen:
	
	// Beispiele:
	// ----------
	
	// +-----------------------+------------------------+------------------------+
    // | (x = 2, y = 2, z = 0) | (x = 0, y = 0, z = -2) | (x = 1, y = -2, z = 1) |
	// +-----------------------+------------------------+------------------------+
	// |         ....#         |         .....          |         .....          |
	// |         ...#.         |         .....          |         ..#..          |
	// |         ..###         |         ..#..          |         ..##.          |
	// |         .....         |         ..#..          |         .#...          |
	// |         .....         |         ..#..          |         #....          |
	// +-----------------------+------------------------+------------------------+
		
	zeigeX(x)
    zeigeY(y)
    zeigeZ(z)
}

function zeigeKoord(milliGX: number, milliGY: number, milliGZ: number) {
	// ueberfuehrt in jeder der drei Raumdimensionen einen Wert in milli-g (milliGX, milliGY, milliGZ)
	// in eine ganzzahlige Skala von -2 bis 2 (px, py, pz) als Koordinate fuer die Anzeige am Bildschirm.

	// Die Grenzfaelle sind -600, -200, 200 und 600, so dass bei angenommenen Maximalwerten
	// von -1 g und +1 g jedes Element der Ziel-Skala einen gleich breiten Wertebereich von 400 milli-g abdeckt.
	// 
	// milli-g   :         -600      -200       200       600
	// Koordinate:     -2   )|[  -1   )|[   0   )|[   1   )|[    2
	//
	// Stellt diese Werte anschliessend in einem Koordinatensystem dar (Aufruf Funktion zeige3d)).
	// Beispiel: (milliGX, milliGY, milliGZ) = (314, -802, 200) -> zeige3d(1, -2,  1)

    let px = Math.trunc((milliGX + 1000) / (2000 / 5)) - 2
    let py = Math.trunc((milliGY + 1000) / (2000 / 5)) - 2
    let pz = Math.trunc((milliGZ + 1000) / (2000 / 5)) - 2
	
    zeige3D(px, py, pz)
}


basic.forever(function () {
    milliGX = input.acceleration(Dimension.X) // messe Beschleunigung x-Achse
    milliGY = input.acceleration(Dimension.Y) // messe Beschleunigung y-Achse
    milliGZ = input.acceleration(Dimension.Z) // messe Beschleunigung z-Achse
    
    zeigeKoord(milliGX, -milliGY, milliGZ)   // im Koordinatensystem anzeigen (y gespiegelt)
	// Normalerweise zeigt z nach oben, x nach rechts, y nach vorne. Bei y wirkt die Anzeige dann aber unnatuerlich.
})

gravity_led

JavaScript
let milliG = 0 // Staerke der Gesamtbeschleunigung (in milli-g)

input.setAccelerometerRange(AcceleratorRange.TwoG) // Empfindlichkeit auf 2 g einstellen

basic.forever(function () {
    milliG = input.acceleration(Dimension.Strength) // Staerke der Gesamtbeschleunigung messen
	
    if (milliG < 200) { // bei einem Wert unterhalb von 0,2 g Schwerelosigkeit unterstellen:
        basic.setLedColor(Colors.Green) // und die RGB-LED gruen faerben
    } else { // ansonsten:
        basic.setLedColor(Colors.Red) // RGB-LED rot faerben
    }
})

gravity_printg

JavaScript
let milliGX = 0 // Beschleunigung x-Achse
let milliGY = 0 // Beschleunigung y-Achse
let milliGZ = 0 // Beschleunigung z-Achse
let milliG = 0 // // Gesamtstaerke

basic.forever(function () {
    milliGX = input.acceleration(Dimension.X) // messe Beschleunigung x-Achse
    milliGY = input.acceleration(Dimension.Y) // messe Beschleunigung y-Achse
    milliGZ = input.acceleration(Dimension.Z) // messe Beschleunigung z-Achse
    milliG = Math.sqrt(milliGX * milliGX + (milliGY * milliGY + milliGZ * milliGZ)) // berechne Gesamtstaerke
	
    basic.showNumber(Math.round(milliG / 1000)) // auf ganze Zahl gerundet in g anzeigen
})

gravity_iss_vs_erde

JavaScript
let milliGX = 0 // Beschleunigung x-Achse
let milliGY = 0 // Beschleunigung y-Achse
let milliGZ = 0 // Beschleunigung z-Achse
let milliG = 0 // Gesamtstaerke

let playback = false // ISS-Messwerte oder aktuell gemessene Werte anzeigen
let i = 0 // Index fuer Array mit ISS-Messwerten
let anzeige = 0 // Art der Anzeige: 0 = 3D-Plot, 1 = RGB-LED, 2 = g-Wert gerundet

// ISS-Messwerte (Ausschnitt von 10 Sek.): [x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3...]
let messwerte_iss: number[] = [
54, 22, -10, 64, 24, 6, 64, 32, -10, 58, 20, 0, 58, 28, -2, 60, 36, -2, 64, 30, -10, 60, 22, -2, 54, 26, -2, 60, 24, -4,
60, 28, 14, 58, 24, -6, 58, 18, 10, 54, 20, -2, 54, 26, 12, 62, 26, -6, 64, 26, -4, 62, 22, 0, 62, 24, 0, 62, 22, 0,
62, 28, 6, 64, 26, 0, 58, 24, 16, 56, 32, 0, 58, 26, 2, 62, 18, 2, 54, 26, 22, 56, 28, -16, 60, 30, 0, 66, 22, -10,
60, 18, 14, 54, 26, -8, 58, 30, 6, 54, 16, 6, 62, 26, -12, 50, 24, 4, 54, 28, 0, 62, 28, -4, 60, 32, 10, 62, 8, -10,
62, 28, 4, 58, 24, -2, 56, 32, 8, 60, 24, 8, 56, 26, 4, 58, 22, 0, 56, 20, 2, 62, 24, 6, 58, 20, 16, 54, 24, 4,
56, 22, 12, 58, 26, 0, 58, 14, 10, 58, 30, 2, 58, 28, -4, 54, 18, 0, 66, 22, 6, 58, 22, 6, 56, 24, 0, 48, 38, 0,
62, 18, 0, 58, 36, 4, 58, 32, 2, 56, 26, 0, 60, 24, -2, 62, 30, 8, 64, 26, -4, 58, 26, 0, 62, 18, 0, 62, 24, 2,
54, 28, 6, 60, 22, -6, 56, 30, -8, 56, 24, 6, 54, 24, 4, 64, 26, -2, 60, 18, -2, 56, 16, 0, 64, 18, -6, 64, 18, 0,
58, 24, -2, 60, 28, 0, 60, 26, -10, 54, 28, 14, 58, 20, 10, 64, 18, 6, 48, 26, 0, 56, 16,-2, 54, 24, 12, 62, 34, 2,
56, 24, 4, 58, 34, 0, 56, 20, 0, 60, 30, 4, 60, 10, 6, 58, 30, 12, 54, 30, 2, 58, 26, 2, 60, 18, 4, 54, 32, -4
]

input.setAccelerometerRange(AcceleratorRange.TwoG) // Empfindlichkeit auf 2 g einstellen


input.onButtonPressed(Button.A, function () {
	// zwischen aktuellen und auf der ISS gemessenen Werten umschalten
	
    playback = !playback
})

input.onButtonPressed(Button.B, function () {
	// Art der Anzeige umschalten
	
    basic.clearScreen()
    basic.setLedColor(Colors.Off)
    if (anzeige < 2) {
        anzeige = anzeige + 1
    } else {
        anzeige = 0
    }
})


function zeigeX(wert: number) {	
	// uebergebenen Wert auf der x-Achse darstellen
	// (horizontal in der Mitte des Bildschirms):
	//
	// +-------+-------+-------+-------+-------+
	// | <= -2 |  -1   |   0   |   1   |  >= 2 |
	// +-------+-------+------------------------
	// | ..... | ..... | ..... | ..... | ..... |
	// | ..... | ..... | ..... | ..... | ..... |
	// | ###.. | .##.. | ..#.. | ..##. | ..### |
	// | ..... | ..... | ..... | ..... | ..... |
	// | ..... | ..... | ..... | ..... | ..... |
    // +-------+-------+-------+-------+-------+
	
	// mittleres Pixel in jedem Fall setzen
	led.plot(2, 2)

	// den Rest der Zeile loeschen
    led.unplot(0, 2)
    led.unplot(1, 2)
    led.unplot(3, 2)
    led.unplot(4, 2)
    
	// weitere Pixel rechts der Mitte setzen,
	// falls uebergebener Wert >= 1 bzw. >= 2
    if (wert >= 1) {
        led.plot(3, 2)
    }
    if (wert >= 2) {
        led.plot(4, 2)
    }
    
	// weitere Pixel links der Mitte setzen,
	// falls uebergebener Wert <= -1 bzw. <= -2	
	if (wert <= -1) {
        led.plot(1, 2)
    }
    if (wert <= -2) {
        led.plot(0, 2)
    }
}

function zeigeY(wert: number) {
	// uebergebenen Wert auf der y-Achse darstellen
	// (diagonal von links unten nach rechts oben):
	//
	// +-------+-------+-------+-------+-------+
	// | <= -2 |  -1   |   0   |   1   |  >= 2 |
	// +-------+-------+------------------------
	// | ..... | ..... | ..... | ..... | ....# |
	// | ..... | ..... | ..... | ...#. | ...#. |
	// | ..#.. | ..#.. | ..#.. | ..#.. | ..#.. |
	// | .#... | .#... | ..... | ..... | ..... |
	// | #.... | ..... | ..... | ..... | ..... |
    // +-------+-------+-------+-------+-------+
	
	// mittleres Pixel in jedem Fall setzen
    led.plot(2, 2)

	// den Rest der Diagonale loeschen
    led.unplot(4, 0)
    led.unplot(3, 1)
    led.unplot(1, 3)
    led.unplot(0, 4)

	// weitere Pixel rechts oberhalb der Mitte setzen,
	// falls uebergebener Wert >= 1 bzw. >= 2
    if (wert >= 1) {
        led.plot(3, 1)
    }
    if (wert >= 2) {
        led.plot(4, 0)
    }
	
	// weitere Pixel links unterhalb der Mitte setzen,
	// falls uebergebener Wert <= -1 bzw. <= -2	
    if (wert <= -1) {
        led.plot(1, 3)
    }
    if (wert <= -2) {
        led.plot(0, 4)
    }
}

function zeigeZ(wert: number) {
	// uebergebenen Wert auf der z-Achse darstellen
	// (vertikal in der Mitte des Bildschirms):
	//
	// +-------+-------+-------+-------+-------+
	// | <= -2 |  -1   |   0   |   1   |  >= 2 |
	// +-------+-------+------------------------
	// | ..... | ..... | ..... | ..... | ..#.. |
	// | ..... | ..... | ..... | ..#.. | ..#.. |
	// | ..#.. | ..#.. | ..#.. | ..#.. | ..#.. |
	// | ..#.. | ..#.. | ..... | ..... | ..... |
	// | ..#.. | ..... | ..... | ..... | ..... |
    // +-------+-------+-------+-------+-------+
	
	// mittleres Pixel in jedem Fall setzen
    led.plot(2, 2)

	// den Rest der Spalte loeschen
    led.unplot(2, 0)
    led.unplot(2, 1)
    led.unplot(2, 3)
    led.unplot(2, 4)

	// weitere Pixel oberhalb der Mitte setzen,
	// falls uebergebener Wert >= 1 bzw. >= 2
    if (wert >= 1) {
        led.plot(2, 1)
    }
    if (wert >= 2) {
        led.plot(2, 0)
    }
	
	// weitere Pixel unterhalb der Mitte setzen,
	// falls uebergebener Wert <= -1 bzw. <= -2	
    if (wert <= -1) {
        led.plot(2, 3)
    }
    if (wert <= -2) {
        led.plot(2, 4)
    }
}

function zeige3D(x: number, y: number, z:number) {
	// uebergebenen Vektor (x, y, z) im Koordinatensystem zeichnen:
	
	// Beispiele:
	// ----------
	
	// +-----------------------+------------------------+------------------------+
    // | (x = 2, y = 2, z = 0) | (x = 0, y = 0, z = -2) | (x = 1, y = -2, z = 1) |
	// +-----------------------+------------------------+------------------------+
	// |         ....#         |         .....          |         .....          |
	// |         ...#.         |         .....          |         ..#..          |
	// |         ..###         |         ..#..          |         ..##.          |
	// |         .....         |         ..#..          |         .#...          |
	// |         .....         |         ..#..          |         #....          |
	// +-----------------------+------------------------+------------------------+
		
	zeigeX(x)
    zeigeY(y)
    zeigeZ(z)
}

function zeigeKoord(milliGX: number, milliGY: number, milliGZ: number) {
	// ueberfuehrt in jeder der drei Raumdimensionen einen Wert in milli-g (milliGX, milliGY, milliGZ)
	// in eine ganzzahlige Skala von -2 bis 2 (px, py, pz) als Koordinate fuer die Anzeige am Bildschirm.

	// Die Grenzfaelle sind -600, -200, 200 und 600, so dass bei angenommenen Maximalwerten
	// von -1 g und +1 g jedes Element der Ziel-Skala einen gleich breiten Wertebereich von 400 milli-g abdeckt.
	// 
	// milli-g   :         -600      -200       200       600
	// Koordinate:     -2   )|[  -1   )|[   0   )|[   1   )|[    2
	//
	// Stellt diese Werte anschliessend in einem Koordinatensystem dar (Aufruf Funktion zeige3d)).
	// Beispiel: (milliGX, milliGY, milliGZ) = (314, -802, 200) -> zeige3d(1, -2,  1)

    let px = Math.trunc((milliGX + 1000) / (2000 / 5)) - 2
    let py = Math.trunc((milliGY + 1000) / (2000 / 5)) - 2
    let pz = Math.trunc((milliGZ + 1000) / (2000 / 5)) - 2
	
    zeige3D(px, py, pz)
}


basic.forever(function () {
    if (playback) {
		milliGX = messwerte_iss[3*i] // lese Beschleunigung x-Achse aus auf der ISS gespeicherten Daten
        milliGY = messwerte_iss[3*i+1] // lese Beschleunigung y-Achse aus auf der ISS gespeicherten Daten
        milliGZ = messwerte_iss[3*i+2] // lese Beschleunigung z-Achse aus auf der ISS gespeicherten Daten
        if (i < messwerte_iss.length/3-1) {
            i++ // naechsten Datensatz auswaehlen
        } else {
            i = 0 // am Ende zurueck zum ersten springen
        }
    } else {
        milliGX = input.acceleration(Dimension.X) // messe Beschleunigung x-Achse
		milliGY = input.acceleration(Dimension.Y) // messe Beschleunigung y-Achse
		milliGZ = input.acceleration(Dimension.Z) // messe Beschleunigung z-Achse
    }
    milliG = Math.sqrt(milliGX * milliGX + (milliGY * milliGY + milliGZ * milliGZ)) // berechne Gesamtstaerke
    
    if (anzeige == 0) { // 3D-Plot
		zeigeKoord(milliGX, -milliGY, milliGZ)   // im Koordinatensystem anzeigen (y gespiegelt)
		// Normalerweise zeigt z nach oben, x nach rechts, y nach vorne. Bei y wirkt die Anzeige dann aber unnatuerlich.
    } else if (anzeige == 1) { // RGB-LED
        if (milliG < 200) { // bei einem Wert unterhalb von 0,2 g Schwerelosigkeit unterstellen:
            basic.setLedColor(Colors.Green) // und die RGB-LED gruen faerben
        } else { // ansonsten:
            basic.setLedColor(Colors.Red) // RGB-LED rot faerben
        }
    } else if (anzeige == 2) { // g-Wert gerundet
        basic.showNumber(Math.round(milliG / 1000)) // auf ganze Zahl gerundet in g anzeigen
    }
})

Credits

Thorsten Kimmeskamp

Thorsten Kimmeskamp

19 projects • 12 followers

Comments