obwohl ich mit etwa 100 punkten verloren habe hat mir diese partie spass gemacht. ich hab’ wenig falsch gemacht und gegen einen 6. kyu ist das nicht so schlecht finde ich ![]()
einzig zug 172 hätte wohl besser auf Q 16 sein sollen.
obwohl ich mit etwa 100 punkten verloren habe hat mir diese partie spass gemacht. ich hab’ wenig falsch gemacht und gegen einen 6. kyu ist das nicht so schlecht finde ich ![]()
einzig zug 172 hätte wohl besser auf Q 16 sein sollen.
morgen startet ORF III (ORF 3) und ORF Sport + (ORF Sport Plus).
da ich nirgendwo eine aktuelle channel.conf für dvb-t gefunden habe, hab’ ich sie selbst für Graz erstellt:
PULS 4:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3050:3051:10121 3SAT:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3055:3056:11302 ORF SPORT +:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3060:3061:11303 ServusTV:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3064:3065:11304 ORF III:490000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:3070:3071:11305 ORF1:514000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5010:5011:10101 ORF2 St:514000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5020:5021:10112 ATV:514000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5040:5041:10120 ORF2 B:514000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_AUTO:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:5020:5021:10132 WKK:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1101:1102:1 Steiermark 1:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1201:1202:2 Soundportal:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:1401:1402:4 Radio West:538000000:INVERSION_AUTO:BANDWIDTH_8_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5
in anderen regionen österreichs wird diese klarerweise variieren.
mit einem USB dvb-t empfänger und linux startet man den VLC so:
vlc channel.conf
viel spass.
recently i finished my latest project: a RFID Door Opener.
besides the fun while hacking it, it improves the security of the door. since it’s not an outside door but the door to the garage, it’s construction does not allow to mount a more secure lock. so locking it from the outside when leaving is a bit bothersome.
the new auto-lock feature, which allows the door to auto-lock itself, saves some time and works around the lazy user, who wouldn’t have locked it.
additionally it is now easy to add or remove the right of access by adding or deleting the RFID’s unique number from the system. revoking someone’s right of access is far more difficult with a normal key.
beside an arduino i’m using an easydriver to drive the stepper and a RFID reader from seeedstudio.
below you can see the schematics of the setup. the ends marked with Ard X go to a port of the arduino, which is the brain of the lock:
/** * door lock application (c) 2011 Florian Klien * some code parts are borrowed from different authorsthx */ #include <NewSoftSerial.h> #define rxPin 2 #define txPin 3 // door defs #define DOOR_SENS 3 // analog #define DRIVER_SWITCH 6 #define DOOR_SW 2 // analog // motor defs #define DIR_PIN 7 #define STEP_PIN 8 #define ledIN 5 #define ledOUT 11 NewSoftSerial rfid = NewSoftSerial( rxPin, txPin ); // The tag database consists of two parts. The first part is an array of // tag values with each tag taking up 5 bytes. The second is a list of // names with one name for each tag (ie: group of 5 bytes). char* allowedTags[] = { "AABBCCDDEE", // Tag 1 "AABBCCDDEE", // Tag 2 }; // List of names to associate with the matching tag IDs char* tagName[] = { "User1", // Tag 1 "User2", // Tag 2 }; // software version number: char* software_version = "1.1"; // Check the number of tags defined int numberOfTags = sizeof(allowedTags)/sizeof(allowedTags[0]); int incomingByte = 0; // To store incoming serial data boolean locked = true; int door_open = 0; // pseudo digital boolean prev_status = false; boolean auto_lock = true; //unsigned long auto_lock_time = 0; int auto_lock_delay = 5; // in seconds int auto_lock_switch_time = 2; // in seconds int status_led = 0; unsigned long status_led_time = millis(); boolean status_led_on = false; unsigned long status_breathe_time = millis(); int breathe_delay = 10; boolean breathe_up = true; int breathe_i = 15; unsigned long last_successful_rfid_read = 0; int rfid_success_timeout = 5000; // millis float lock_speed = 1; /** * Setup */ unsigned long time_door = millis(); unsigned long time_switch = millis(); long debounce = 500; void setup() { pinMode(ledIN, OUTPUT); pinMode(ledOUT, OUTPUT); digitalWrite(ledIN, HIGH); digitalWrite(ledOUT, HIGH); delay(300); digitalWrite(ledIN, LOW); digitalWrite(ledOUT, LOW); pinMode(DRIVER_SWITCH, OUTPUT); digitalWrite(DRIVER_SWITCH, LOW); pinMode(DIR_PIN, OUTPUT); digitalWrite(DIR_PIN, LOW); pinMode(STEP_PIN, OUTPUT); digitalWrite(STEP_PIN, LOW); pinMode(DOOR_SENS,INPUT); pinMode(DOOR_SW,INPUT); Serial.begin(9600); // Serial port for connection to host rfid.begin(9600); // Serial port for connection to RFID module Serial.println("RFID reader starting up"); delay(1000); Serial.println("done"); Serial.print("Software Version no: "); Serial.println(software_version); Serial.print("door locked: "); Serial.print(locked, DEC); Serial.print("\n"); Serial.print("door closed: "); Serial.print(!door_open, DEC); Serial.print("\n"); } /** * Loop * non-blocking version of each function! */ void loop() { readRFID(); doorSensor(); doorSwitch(); statusLed(); } void doorSensor(){ // pseudo digital door_open = analogRead(DOOR_SENS); if(millis() - time_door > debounce){ if (door_open <= 500 && prev_status == false){ Serial.println("Door: opened"); prev_status = true; locked = false; }else if(door_open > 500 && prev_status == true){ Serial.println("Door: closed"); prev_status = false; if(auto_lock){ Serial.println("locking door automatically..."); delay(auto_lock_delay*1000); lock(); locked = true; } } time_door = millis(); } } void doorSwitch(){ int dstimer = 0; int door_switch = analogRead(DOOR_SW); // pseudo digital if(millis() - time_switch > debounce && door_switch >= 300){ while (analogRead(DOOR_SW) >= 300) { delay(100); dstimer++; } Serial.println(door_switch,DEC); Serial.println(dstimer,DEC); if (dstimer < auto_lock_switch_time*10) { //button has been pressed less than 2 seconds = 1000/100 if (locked == false){ Serial.println("door locked"); locked = true; lock(); }else if(locked == true){ Serial.println("door unlocked"); locked = false; unlock(); } }else { // auto_unlock off/on if(auto_lock == true){ Serial.println("auto_lock off"); auto_lock = false; }else{ Serial.println("auto_lock on"); auto_lock = true; } analogWrite(ledIN, 0); // resetting output } time_switch = millis(); } } // breathing status led on the inside void statusBreathe(){ if( (status_breathe_time + breathe_delay) < millis() ){ analogWrite(ledIN, breathe_i/1.5); status_breathe_time = millis(); if (breathe_up == true){ if (breathe_i > 150) { breathe_delay = 4; } if ((breathe_i > 125) && (breathe_i < 151)) { breathe_delay = 5; } if (( breathe_i > 100) && (breathe_i < 126)) { breathe_delay = 7; } if (( breathe_i > 75) && (breathe_i < 101)) { breathe_delay = 10; } if (( breathe_i > 50) && (breathe_i < 76)) { breathe_delay = 14; } if (( breathe_i > 25) && (breathe_i < 51)) { breathe_delay = 18; } if (( breathe_i > 1) && (breathe_i < 26)) { breathe_delay = 19; } breathe_i += 1; if( breathe_i >= 255 ){ breathe_up = false; } }else{ if (breathe_i > 150) { breathe_delay = 4; } if ((breathe_i > 125) && (breathe_i < 151)) { breathe_delay = 5; } if (( breathe_i > 100) && (breathe_i < 126)) { breathe_delay = 7; } if (( breathe_i > 75) && (breathe_i < 101)) { breathe_delay = 10; } if (( breathe_i > 50) && (breathe_i < 76)) { breathe_delay = 14; } if (( breathe_i > 25) && (breathe_i < 51)) { breathe_delay = 18; } if (( breathe_i > 1) && (breathe_i < 26)) { breathe_delay = 19; } breathe_i -= 1; if( breathe_i <= 15 ){ breathe_up = true; breathe_delay = 970/2; } } } } void statusLed(){ if(auto_lock == false){ status_led = 150; }else{ // set this to > 0 if you want the status led to blink in default mode status_led = 0; if(status_led == 0){ statusBreathe(); } } if(millis() - status_led_time >= status_led && status_led != 0){ status_led_on = !status_led_on; digitalWrite(ledIN,status_led_on); status_led_time = millis(); } } void readRFID(){ byte i = 0; byte val = 0; byte checksum = 0; byte bytesRead = 0; byte tempByte = 0; byte tagBytes[6]; // "Unique" tags are only 5 bytes but we need an extra byte for the checksum char tagValue[10]; if(rfid.available()>0){ if((val = rfid.read()) == 2) { // Check for header bytesRead = 0; while (bytesRead < 12) { // Read 10 digit code + 2 digit checksum val = rfid.read(); Serial.print(val,BYTE); // Append the first 10 bytes (0 to 9) to the raw tag value if (bytesRead < 10) { tagValue[bytesRead] = val; } // Check if this is a header or stop byte before the 10 digit reading is complete if((val == 0x0D)||(val == 0x0A)||(val == 0x03)||(val == 0x02)) { break; // Stop reading } // Ascii/Hex conversion: if ((val >= '0') && (val <= '9')) { val = val - '0'; } else if ((val >= 'A') && (val <= 'F')) { val = 10 + val - 'A'; } // Every two hex-digits, add a byte to the code: if (bytesRead & 1 == 1) { // Make space for this hex-digit by shifting the previous digit 4 bits to the left tagBytes[bytesRead >> 1] = (val | (tempByte << 4)); if (bytesRead >> 1 == 5) { // If we're at the checksum byte, checksum ^= tagBytes[bytesRead >> 1]; // Calculate the checksum... (XOR) }; } else { tempByte = val; // Store the first hex digit first }; bytesRead++; // Ready to read next digit } // Send the result to the host connected via USB if (bytesRead == 12) { // 12 digit read is complete tagValue[10] = '\0'; // Null-terminate the string Serial.print("Tag read: "); for (i=0; i<5; i++) { // Add a leading 0 to pad out values below 16 if (tagBytes[i] < 16) { Serial.print("0"); } Serial.print(tagBytes[i], HEX); } Serial.println(); Serial.print("Checksum: "); Serial.print(tagBytes[5], HEX); Serial.println(tagBytes[5] == checksum ? " -- passed." : " -- error."); // Show the raw tag value //Serial.print("VALUE: "); //Serial.println(tagValue); Serial.print("door_open: "); Serial.println(door_open,DEC); // Search the tag database for this particular tag int tagId = findTag( tagValue ); // Only fire the strike plate if this tag was found in the database if( tagId > 0 ) { Serial.print("Authorized tag ID "); Serial.print(tagId); if(door_open > 500 && (last_successful_rfid_read + rfid_success_timeout) < millis() ){ Serial.print(": unlocking for "); Serial.println(tagName[tagId - 1]); // Get the name for this tag from the database unlock(); last_successful_rfid_read = millis(); delay(2000); } } else { Serial.println("Tag not authorized"); //failSound(); for (int i=0;i<7;i++){ // FIXXME nonblocking version? digitalWrite(ledOUT, HIGH); digitalWrite(ledIN, HIGH); delay(100); digitalWrite(ledOUT, LOW); digitalWrite(ledIN, LOW); delay(80); } } Serial.println(); // Blank separator line in output } bytesRead = 0; } } } /** * Fire the relay to activate the strike plate for the configured * number of seconds. */ void unlock() { digitalWrite(ledOUT, HIGH); digitalWrite(ledIN, HIGH); delay(100); // if your stepper is powerful enough you can use full speed rotateDeg(-800, 0.6); digitalWrite(ledIN, LOW); digitalWrite(ledOUT, LOW); locked = false; } void lock(){ digitalWrite(ledOUT, HIGH); digitalWrite(ledIN, HIGH); delay(100); rotateDeg(800, 1); digitalWrite(ledIN, LOW); digitalWrite(ledOUT, LOW); locked = true; } void rotate(int steps, float speed){ // power driver digitalWrite(DRIVER_SWITCH,HIGH); delay(200); //rotate a specific number of microsteps (8 microsteps per step) - (negitive for reverse movement) //speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger int dir = (steps > 0)? HIGH:LOW; steps = abs(steps); digitalWrite(DIR_PIN,dir); float usDelay = (1/speed) * 250; for(int i=0; i < steps; i++){ digitalWrite(STEP_PIN, HIGH); delayMicroseconds(usDelay); digitalWrite(STEP_PIN, LOW); delayMicroseconds(usDelay); } // unpower driver delay(200); digitalWrite(DRIVER_SWITCH,LOW); } void rotateDeg(float deg, float speed){ // power driver digitalWrite(DRIVER_SWITCH,HIGH); delay(200); //rotate a specific number of degrees (negative for reverse movement) //speed is any number from .01 -> 1 with 1 being fastest - Slower is stronger int dir = (deg > 0)? HIGH:LOW; digitalWrite(DIR_PIN,dir); int steps = abs(deg)*(1/0.225); float usDelay = (1/speed) * 250; for(int i=0; i < steps; i++){ digitalWrite(STEP_PIN, HIGH); delayMicroseconds(usDelay); digitalWrite(STEP_PIN, LOW); delayMicroseconds(usDelay); } // unpower driver delay(200); digitalWrite(DRIVER_SWITCH,LOW); } /** * Search for a specific tag in the database */ int findTag( char tagValue[10] ) { for (int thisCard = 0; thisCard < numberOfTags; thisCard++) { // Check if the tag value matches this row in the tag database if(strcmp(tagValue, allowedTags[thisCard]) == 0) { // The row in the database starts at 0, so add 1 to the result so // that the card ID starts from 1 instead (0 represents "no match") return(thisCard + 1); } } // If we don't find the tag return a tag ID of 0 to show there was no match return(0); }
i needed a version of the ‘breathing led’ for a project which would not block everything else. button presses and the actual application should run without delay. after all it would just be cosmetics
the result looks like this:
here is my non-blocking code for a breathing led with arduino:
/*
"Breathing non-blocking sleep LED."
Florian Klien 2011
blog.flo.cx
based on work from Jeremy Saglimbeni (thecustomgeek.com)
*/
#define LED 5 // any PWM led will do
unsigned long status_breathe_time = millis();
int breathe_delay = 10;
boolean breathe_up = true;
int breathe_i = 15;
void setup() { // bring the LED up nicely from being off
for(i = 0 ; i <= 15; i+=1)
{
analogWrite(11, i);
delay(5);
}
}
void loop()
{
nonBlockingBreathe();
otherImportantNonBlockingStuff();
}
void nonBlockingBreathe(){
if( (status_breathe_time + breathe_delay) < millis() ){
analogWrite(LED, breathe_i);
status_breathe_time = millis();
if (breathe_up == true){
if (breathe_i > 150) {
breathe_delay = 4;
}
if ((breathe_i > 125) && (breathe_i < 151)) {
breathe_delay = 5;
}
if (( breathe_i > 100) && (breathe_i < 126)) {
breathe_delay = 7;
}
if (( breathe_i > 75) && (breathe_i < 101)) {
breathe_delay = 10;
}
if (( breathe_i > 50) && (breathe_i < 76)) {
breathe_delay = 14;
}
if (( breathe_i > 25) && (breathe_i < 51)) {
breathe_delay = 18;
}
if (( breathe_i > 1) && (breathe_i < 26)) {
breathe_delay = 19;
}
breathe_i += 1;
if( breathe_i >= 255 ){
breathe_up = false;
}
}else{
if (breathe_i > 150) {
breathe_delay = 4;
}
if ((breathe_i > 125) && (breathe_i < 151)) {
breathe_delay = 5;
}
if (( breathe_i > 100) && (breathe_i < 126)) {
breathe_delay = 7;
}
if (( breathe_i > 75) && (breathe_i < 101)) {
breathe_delay = 10;
}
if (( breathe_i > 50) && (breathe_i < 76)) {
breathe_delay = 14;
}
if (( breathe_i > 25) && (breathe_i < 51)) {
breathe_delay = 18;
}
if (( breathe_i > 1) && (breathe_i < 26)) {
breathe_delay = 19;
}
breathe_i -= 1;
if( breathe_i <= 15 ){
breathe_up = true;
breathe_delay = 970;
}
}
}
}
original code came from thecustomgeek.com
yesterday our API (the API of qr.cx) returned rubbish for about 12 hours. i apologize for that, this will not happen again. we are working on a reimplementation which should be far more reliable.
however the thing had an upside. we were able to expose twitter bots who published this rubbish without checking. in total we found 336 twitter bots who did so. they included
Notice: Undefined variable: [...] in /[...]/qr.cx/htdocs/api/index.php[...]"
in their tweets. a human being would not do that. firstly the API is made for automated use, so why would one use that on a regular basis; secondly the error is apparent to a human user. one would not publish a tweet with the full nonsense. the bots did.
so now we can search twitter for this perfidious string and see which account is a bot. this is good, this could help twitter™ to identify malicious users/bots and protect their normal human users.

but it also helps us, the urlshortener, to safeguard the system. we can identify spam links. we can search the twitter bot’s stream for links it has shortened before. those links are most likely links to spam or fraudulent pages. disabling those would be no harm.
i’m looking forward to implementing these security features. it will definitely require a little more thinking to setup a nice safe system.
this saturday we went to see the “Airpower 11“. apparently the biggest air show in europe, and it really was huge.
it started on friday, with about 140.000 people. on saturday there were about 160.000. let’s just say: it was really crowded!
i did take some photos:









the full selection can be found in my picasa album.