Jump to content

Data Logger Red Brick + mehrere Bricks/Bricklets


jawedoo

Recommended Posts

Hallo liebe Leute,

Ich hab hier an einem Red-Brick eine IMU 2.0, einen Accelerometer und ein GPS bricklet. jetzt würde ich gerne zu einer bestimmten Frequenz (20Hz z.b.) von allen Sensoren ihre aktuellen Daten bekommen.

Geht das auf diese Art und Weise?:

Alldata-Listener der Imu ruft eine außenstehende methode auf und übergibt alle 3 sensoren. Diese werden ausgelesen und geloggt.

 

Mein gedanke war, dass ich nur den Alldata callback von der IMU nutze, weil diese sich mit sicherheit ändert und auf die 20Hz hört (alle anderen callbacks auch einzuschalten würde meine logdatenzahl vervielfachen und nicht zum gewünschten effekt führen)... nur ist mein problem dass ich statt 20 ergebnissen pro sekunde z.b. nur 13/15 bekomme... die imu unterstütz ja eigentlich eine Abtastrate von 100Hz, übersehe ich da was?

Hier mein Code, bin für jede Hilfe dankbar =)

 

public class Red {
    private static final String HOST = "localhost";
    private static final int PORT = 4223;

    private static final String UID = "xxx";		//IMUV2
    private static final String UID2 = "xx2";		//Accelerometer 1.1
    private static final String UID3 = "xx3";		//GPS 1.0
    private static final int HERZ = 20;			//Set here your desired Frequency
    
    public static void main(String args[]) throws Exception {
        IPConnection ipcon = new IPConnection(); // Create IP connection
        BrickIMUV2 imu = new BrickIMUV2(UID, ipcon); 
        BrickletAccelerometer accel = new BrickletAccelerometer(UID2, ipcon);
        BrickletGPS gps = new BrickletGPS(UID3, ipcon);
        
        ipcon.connect(HOST, PORT); // Connect to brickd
        // Don't use device before ipcon is connected

        
//#####################All Listeners are going to trigger the logging######################
        // Add all data listener
        imu.addAllDataListener(new BrickIMUV2.AllDataListener() {
            public void allData(short[] acceleration, short[] magneticField,
                                short[] angularVelocity, short[] eulerAngle,
                                short[] quaternion, short[] linearAcceleration,
                                short[] gravityVector, byte temperature,
                                short calibrationStatus) {
            	output(imu, accel, gps);
            }
        });

//###############################Listener Ends here #######################################
        
        
        // Set period for all callbacks
        imu.setAllDataPeriod(1000/HERZ);
        
        //first line for titles
        System.out.println("Euler Angle x;ImuAccel x;ImuAccel y; Accel x; Accel y;Latitude;Longitude;Speed;Date;Time;Satelites used;GPS fix");
        System.in.read();
        ipcon.disconnect();
    }

    private static void output(BrickIMUV2 imu, BrickletAccelerometer accel, BrickletGPS gps){
	try {
		LinearAcceleration acc = imu.getLinearAcceleration();
		Acceleration acc2 = accel.getAcceleration();
		Orientation euler = imu.getOrientation();
		Coordinates coords = gps.getCoordinates();
		Motion speed = gps.getMotion();
		Status stat = gps.getStatus();
    	String timeStamp = new SimpleDateFormat("dd.MM.yyyy;HH:mm:ss.SSS").format(new Date()); 

        System.out.println(euler.heading/16 + ";" + acc.x/100.0 + ";" + acc.y/100.0 + ";" + 
        		acc2.x/1000.0 + ";" + acc2.y/1000.0 + ";" + coords.latitude/1000000.0 + ";" + 
        		coords.longitude/1000000.0 + ";" + speed.speed/100.0 + ";" + timeStamp + ";" + stat.satellitesUsed + ";" + stat.fix);
	} catch (TimeoutException | NotConnectedException e) {
		// dont log
	}
    }
}

Link to comment
Share on other sites

  • 1 month later...

Hi,

 

Du stellst Dir gleich zweimal ein Bein:

  • Du verwendest den Callback der IMU als Scheduler für Deine Anwendung.
  • Statt die Werte, die die IMU im Callback schon liefert rufst Du sie lieber noch mal neu ab. (short[] acceleration im Callback vs. imu.getLinearAcceleration() in output(...))

 

Ich würde (für quick & dirty) empfehlen die Werte, die Du im AllDataListener::allData([viele Arrays]) bekommst, in ein ImuData POJO zu verpacken in output(imudata, accel, gps) zu übergeben, und noch zusätzlich die anderen Brick(let)s abzurufen.

 

Eine gute Lösung wäre meiner Meinung nach, für alle benötigten Datenquellen periodic Callback Listener zu registrieren, damit die Werte periodisch schicken zu lassen und in einer ConcurrentHashMap zu speichern. In einem separaten Task kannst Du die Werte dann periodisch aus der Map lesen und ausgeben.

 

Wenn es unbedingt Polling sein soll, verwende besser einen ScheduledTaskExecutor. Dann ersparst Du dem Datenbus wenigstens die Last, Dir alle IMU Werte doppelt zu schicken (1x Callback + 1x getNNN() im Output).

 

Freundliche Grüße

  Bernhard

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...