Reset clock fuse bits on AVR

I am just starting to learn about AVR programming and I really enjoy myself! 😀
Except maybe when I play with the fuse bytes and I screw things up…

Basically, I was using a ATtiny13A microcontroller and I configured the fuse bytes to use the internal low-frequency oscillator running at 128kHz. I thought it would be a good idea to check if my simple blinking LED program was still working with this internal oscillator.
The good news is the LED was still blinking. But the bad news is I wasn’t able to reprogram the chip anymore… 🙁 After some research, I figure it out: the ISP interface needs to run slower than the microcontroller in order to flash it! And obviously, my ISP interface was running faster than 128kHz…

These microcontrollers are very cheap so I could just throw it away. But I am not the kind of person to give up without a fight! 😉
So I talked to my friend Google and he suggested me to read the following article: Fixing a bad frequency fuse bit on an AVR.
I followed the instructions and here is the output:

C:\AVR>avrdude -p attiny13 -P usb -c usbtiny -tuF

avrdude: initialization failed, rc=-1
avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.00s

avrdude: Device signature = 0x000000
avrdude: Yikes! Invalid device signature.
avrdude: Expected signature for ATtiny13 is 1E 90 07
avrdude> sck 1000
>>> sck 1000
avrdude: Setting SCK period to 250 usec
avrdude> e
>>> e
avrdude: erasing chip
avrdude> sck 10
>>> sck 10
avrdude: Setting SCK period to 10 usec
avrdude> quit
>>> quit

avrdude done. Thank you.

However, there is a missing instruction in this article. Indeed, these instructions erased the chip but didn’t fix the fuses, so now it’s blank but the fuses are still wrong!
In order to reprogram the fuses, you need to use the ‘-B250’ in the command line:

avrdude -p attiny13 -P usb -c usbtiny -U lfuse:w:0x6A:m -U hfuse:w:0xFF:m -B250

, , , ,

18 Comments

JDBC and the “zero” date

A few weeks ago, I was in the process of writing a little script in Java to extract data from a MySQL database. Because this is what we can call a micro project, I decided to simply use JDBC to talk to the database.

But when I tried to run my script, I got the following exception:

java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Date
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:910)
	at com.mysql.jdbc.ResultSet.getDateFromString(ResultSet.java:2032)
	at com.mysql.jdbc.ResultSet.getDate(ResultSet.java:1956)
	at com.mysql.jdbc.ResultSet.getDate(ResultSet.java:1924)
	at com.mysql.jdbc.ResultSet.getDate(ResultSet.java:1972)
	...

After looking at the database, it seems that this exception has been thrown because the fields of type datetime contain the value ‘0000-00-00 00:00:00’. Don’t ask me why I have this kind of value in the database! Obviously, we would prefer to have a NULL value instead of a “zero” date.

There are two solutions to fix this problem:

  1. Replace all the “zero” dates by NULL using the following SQL query:

    UPDATE table SET datefield = NULL WHERE datefield = '0000-00-00 00:00:00';
    
  2. Add the parameter zeroDateTimeBehavior=convertToNull to the connection url which will automatically convert the “zero” date to NULL. Please find below an example of connection url with this parameter:

    jdbc:mysql://localhost:3306/dbname?zeroDateTimeBehavior=convertToNull
    

Personally, I choose the second solution as I didn’t want to change the original data of the database.

, , , ,

No Comments

Permissions ignored with Samba

After the issue regarding the ntpd process, I encountered another problem with my D-Link DNS-313. This time it was about permissions problem using Samba.

Because I have multiple user accounts sharing the same data, I added the following lines into the Samba configuration file (smb.conf):

create mask = 0774
directory mask  = 0775
force create mode = 0774
force directory mode = 0775

With these properties, a user will have the permission to read any files created by another user and will also be able to edit them if both users are part of the same group.

However, it appeared that these properties had been ignored by Samba! 🙁 Please note that the client was a Mac OS X 10.6.6 (Snow Leopard) and the Samba version on the NAS was 3.0.25a.

After some googling on the web, I found the following explanation on the contribs.org forum:

Samba 3.0.2x has the ‘unix extensions’ option set to ‘on’ by default. This allows Unix users who write to the Samba shares to set their own permissions bits. Mac OS X up until now has never attempted to do this, but from Leopard, any directory that gets created on a Samba share, get chmod’ed through this Samba extension.

Alright, this is clear enough! This means that we have to set the ‘unix extensions’ option to ‘no’ in our Samba configuration file:

unix extensions = no

The problem should be gone after restarting Samba. 🙂

, , , , , ,

7 Comments

ntpd process on D-Link DNS-313

During the configuration of a D-Link DNS-313 which is basically a NAS (Network-Attached Storage), I got a serious but easy-to-fix problem. 🙂

In order to get access to the box by command line, I installed the Fonz fun_plug. I then wanted to automatically synchronise the internal time with some NTP Pool Time Servers. But, for some reason, the version of the ntpd process provided with fun_plug is completely freezing the NAS. I wasn’t able to find the root cause of it, trust me, I tried everything I could think of!
Please also note that the same process is working perfectly fine on his brother, the D-Link DNS-323. As I said, I can’t explain why… 🙄

But there is a good news! The ntpd process is actually part of the D-Link DNS-313 firmware. And it is working fine! 😀 After double-checking, this process is however NOT part of the D-Link DNS-323 firmware. Why is that? Maybe D-Link got complaints from DNS-313 users and fixed it? Who knows…

Anyway, in order to get the ntpd process to work on the D-Link DNS-313, you need to replace the content of your ntpd startup script (/ffp/start/ntpd.sh) by the one below:

#!/ffp/bin/sh

# PROVIDE: ntpd
# REQUIRE: SERVERS
# BEFORE: LOGIN

. /ffp/etc/ffp.subr

name="ntpd"
command="/usr/sbin/ntpd"
ntpd_flags="-f /ffp/etc/ntpd.conf"
required_files="/ffp/etc/ntpd.conf"
start_cmd="ntpd_start"

ntpd_start()
{
    # remove rtc and daylight cron jobs
    crontab -l | grep -vw '/usr/sbin/daylight' | grep -vw '/usr/sbin/rtc' | crontab -

    proc_start $command
}

run_rc_command "$1"

, , , , , , , , ,

1 Comment

Update your Twitter status with Java

This article has been written for the version 2.1.7 of Twitter4J. If you want to use a newer version, please read the following article: Changes in Twitter4J 2.2.5

Some time ago, Twitter stopped supporting “Basic Authentication” in the Twitter API, in favour of a new, more secure system, OAuth.
Please read this article for more information about OAuth: http://en.wikipedia.org/wiki/OAuth

The basic authentication was straightforward, you only needed to provide the Twitter username and password in order to authenticate and send tweets from an application. That was it!
But things get more complicated with the new authentication. 🙁
You now need FOUR credentials:

  • A consumer key;
  • A consumer secret;
  • An access token;
  • An access token secret.

Please follow the instructions below to get these credentials for your application:

  1. Register the site as an application on http://dev.twitter.com/apps/new
    • If you’re not currently logged in, use the Twitter username and password which you want associated with this site
    • Your Application’s Name will be what shows up after “via” in your twitter stream. Your application name cannot include the word “Twitter.” I suggest using the name of your web site.
    • Your Application Description can be whatever you want
    • Application Type should be set on Browser
    • The Callback URL should be the URL of your web application
    • Default Access type must be set to Read & Write (this is NOT the default)

    Once you have registered your site as an application, you will be provided with a consumer key and a consumer secret.

  2. Get the access token executing the following code:
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    import twitter4j.Twitter;
    import twitter4j.TwitterException;
    import twitter4j.TwitterFactory;
    import twitter4j.http.AccessToken;
    import twitter4j.http.RequestToken;
    
    public class TwitterAccessToken {
    	private static final String CONSUMER_KEY = "[your consumer key]";
    	private static final String CONSUMER_SECRET = "[you consumer secret]";
    	
    	public static void main(String[] args) throws Exception {
     		Twitter twitter = new TwitterFactory().getInstance();
    		twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
    		RequestToken requestToken = twitter.getOAuthRequestToken();
    		AccessToken accessToken = null;
    		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    		while (null == accessToken) {
    			System.out.println("Open the following URL and grant access to your account:");
    			System.out.println(requestToken.getAuthorizationURL());
    			System.out.print("Enter the PIN (if available) or just hit enter.[PIN]:");
    			String pin = br.readLine();
     			try {
    				if (pin.length() > 0) {
    					accessToken = twitter.getOAuthAccessToken(requestToken, pin);
    				} else {
    					accessToken = twitter.getOAuthAccessToken();
    				}
    			} catch (TwitterException e) {
    				if (401 == e.getStatusCode()) {
    					System.err.println("Unable to get the access token.");
    				} else {
    					e.printStackTrace();
    				}
    			}
    		}
    
    		System.out.println("Access Token: " + accessToken.getToken());
    		System.out.println("Access Token Secret: " + accessToken.getTokenSecret());
    	}
    }
    

    Once you have executed this script and followed the instructions, you will be provided with an access token and an access token secret.

Finally, here is the code to update your Twitter status using the new credentials:

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.conf.ConfigurationContext;
import twitter4j.http.AccessToken;
import twitter4j.http.OAuthAuthorization;

public class TwitterTest {
	private static final String ACCESS_TOKEN = "[your access token]";
	private static final String ACCESS_TOKEN_SECRET = "[your access token secret]";
	private static final String CONSUMER_KEY = "[your consumer key]";
	private static final String CONSUMER_SECRET = "[you consumer secret]";
	
    public static void main(String[] args) {
    	AccessToken accessToken = new AccessToken(ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
    	OAuthAuthorization authorization = new OAuthAuthorization(ConfigurationContext.getInstance(), CONSUMER_KEY, CONSUMER_SECRET, accessToken);
    	Twitter twitter = new TwitterFactory().getInstance(authorization);
		try {
			twitter.updateStatus("Hello World!");
		} catch (TwitterException e) {
			System.err.println("Error occurred while updating the status!");
			return;
		}
        System.out.println("Successfully updated the status.");
    }
}

Please note that this code is using the Java library Twitter4J which helps to integrate a Java application with the Twitter service.

, , , , ,

9 Comments