Archiv nach Kategorien: Programmierung

Heap Error finden mit GFlags – Debug

Beim Entwickeln kann es schnell mal sein, dass ein Buffer ungewollt über den allokierten Bereich überschrieben wird. Um einen Fehler dieser Art zu finden, bieten sich Tools von Mircosoft an:

https://developer.microsoft.com/en-us/windows/hardware/windows-driver-kit

Hat man die Tools installiert geht man mit der Konsole an folgend Ort:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86

dort ruft man
gflags.exe /p
auf, um zu sehen welche Programme (Binaries) gerade überwacht werden.

Als nächsten Schritt müssen wir unser Programm einfügen (mit absolutem Pfad), PATH ist zu ersetzen
gflags.exe /p /full /enable PATH

Jetzt starten wir die Debug-Gui aus dem gleichen Ordner (C:\Program Files (x86)\Windows Kits\10\Debuggers\x86) mit dem Namen
windbg.exe
Ist das Programm gestartet kann man entweder einen laufenden Prozess (nicht aus anderer Debugging-Umgebung, sondern direkt gestartet) auswählen oder den Prozess direkt mit dem Windows Debugger starten.
Für den zweiten Fall kann die Session mit F5 gestartet werden.

Sobald der Heap-Error auftritt wird der entsprechende Code im Debugger angezeigt und die betroffene Zeile markiert.

Zum Schluss sollte die Überwachung wieder beendet werden, dies geschieht mit
gflags.exe /p /full /disable EXECUTEABLE
wobei hier nur der EXECUTEABLE Name angegeben werden muss und nicht der komplette Pfad

Quellen

https://blog.kowalczyk.info/article/1j9/gflags-a-debugging-story.html
https://developer.microsoft.com/en-us/windows/hardware/windows-driver-kit

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

433MHz Temperatursensor Reverse Engineering

Mein Ziel ist es die verschiedenen Außenfühler oder Außenthermometer anzuzapfen und die Daten über ein Microchip RN171 Modul im Netzwerk verfügbar zu machen (leider bisher noch Zukunftsmusik).
Hierfür habe ich mir auf Ebay ein Sende – und Empfangsmodul gekauft (~2€) und dieses an mein Picoscope angeschlossen. Die getriggerten Daten habe ich als CSV gespeichert und mittels PHP ausgewertet.

Ich habe mehrere Temperaturfühler und werde sie hier nach und nach hinzufügen.

Die Angaben sind alle selbst ermittelt und können bei anderen Systemen abweichen. Dieser Betrag gilt für mich als Gedankenstütze, die vielleicht jemand brauchen kann um bei dem gleichen Vorhaben ein bisschen weiterzukommen. Meine beste Quelle war hier folgender Beitrag:
http://www.mikrocontroller.net/topic/57829#449580

Fehler oder weitere Erkenntnisse sind jederzeit gerne willkommen. Ich hoffe irgendwann alle Bits jedes Datenpakets interpretieren zu können, gerne auch die Checksum 😐

Aldi Wetterstation Meteotime Sempre

(gekauft Herbst 2016)

Durch die Anzeige auf dem Außenfühler ist es relativ leicht die Temeratur und Luftfeuchtigkeit in den geloggten Daten wiederzufinden.
Als Übertragungsprotokoll wird hier der Biphase-Mark-Code verwendet. Der sieht im Fall der Wetterstation so aus:

AldiMeteotimeBiphaseMarkCode-1024x45 in

Biphase-Mark-Code der Wetterstation (aufbereitet)

Man sieht kurze und lange Takte, die Bedeutung ist relativ schnell erklärt. Nimmt man den kurzen Takt als Basis, dann ist überall dort wo kein Phasenwechsel ist eine „1“ zu deuten, dort wo ein Phasenwechsel stattfindet dementsprechend eine „0“.
Die Daten werden als Little-Endian übertragen, also das LSB zuerst.

Folgende Daten habe ich aufgenommen und ausgewertet:

                |<START->| ** ****                          kkkk tttt   TTTT    +  hhhhHHHH |<------CHECKSUM--------->|
17.0	43	1111110010 10 1111 00 1 011100111011110 110 0000 1110 1 1000 00111 11000010 111001111000110100100100100
17.1	45	1111110010 10 1111 00 1 011100111011110 110 1000 1110 0 1000 00111 10100010 111001111011010100011011000
17.2	46	1111110010 10 1111 00 1 011100111011110 011 0100 1110 0 1000 00111 01100010 111001111011010110101010110
17.3	46	1111110010 10 1111 00 1 011100111011110 101 1100 1110 1 1000 00111 01100010 111001111001010101000111010
17.4	45	1111110010 10 1111 00 1 011100111011110 110 0010 1110 0 1000 00111 10100010 111001111001110100001000010
17.5	45	1111110010 10 1111 00 1 011100111011110 101 1010 1110 1 1000 00111 10100010 111001111011110101001110010
14.1	42	1111110010 10 1111 00 1 011100111011110 110 1000 0010 0 1000 00111 01000010 011001111000111000100001010
15.4	42	1111110010 10 1111 00 1 011100111011110 011 0010 1010 1 1000 00111 01000010 011001111010010010111101101
16.7	42	1111110010 10 1111 00 1 011100111011110 011 1110 0110 1 1000 00111 01000010 011001111001011110101001110
17.3	42	1111110010 10 1111 00 1 011100111011110 011 1100 1110 1 1000 00111 01000010 011001111001110110111101011
24.0	42	1111110010 10 1111 00 1 011100111011110 110 0000 0010 1 0100 00111 01000010 011111111001001000010011001
24.6	41	1111110010 10 1111 00 1 011100111011110 011 0110 0010 1 0100 00111 10000010 011111111011101010110001101
-0.2	64	1111110010 10 1111 00 1 011100111011110 101 0100 0000 1 0000 00101 00100110 111001111000011110000000011
0.5	66	1111110010 10 1111 00 1 011100111011110 110 1010 0000 0 0000 00110 01100110 011001111010111110011101000
-17.8	41	1111110010 10 1111 00 1 011100111011110 110 0001 1110 0 1000 00100 10000010 011001111001100101000110110
-15.3	50	1111110010 10 1111 00 1 011100111011110 110 1100 1010 0 1000 00100 00001010 011001111000111001000011101
-13.1	56	1111110010 10 1111 00 1 011100111011110 011 1000 1100 1 1000 00100 01101010 011001111000011101011110101
-10.8	62	1111110010 10 1111 00 1 011100111011110 110 0001 0000 1 1000 00100 01000110 111001111010101111000111010
-6.6	69	1111110010 10 1111 00 1 011100111011110 110 0110 0110 0 0000 00101 10010110 011001111010001001100000011
// Batterien neu eingelegt
24.5	33	1111110010 11 0101 00 0 011100111011110 101 1010 0010 1 0100 00111 11001100 000011111111101111101110001
22.5	33	1111110010 11 0101 00 0 011100111011110 011 1010 0100 1 0100 00111 11001100 000011111111101010101011010
22.5	32	1111110010 11 0101 00 0 011100111011110 110 1010 0100 1 0100 00111 01001100 100011111101101000110000100
// Batterien neu eingelegt
24.1	33	1111110010 11 1001 00 0 011100111011110 011 1000 0010 0 0100 00111 11001100 000011111111111100001001110
23.8	32	1111110010 01 1001 00 1 011100111011110 110 0001 1100 1 0100 00111 01001100 100011111101100000010000010
23.8	32	1111110010 01 1001 00 1 011100111011110 011 0001 1100 1 0100 00111 01001100 100011111101100010111011110
// Batterien neu eingelegt
25.3	34	1111110010 11 0011 00 0 011100111011110 011 1100 1010 0 0100 00111 00101100 100011111101111100100101110
24.7	31	1111110010 11 0011 00 0 011100111011110 110 1110 0010 0 0100 00111 10001100 100011111111110110011110110
24.4	34	1111110010 00 0011 00 0 011100111011110 011 0010 0010 0 0100 00111 00101100 100011111101010100110110111
// Batterien neu eingelegt
23.7	30	1111110010 01 1001 00 1 011100111011110 011 1110 1100 1 0100 00111 00001100 000011111111010010001001000
23.9	31	1111110010 01 1001 00 1 011100111011110 011 1001 1100 0 0100 00111 10001100 100011111100100010000000011

* zufällig vergeben bei Batteriewechsel
k Temperatur floating-Byte
t Temperatur low-Byte
T Temperatur high-Byte
h Luftfeuchtigkeit low-Byte
H Luftfeuchtigkeit high-Byte

Hier noch ein paar Bilder der Wetterstation von außen und innen

Tmp 9754-20170104 1522391997708704-300x169 in Tmp 9754-20170104 1142401931758206-300x169 in Tmp 9754-20170104 114232-255450897-300x169 in

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Silabs USBxpress :: SI_Open returns SI_DEVICE_NOT_FOUND

Um einen Silicon Labs EFM8 UB1 unter Windows 10 mit USBxpress zu betreiben muss man folgendes beachten:

Ist der Treiber in der richtigen Version vorhanden? Bei mir hat Windows automatisch den Treiber installiert, ganz ohne mein Zutun. Die Version (zu prüfen im Gerätemanger) war 3.2.0.0.
Leider ist diese Version viel zu alt, um mit dem Treiber 6.7.3.0 (Stand 11/2016) zusammenzuarbeiten. Wird der Treiber aktuallisiert, so funktioniert sofort der Befehl SI_Open und gibt nicht mehr SI_DEVICE_NOT_FOUND zurück.

SI OpenDriverVersion-264x300 in

VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

SVN :: Backup and Restore Scripting

Hat man ein privates SVN Repository muss man sich auch selbst um ein Backup kümmern. Wird nicht vom ganzen Rechner ein Backup gemacht, so helfen kleine Scripte, die durch Crontabs gestartet werden. Zu diesem Zweck habe ich mir selbst ein kleines Script gebaut:

#!/bin/bash
backupDate=$(date +%Y%m%d-%H%M)
backupSrc="/svn"
backupDest="/svn/_BACKUP"
restoreScript="#!/bin/bash
sudo mkdir /$backupSrc
mkdir /$backupDest"

rm $backupDest/*
cd $backupSrc

for repo in *; do
        if [ "$repo" != "_BACKUP" ] ; then
                echo "backup: $repo"
                svnadmin dump $repo > $backupDest/$backupDate-$repo.svn.dump
                restoreScript="$restoreScript
sudo svnadmin create $backupSrc/$repo
sudo svnadmin load $backupSrc/$repo < $backupDate-$repo.svn.dump
"
        fi
done

cd $backupDest


restoreScript="$restoreScript
cd /
sudo chown -R www-data:subversion $backupSrc"
cd $backupDest
echo "$restoreScript" > restore.sh
chmod +x restore.sh

tar -cf $backupDate-svn.tar *.dump restore.sh

#copy
cp $backupDate-svn.tar /BACKUP/svn/

Will man noch sicherer sein, kann man das Backup mittels scp auch noch auf einen über das Internet erreichbaren PC speichern. Hierfür muss der RSA oder DSA Key noch auf dem Remote PC in die Datei „authorisized_keys“ eingetragen werden, und folgende Zeile im Script ergänzt werden:

scp -P PORT $backupDate-svn.tar USER@SERVER.de:/PFAD_ZU_BACKUP
VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

SVN :: TortoiseSVN over SSH, different port

Manch einer hat unter einer Domain mehrere PC’s hängen, die per SSH erreicht werden können – über verschiedene Ports nach außen.

Windows

Ist dies der Fall und SVN soll über SSH genutzt werden, dann sind folgende Konfigurationen vorzunehmen:

C:\Users\[YOUR_NAME]\AppData\Roaming\Subversion\config

editieren und dort nach „[tunnel]“ suchen. direkt darunter kommt jetzt die Anpassung des SSH Befehls:

ssh2345 = C:\\Program Files\\TortoiseSVN\\bin\\TortoisePlink.exe -P 2345

wobei „ssh2345“ frei wählbar ist.

In TortoiseSVN muss man jetzt für einen Checkout folgendes eingeben:

svn+ssh2345://NAME@DOMAIN/PATH_FROM_ROOT_DIRECTORY

als Beispiel:

svn+ssh2345://me@mydomain.com/var/repos/svn/testProject

Linux

Unter Linux geht es ähnlich. Dort gibt es im home – Verzeichnis ein Unterverzeichnis „.subversion“ in diesem Ornder gibt es eine „config“ Datei. Diese muss editiert werden, und auch hier nach „[tunnel]“ gesucht werden.
Hier muss jetzt unter dem „[tunnel]“ folgendes eingefügt werden:

ssh2345 = ssh -p 2345

ein Beispiel zum auschecken wäre dann:

svn co svn+ssh2345://me@mydomain.com/var/repos/svn/testProject
VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

OpenCV :: Kinect VideoCapture data in IplImage

To use functions in OpenCV like cvSmooth or cvAdaptiveThreshold you must have the data of your VideoCapture in an IplImage object.

VideoCapture capture;
Mat grayImage;
IplImage *imgSrc, *imgResult;

imgSrc = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1);
imgResult = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 1);

capture.open(CV_CAP_OPENNI);
if (!capture.isOpened()) {
	cout << "Can not open a capture object." << endl;
	return -1;
}
capture.set(CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_VGA_30HZ);

for(;;) {
	if (!capture.grab()) {
		cout << "Can not grab images." << endl;
		return -1;
	}
	else {
		if (capture.retrieve(grayImage, CV_CAP_OPENNI_GRAY_IMAGE)) {
			imgSrc->imageData = (char *) grayImage.data;
			cvShowImage("Source", imgSrc);

			cvSmooth(imgSrc, imgResult, CV_BLUR, 100, 100);
			cvShowImage("Result", imgResult);
		}
	}
	if (waitKey(30) >= 0)
		break;
}
VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

OpenCV :: Convert Mat into IplImage

I’ve search long time for having result on this problem. I want to use the object of IplImage, which data should be filled from Mat. If you using the simple solution found on stackoverflow, then you can’t access the methods of the IplImage object.

Mat matImage;
IplImage iplImage;

iplImage = cvCreateImage(cvSize(640,480), IPL_DEPTH_8U, 1);
iplImage->imageData = (char *) matImage.data;
VN:F [1.9.22_1171]
Rating: 5.0/5 (1 vote cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Android :: create dynamic table programmatically

My problem was to create a dynamic table and not hard xml-coded. So I’ve wrote a table class to create it programmatically. The created table has also borders.

TableGenerator class

public class TableGenerator {
    private final Context mContext;
    private TableLayout mTable;

    private TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams();
    private TableRow.LayoutParams colParams = new TableRow.LayoutParams();

    public TableGenerator(Context context) {
        mContext = context;
        mTable = new TableLayout(context);
        rowParams.setMargins(0, 0, 0, 1);
        colParams.setMargins(0, 0, 1, 0);

        TableLayout.LayoutParams lptable = new TableLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        mTable.setLayoutParams(lptable);

        mTable.setStretchAllColumns(true);
        mTable.setBackgroundColor(mContext.getResources().getColor(
                R.color.table_background));
    }

    public void addRow(String[] data) {
        TableRow tr = new TableRow(mContext);
        tr.setBackgroundColor(mContext.getResources().getColor(
                R.color.table_background));

        tr.setLayoutParams(rowParams);

        for (int iCol = 0; iCol < data.length; iCol++) {
            TextView tvCol = new TextView(mContext);
            tvCol.setText(data[iCol]);
            tvCol.setGravity(Gravity.CENTER | Gravity.CENTER);
            tvCol.setPadding(3, 3, 3, 3);
            tvCol.setTextColor(mContext.getResources().getColor(
                    R.color.text_black));
            tvCol.setLayoutParams(colParams);
            tvCol.setBackgroundColor(mContext.getResources().getColor(
                R.color.row_background));
            tr.addView(tvCol);
        }

        mTable.addView(tr);
    }

    public TableLayout getTable() {
        return mTable;
    }
}

how to use the class:

MainActivity class

public class MainActivity extends Activity {
	private ScrollView layMain;
	private TableGenerator mTable;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.layout_main);

		showTable();
	}

	private void showTable() {
		mTable = new TableGenerator(getApplicationContext());
		layMain = (ScrollView)findViewById(R.id.table);

		String[] firstRow = {"col1", "col2", "col3", "col4"};
		String[] secondRow = {"11", "12", "13", "14"};
		String[] thridRow = {"2a", "2b", "2c", "2d"};

		mTable.addRow(firstRow);
		mTable.addRow(secondRow);
		mTable.addRow(thridRow);

		layMain.removeAllViews();
		layMain.addView(mTable.getTable());
	}
}

to successfully use the code above you need to set the main.xml in layout folder to

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ScrollView
        android:id="@+id/table"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
    </ScrollView>

</LinearLayout>

now we need some color and string definitions res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
	<string name="app_name">Table</string>
	<color name="table_background">#999999</color>
	<color name="row_background">#ffffff</color>
</resources>

Downloads

Table.zip (Project files)
Table-180x300 in

VN:F [1.9.22_1171]
Rating: 4.7/5 (3 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 2 votes)

Android :: Custom Items in ListPreference

Lange habe ich gesucht, in Google mit den Wörtern „ListPreference SQLLite“ und bin immer auf sehr lange Beiträge gestoßen. Heute habe ich die Lösung gefunden, diese ist wie immer ganz einfach:

Ich habe jetzt hier nur den Teil gepostet, in dem die dynamischen Items der ListPreference zugeordnet werden.

addPreferencesFromResource(R.xml.app_preferences);

ListPreference lp = (ListPreference)findPreference("favourite_day");

CharSequence[] entries = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
CharSequence[] entryValues = { "1", "2", "3", "4", "5", "6", "7" };

lp.setEntries(entries);
lp.setEntryValues(entryValues);
VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Android :: ImageView drehen mit Animation

Um ein ImageView in Android zu drehen sind folgende Zeilen Code notwendig:

public void rotate(Viev v) {

	ImageView ivRotate = (ImageView)(findViewById(R.id.ivRotate));

	RotateAnimation aRotate = new RotateAnimation(0,180,
		ivRotate.getWidth() / 2, ivRotate.getHeight() / 2);
	aRotate.setDuration(3000);
	aRotate.setFillAfter(true);
	aRotate.setInterpolator(new LinearInterpolator());
	ivRotate.startAnimation(aRotate);
}

In die Layout.xml (z.B. main.xml) muss noch folgendes eingefügt werden, um diese Funktion mit einem Button aufzurufen:

<Button
	android:id="@+id/button1"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="Button"
	android:onClick="rotate">
</Button>
VN:F [1.9.22_1171]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)