I got a new smartphone, a Samsung Galaxy Note III, 32 GB with LTE version, model N900W8, from WIND Mobile.
I will not discuss any benchmarks or performance measurements, please check other websites for stuff like speed tests and battery life.
I got a new smartphone, a Samsung Galaxy Note III, 32 GB with LTE version, model N900W8, from WIND Mobile.
I will not discuss any benchmarks or performance measurements, please check other websites for stuff like speed tests and battery life.
The product: http://www.clearsounds.com/node/65 (product code CSQLINK), or Amazon.ca link
I got one because I love my DIY BT headphones, but my recently obtained PS3 doesn’t support A2DP. So I decided to get some form of an adapter so I can play my PS3 without using speakers.
Continue reading
I just received my SeeedStudio Bluetooth Multimeter.
I’m not going to talk about the measurement specifications and capabilities, because they are clearly stated, and you should decide for yourself if the specifications and capabilities meet your needs. This review will be more focused on the usability.
The enclosure is made with split Continue reading
I got my Raspberry Pi. I do not have an ethernet connection or Wifi dongle available, or an extra keyboard. I don’t have any Bluetooth either. I needed a substitute keyboard to use the Raspberry Pi.
For fun, I designed a little USB device, actually it has two USB devices on a small board in the shape of a stick. Two USB capable microcontrollers are on this circuit. One will connect to the Raspberry Pi, and behave like a keyboard and mouse. The other will connect to my laptop. My laptop will run software that captures keystrokes and mouse events. The laptop will tell the microcontroller what to do, so when I press a key on my laptop, the Raspberry Pi thinks the same key is pressed. (and the same with the mouse)
I wore the Pebble every day. The display is still amazing, battery life has never been a problem. There’s been firmware updates and the UI has some great improvements.
Usually when I hit my wall (my desk is in the corner beside a wall, right by my left hand, where I wear my Pebble), the Pebble handles it just fine without any scratches. But this time I hit a stone pillar outside, and it got some deep scratches.
The scratches were too deep for any conventional polishing techniques. I could try sanding it and then running it under a buffing wheel, but I do not have access to one. So I was pretty sad, especially because I already ordered some screen protectors for it.
The first lesson here is that, if you want a Pebble, you want a screen protector as soon as possible.
With that said, I’m not the kind of person who just gives up. When the screen protector arrived, I did an experiment.
Petroleum jelly, aka Vaseline, has a similar refractive index to most plastics. I know this because I know that you can repair scratched LCD monitors by spearing Vaseline over it. The Vaseline will fill the scratch, and since the refractive index is matched, the light travels through it without bending or reflections, this makes the scratch invisible. I smeared some Vaseline over my Pebble, and the scratches disappeared. Great!
The next problem is that the Vaseline will rub off and wash off eventually, unless you cover it up somehow. So the next part of the trick is to install a screen protector to cover up the Vaseline. So clean the screen with soapy water to get rid of any oil, dry it off, smear some Vaseline on it, apply the screen protector, and squeeze out any bubbles. Then let it sit still for an entire day or two. Make sure your hands are clean and no dust ever lands on it while doing this.
I highly recommend using Gadget Wraps for this, because their “wraps” is two parts, one part is a sticky decorative part (the brushed metal one looks amazing on a black Pebble) and a second part which is a clear screen protector. The sticker has a rectangular cutout in the center, where the screen protector sits in, in the end, everything is perfectly smooth. This makes my method of hiding scratches much easier because the sticker traps the screen protector, making it easier to squish out the bubbles.
Some pictures: http://i.imgur.com/QOvWHYz.jpg and http://i.imgur.com/fDLZCHL.jpg
On my old website, the article “MMC/SD Card and FAT Tutorial” was really popular (it still holds almost top ranking on Google). However, the information there is so old that most of it is obsolete. Elm-Chan’s FatFs library has been updated many times since then, rendering some of the old webpage I wrote obsolete. But I will put up some of the old content here so you may still see it.
The GG button (link to original website) is a button that yells “GG” when you press it. Similar to the Staples Easy Button.
I modified it so that it has a USB port and it becomes a USB keyboard when you plug it into a computer. When you press the button, it types out a certain key sequence. The key sequence is such that it chats “GG WP” to an opponent in Starcraft II, and then surrenders the game (by pressing F10, then ‘n’).
This is a PPM signal splitter for use with the VEX radio transmitter/receiver kit sold at All Electronics (item is now gone from their web site, this article itself is extremely old and outdated because newer technology has arrived)
For $30 at All Electronics, you can buy a 6 channel radio transmitter and receiver. The transmitter is excellent for $30, trim, scaling, mixing are all programmable on the transmitter itself and it stores several configurations. The receiver only has one output pin, which outputs a PPM signal which needs to be split into individual channels in order to be able to control servos.
If you put the receiver right side up and with the socket facing you, the pin on the far left is the Vdd pin, connect this to a regulated 5 volt power supply, the middle left pin is the PPM output pin (it is open collector so a pull up resistor is needed), and the middle right pin is the Vss pin, connect this to your circuit’s ground, the far right pin is not connected to anything inside the receiver.
The 6 channel PPM signal has 7 periods of high and low pulses, each of these pulses all start with a high period of 500 microseconds, and a low period of varying lengths. The first low period is a sync pulse with a fixed low period of about 7 milliseconds, this exceptionally long low period indicates the next rising edge of the PPM signal will indicate the pulse start for channel 1. The period from the rising edge to rising edge of the a pulse is equal to the period of the high pulse that should be sent to the servo.
#include <avr/io.h> #include <avr/interrupt.h> #define BAUD 9600 // define baud rate here #include <util/setbaud.h> #define width_500 ((F_CPU * 5) / 10000) // calculates ticks for 0.5ms // pin and port renaming #define in_port PORTD #define in_pinin PIND #define in_ddr DDRD #define in_pin 6 #define LED_A_pin 4 #define LED_B_pin 5 #define out_port PORTB #define out_ddr DDRB // global variables static volatile unsigned long ovf_cnt; // overflow counter static volatile unsigned char chan_cnt; // channel counter static volatile unsigned char mask_cnt; // used to determin next pin static volatile unsigned int chan_width[8]; // stores pulse width in clock ticks static volatile unsigned int chan_width_temp[8]; static volatile unsigned int last_capt; // time of last capture, used to find difference static volatile unsigned char data_ready; // 1 if data is good, 0 if transmitter is off static volatile unsigned char next_mask; // next port mask to apply static volatile unsigned char busy_flag; // input capture interrupt vector ISR(TIMER1_CAPT_vect) { out_port = next_mask; // apply port mask to pulse pin mask_cnt++; // next pin unsigned long t_ovf = ovf_cnt; // store overflow counter in case another overflow occurs during interrupt ovf_cnt = 0; unsigned long t_icr = ICR1; // convert to unsigned long // calculate total time using overflows and time difference unsigned long t = ((t_icr | 0x10000) - last_capt) & 0xFFFF; if(t_icr < last_capt) { t_ovf--; } t += 0x10000 * t_ovf; last_capt = ICR1; // if pulse is longer than 3ms, then it's a sync pulse if(t > width_500 * 6) { chan_cnt = 0; if(data_ready == 0) { data_ready = 1; } } else // if pulse is shorter than 3ms, then it's a servo pulse { chan_width[chan_cnt] = t; // store time if(busy_flag == 0) { chan_width_temp[0] = chan_width[0]; chan_width_temp[1] = chan_width[1]; chan_width_temp[2] = chan_width[2]; chan_width_temp[3] = chan_width[3]; chan_width_temp[4] = chan_width[4]; chan_width_temp[5] = chan_width[5]; chan_width_temp[6] = chan_width[6]; chan_width_temp[7] = chan_width[7]; } chan_cnt++; // next channel if(chan_cnt >= 4 && data_ready != 0) // last channel, data is now good, reset to first pin { data_ready = 2; mask_cnt = 0; } } next_mask = _BV(mask_cnt); // prepare mask } // timer overflow interrupt vector ISR(TIMER1_OVF_vect) { ovf_cnt++; if(ovf_cnt >= 7) // if too many, then transmitter is missing { data_ready = 0; } } int main() { // initialize variables ovf_cnt = 0; chan_cnt = 0; mask_cnt = 0; data_ready = 0; MCUCR |= _BV(PUD); // no pull-ups // initialize ports out_port = 0; out_ddr = 0; in_ddr |= _BV(LED_A_pin) | _BV(LED_B_pin); in_ddr &= 0xFF ^ _BV(in_pin); // initialize serial port UBRRH = UBRRH_VALUE; // set baud rate UBRRL = UBRRL_VALUE; UCSRB = _BV(RXEN) | _BV(TXEN); // enable port // initialize timer TCCR1B = 1 | _BV(ICES1); // start timer, input capture on rising edge TIMSK = _BV(TOIE1) | _BV(ICIE1); // enable interrupts sei(); // enable global interrupts while(1) { if(data_ready == 2) { // enable output if data is good, light LED out_ddr = 0xFF; in_port |= _BV(LED_A_pin); } else { // disable output if transmitter is missing, LED off out_ddr = 0; in_port &= 0xFF ^ _BV(LED_A_pin); } busy_flag = 0; if(bit_is_set(UCSRA, RXC)) // if command received { unsigned char ch = UDR; if(ch != 0) // if not null command { UDR = data_ready; // send status busy_flag = 1; unsigned int t = chan_width_temp[ch - 1]; // fetch from array unsigned char h = (t & 0xFF00) >> 8; // get high byte unsigned char l = t & 0xFF; // get low byte loop_until_bit_is_set(UCSRA, TXC); // wait for finish UCSRA |= _BV(TXC); // clear finished flag // send two bytes, most significant byte first UDR = h; loop_until_bit_is_set(UCSRA, TXC); // wait for finish UCSRA |= _BV(TXC); // clear finished flag UDR = l; loop_until_bit_is_set(UCSRA, TXC); // wait for finish UCSRA |= _BV(TXC); // clear finished flag } } } return 0; }
I’ve recently rewrote the code from scratch, this is actually version 2. This new version eliminates any timing errors because everything is handled by the 16 bit timer’s input capture feature. Timer overflows help determine whether or not the transmitter is missing, and if it is missing, the port is disabled.
The serial port can be used to retrieve the pulse width of the channels. The baud rate is defined when you compile the code. First send the channel number, then wait for a three byte reply, the first byte will be 0x01 if the data is good, or 0x00 if the transmitter is missing, the next two bytes is the width of the channel pulse as a 16 bit integer, most significant byte being sent first. Pulse width is given in clock cycles and thus it varies based on the clock frequency you choose to use.