Monday, April 27, 2015
Fake DS1302 chips
After wasting many hours trying to set the Trickle Charge parameters on my otherwise-obedient DS1302 chips, I eventually realised that I had counterfeit chips.
I've knocked up an Arduino sketch that will try to set the Trickle Charge byte, reporting back on success or failure - users of other hardware can still get the gist:
//written for Uno R3 or Mega
//Tests whether a DS1302 will process a change of the byte controlling Trickle Charge settings (if not, may be a fake)
//John Geddes, February 2016
#include
#include //http://playground.arduino.cc/uploads/Main/DS1302RTC.zip
const int PIN_1302_CE = A0; //5; // Chip Enable
const int PIN_1302_IO = A1; //6; // Input/Output
const int PIN_1302_SCLK = A2; //7; // Serial Clock
#define OPTION_TRICKLE_CHARGE_BYTE 0
#define OPTION_YEAR_BYTE 1
byte testResult=0;//score 1 for rtc byte ok, 2 for yeat byte ok. value of 3 means all ok
DS1302RTC my1032rtc(PIN_1302_CE, PIN_1302_IO, PIN_1302_SCLK);
void printPaddedBin(unsigned long thisValue, byte outputLength=8, boolean endLine=false){
String thisString;
String netString=String(thisValue,BIN);//no leading zeroes
byte padCharsRequired=outputLength-netString.length();
for (byte padCount=0; padCount<(padCharsRequired);padCount++){
thisString.concat("0");
}
Serial.print(thisString);
Serial.print(netString);
if (endLine){
Serial.println();
}
}
byte toggleByteAndReportOutcome(byte whichByte){
//returns 1 if ok, otherwise 0
byte addressWriteByte; //read byte has address one higher
byte retValIfOK=0;
String descString;
byte maxValueBeforeReturningTo1;
byte valueA;
byte valueB;
switch (whichByte){
case OPTION_TRICKLE_CHARGE_BYTE:
descString="TRICKLE-CHARGE";
addressWriteByte=0x90;
retValIfOK=1;
valueA=165;
valueB=166;
break;
case OPTION_YEAR_BYTE:
descString="YEAR";
addressWriteByte=0x8c;
retValIfOK=2;
valueA=B10100001;
valueB=B10100111;
break;
}
byte startingByteValue=my1032rtc.readRTC((addressWriteByte+1));
byte targetByteValue=startingByteValue+1;
if (startingByteValue==valueA){
targetByteValue=valueB;
} else {
targetByteValue=valueA;
}
Serial.print("Attempt to update ");
Serial.print(descString);
Serial.print(" byte which currently holds value of ");
Serial.print(startingByteValue);
Serial.print(", ie ");
printPaddedBin(startingByteValue, 8, false);
Serial.print(" to new value of ");
Serial.print(targetByteValue);
Serial.print(", ie ");
printPaddedBin(targetByteValue, 8, true);
my1032rtc.writeRTC(addressWriteByte,targetByteValue);
byte revisedByteValue=my1032rtc.readRTC((addressWriteByte+1));
if (revisedByteValue==targetByteValue){
Serial.print("SUCCESS - new value is ");
Serial.print(revisedByteValue);
Serial.print(", ie ");
printPaddedBin(revisedByteValue, 8, true);
return retValIfOK;
} else if (revisedByteValue==startingByteValue){
Serial.print("ERROR - updating has failed: value stayed at ");
Serial.print(revisedByteValue);
Serial.print(", ie ");
printPaddedBin(revisedByteValue, 8, true);
return 0;
} else {
Serial.print("ERROR - updating has failed: value changed but wrong - at ");
Serial.print(revisedByteValue);
Serial.print(", ie ");
printPaddedBin(revisedByteValue, 8, true);
return 0;
}
}
void setup() {
delay (2000);//time to open Serial Monitor
Serial.begin(9600);
Serial.println("DS1302 test started");
//initialise RTC to be writeable but clock STOPPED
my1032rtc.writeEN(1);
Serial.println("DS1302 set to write-enabled");
my1032rtc.haltRTC(1);//in case this helps
Serial.println("DS1302 halted");
testResult+=toggleByteAndReportOutcome(OPTION_TRICKLE_CHARGE_BYTE);
Serial.print("testResult=");
Serial.println(testResult);
testResult+=toggleByteAndReportOutcome(OPTION_YEAR_BYTE);
Serial.print("testResult=");
Serial.println(testResult);
Serial.println("\n");
switch(testResult){
case 0:
Serial.println("Failed both tests: could not update trickle-charge byte or year byte. Check connections");
break;
case 1:
Serial.println ("OK on updating trickle-charge byte but failed on year byte - looks like genuine-but-faulty chip");
break;
case 2:
Serial.println ("Failed to update trickle-charge byte but succeeded with change of year byte - this is the result you get with a FAKE DS1302");
break;
case 3:
Serial.println ("OK on both tests - GENUINE DS1302 working properly");
break;
}
}
void loop() {}
I've knocked up an Arduino sketch that will try to set the Trickle Charge byte, reporting back on success or failure - users of other hardware can still get the gist:
//written for Uno R3 or Mega
//Tests whether a DS1302 will process a change of the byte controlling Trickle Charge settings (if not, may be a fake)
//John Geddes, February 2016
#include
#include
const int PIN_1302_CE = A0; //5; // Chip Enable
const int PIN_1302_IO = A1; //6; // Input/Output
const int PIN_1302_SCLK = A2; //7; // Serial Clock
#define OPTION_TRICKLE_CHARGE_BYTE 0
#define OPTION_YEAR_BYTE 1
byte testResult=0;//score 1 for rtc byte ok, 2 for yeat byte ok. value of 3 means all ok
DS1302RTC my1032rtc(PIN_1302_CE, PIN_1302_IO, PIN_1302_SCLK);
void printPaddedBin(unsigned long thisValue, byte outputLength=8, boolean endLine=false){
String thisString;
String netString=String(thisValue,BIN);//no leading zeroes
byte padCharsRequired=outputLength-netString.length();
for (byte padCount=0; padCount<(padCharsRequired);padCount++){
thisString.concat("0");
}
Serial.print(thisString);
Serial.print(netString);
if (endLine){
Serial.println();
}
}
byte toggleByteAndReportOutcome(byte whichByte){
//returns 1 if ok, otherwise 0
byte addressWriteByte; //read byte has address one higher
byte retValIfOK=0;
String descString;
byte maxValueBeforeReturningTo1;
byte valueA;
byte valueB;
switch (whichByte){
case OPTION_TRICKLE_CHARGE_BYTE:
descString="TRICKLE-CHARGE";
addressWriteByte=0x90;
retValIfOK=1;
valueA=165;
valueB=166;
break;
case OPTION_YEAR_BYTE:
descString="YEAR";
addressWriteByte=0x8c;
retValIfOK=2;
valueA=B10100001;
valueB=B10100111;
break;
}
byte startingByteValue=my1032rtc.readRTC((addressWriteByte+1));
byte targetByteValue=startingByteValue+1;
if (startingByteValue==valueA){
targetByteValue=valueB;
} else {
targetByteValue=valueA;
}
Serial.print("Attempt to update ");
Serial.print(descString);
Serial.print(" byte which currently holds value of ");
Serial.print(startingByteValue);
Serial.print(", ie ");
printPaddedBin(startingByteValue, 8, false);
Serial.print(" to new value of ");
Serial.print(targetByteValue);
Serial.print(", ie ");
printPaddedBin(targetByteValue, 8, true);
my1032rtc.writeRTC(addressWriteByte,targetByteValue);
byte revisedByteValue=my1032rtc.readRTC((addressWriteByte+1));
if (revisedByteValue==targetByteValue){
Serial.print("SUCCESS - new value is ");
Serial.print(revisedByteValue);
Serial.print(", ie ");
printPaddedBin(revisedByteValue, 8, true);
return retValIfOK;
} else if (revisedByteValue==startingByteValue){
Serial.print("ERROR - updating has failed: value stayed at ");
Serial.print(revisedByteValue);
Serial.print(", ie ");
printPaddedBin(revisedByteValue, 8, true);
return 0;
} else {
Serial.print("ERROR - updating has failed: value changed but wrong - at ");
Serial.print(revisedByteValue);
Serial.print(", ie ");
printPaddedBin(revisedByteValue, 8, true);
return 0;
}
}
void setup() {
delay (2000);//time to open Serial Monitor
Serial.begin(9600);
Serial.println("DS1302 test started");
//initialise RTC to be writeable but clock STOPPED
my1032rtc.writeEN(1);
Serial.println("DS1302 set to write-enabled");
my1032rtc.haltRTC(1);//in case this helps
Serial.println("DS1302 halted");
testResult+=toggleByteAndReportOutcome(OPTION_TRICKLE_CHARGE_BYTE);
Serial.print("testResult=");
Serial.println(testResult);
testResult+=toggleByteAndReportOutcome(OPTION_YEAR_BYTE);
Serial.print("testResult=");
Serial.println(testResult);
Serial.println("\n");
switch(testResult){
case 0:
Serial.println("Failed both tests: could not update trickle-charge byte or year byte. Check connections");
break;
case 1:
Serial.println ("OK on updating trickle-charge byte but failed on year byte - looks like genuine-but-faulty chip");
break;
case 2:
Serial.println ("Failed to update trickle-charge byte but succeeded with change of year byte - this is the result you get with a FAKE DS1302");
break;
case 3:
Serial.println ("OK on both tests - GENUINE DS1302 working properly");
break;
}
}
void loop() {}
BBC iPlayer Radio - for older Androids
The BBC disgracefully abandoned older Android users in 2014 when they "upgraded" their iPlayer app to use separate versions for TV and for Radio. The Radio app demanded Android 4 upwards - justified on the basis that over 80% of users had suitable devices. Tough luck for the rest of us.
We were intended to use the iPlayer radio feature on the BBC website, but I found this unusable - most browsers refused to load an appropriate driver, and when I did find a workable combination, programmes might take 15 attempts to start - or not start at all.
Eventually, I found a way to get near-100% availability, and offer it here. It works on my Samsung Galaxy Player 4.2 running Android 2.3.6 - and I hope it will work for you too.
Happy listening
We were intended to use the iPlayer radio feature on the BBC website, but I found this unusable - most browsers refused to load an appropriate driver, and when I did find a workable combination, programmes might take 15 attempts to start - or not start at all.
Eventually, I found a way to get near-100% availability, and offer it here. It works on my Samsung Galaxy Player 4.2 running Android 2.3.6 - and I hope it will work for you too.
- Check that you have the BBC Media Player app loaded (it won't play stuff directly, but is needed by your browser).
- Use the Opera Mini browser. This comes with appropriate drivers to play the iPlayer Radio streams.
- If a stream refuses to start, go to Settings and look for something like "Maintain Applications". Find the BBC Media Player and delete the data - always 0.95Gb in my case. Now try again.
- If you still can't load the stream, edit the URL. If it ends "#auto", then strip off that bit. If it doesn't have "#auto" at the end, add it. Then try loading again (it might take two attempts).
Happy listening