A while back I posted a video that showed a strange bug that was happening with my oscilloscope LCD program. It used U8GLib or the Universal 8 Bit Graphics Library. The video is available at, http://youtu.be/1qPy6FVSllY
** UPDATE ** This problem is caused by updating the data while it is being displayed. The update must not happen within the display loop.
Then I made a perfectly working oscilloscope using the Universal TFT Library and a better LCD. So then I thought I would go back and see what was the problem with U8GLib.
To rule out the LCD display I purchased a KS0108 compatible display because I could run it with its own support software or with the U8GLib. With the KS0108 driver, I could not scale the amplitude of the input waveform, a new issue. However the sine wave turned out perfectly using the KS0108 driver. Then the same software really went crazy when I tried to use the U8GLib drivers. Here is the video on YouTube, http://youtu.be/l-I4vf83OIc
Does anyone else have this problem or know of a solution??
Here is a picture of what the display should look like;
But this is what happens when you move the position control to center the sine wave;
Thursday, June 20, 2013
Monday, June 17, 2013
Six channel 3 Million samples per second Arduino powered logic analyzer
I DID IT! I not only got the six channel logic analyzer to work, but I have also succeeded in breaking the 2 million samples per second limit.
Here is the video of it working on YouTube: YouTube Video
Here is a close up of the screen showing the outputs of a 74LS390, with a 10 MC clock input. The top trace is 100 KC and the bottom one is 1 MC.
How did I do it? The sample rate is much faster, if you code it like this:
sample[1]=PINC
sample[2]=PINC
sample[3]=PINC
sample[4]=PINC
sample[5]=PINC
sample[6]=PINC
sample[7]=PINC
sample[8]=PINC
sample[9]=PINC
sample[10]=PINC
etc.
It takes a while to type in the code, but using a "loop" slows the sampling time down by more than 50%!
Blogger keeps trashing my code buy hopefully here it is;
Here is the video of it working on YouTube: YouTube Video
Here is a close up of the screen showing the outputs of a 74LS390, with a 10 MC clock input. The top trace is 100 KC and the bottom one is 1 MC.
How did I do it? The sample rate is much faster, if you code it like this:
sample[1]=PINC
sample[2]=PINC
sample[3]=PINC
sample[4]=PINC
sample[5]=PINC
sample[6]=PINC
sample[7]=PINC
sample[8]=PINC
sample[9]=PINC
sample[10]=PINC
etc.
It takes a while to type in the code, but using a "loop" slows the sampling time down by more than 50%!
Blogger keeps trashing my code buy hopefully here it is;
/***********************************
128 by 64 LCD Logic Analyzer 6 channel and 3Mb/s
By Bob Davis
Uses Universal 8bit Graphics Library, http://code.google.com/p/u8glib/
Copyright (c) 2012, olikraus@gmail.com All rights reserved.
********************************************/
#include "U8glib.h"
// 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, di=17,rw=16
//U8GLIB_ST7920_128X64_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 18, 17, 16);
// **** NOTE **** I Moved the three control pins !!!
U8GLIB_ST7920_128X64_4X u8g(8, 9, 10, 11, 4, 5, 6, 7, 1, 2, 3);
int Sample[128];
int Input=0;
int OldInput=0;
int xpos=0;
void u8g_prepare(void) {
u8g.setFont(u8g_font_6x10);
u8g.setFontRefHeightExtendedText();
u8g.setDefaultForegroundColor();
u8g.setFontPosTop();
}
void DrawMarkers(void) {
u8g.drawFrame (0,0,128,64);
u8g.drawPixel (20,1);
u8g.drawPixel (40,1);
u8g.drawPixel (60,1);
u8g.drawPixel (80,1);
u8g.drawPixel (100,1);
u8g.drawPixel (20,62);
u8g.drawPixel (40,62);
u8g.drawPixel (60,62);
u8g.drawPixel (80,62);
u8g.drawPixel (100,62);
}
void draw(void) {
u8g_prepare();
DrawMarkers();
// wait for a trigger of a positive going input
Input=digitalRead(A0);
while (Input != 1){
Input=digitalRead(A0);
}
// collect the analog data into an array
// No loop is about 50% faster!
Sample[1]=PINC; Sample[2]=PINC; Sample[3]=PINC; Sample[4]=PINC;
Sample[5]=PINC; Sample[6]=PINC; Sample[7]=PINC; Sample[8]=PINC;
Sample[9]=PINC; Sample[10]=PINC; Sample[11]=PINC; Sample[12]=PINC;
Sample[13]=PINC; Sample[14]=PINC; Sample[15]=PINC; Sample[16]=PINC;
Sample[17]=PINC; Sample[18]=PINC; Sample[19]=PINC; Sample[20]=PINC;
Sample[21]=PINC; Sample[22]=PINC; Sample[23]=PINC; Sample[24]=PINC;
Sample[25]=PINC; Sample[26]=PINC; Sample[27]=PINC; Sample[28]=PINC;
Sample[29]=PINC; Sample[30]=PINC; Sample[31]=PINC; Sample[32]=PINC;
Sample[33]=PINC; Sample[34]=PINC; Sample[35]=PINC; Sample[36]=PINC;
Sample[37]=PINC; Sample[38]=PINC; Sample[39]=PINC; Sample[40]=PINC;
Sample[41]=PINC; Sample[42]=PINC; Sample[43]=PINC; Sample[44]=PINC;
Sample[45]=PINC; Sample[46]=PINC; Sample[47]=PINC; Sample[48]=PINC;
Sample[49]=PINC; Sample[50]=PINC; Sample[51]=PINC; Sample[52]=PINC;
Sample[53]=PINC; Sample[54]=PINC; Sample[55]=PINC; Sample[56]=PINC;
Sample[57]=PINC; Sample[58]=PINC; Sample[59]=PINC; Sample[60]=PINC;
Sample[61]=PINC; Sample[62]=PINC; Sample[63]=PINC; Sample[64]=PINC;
Sample[65]=PINC; Sample[66]=PINC; Sample[67]=PINC; Sample[68]=PINC;
Sample[69]=PINC; Sample[70]=PINC; Sample[71]=PINC; Sample[72]=PINC;
Sample[73]=PINC; Sample[74]=PINC; Sample[75]=PINC; Sample[76]=PINC;
Sample[77]=PINC; Sample[78]=PINC; Sample[79]=PINC; Sample[80]=PINC;
Sample[81]=PINC; Sample[82]=PINC; Sample[83]=PINC; Sample[84]=PINC;
Sample[85]=PINC; Sample[86]=PINC; Sample[87]=PINC; Sample[88]=PINC;
Sample[89]=PINC; Sample[90]=PINC; Sample[91]=PINC; Sample[92]=PINC;
Sample[93]=PINC; Sample[94]=PINC; Sample[95]=PINC; Sample[96]=PINC;
Sample[97]=PINC; Sample[98]=PINC; Sample[99]=PINC; Sample[100]=PINC;
Sample[101]=PINC; Sample[102]=PINC; Sample[103]=PINC; Sample[104]=PINC;
Sample[105]=PINC; Sample[106]=PINC; Sample[107]=PINC; Sample[108]=PINC;
Sample[109]=PINC; Sample[110]=PINC; Sample[111]=PINC; Sample[112]=PINC;
Sample[113]=PINC; Sample[114]=PINC; Sample[115]=PINC; Sample[116]=PINC;
Sample[117]=PINC; Sample[118]=PINC; Sample[119]=PINC; Sample[120]=PINC;
Sample[121]=PINC; Sample[122]=PINC; Sample[123]=PINC; Sample[124]=PINC;
Sample[125]=PINC; Sample[126]=PINC; Sample[127]=PINC;
// display the collected analog data from array
for(int xpos=0; xpos<128; xpos++) {
u8g.drawLine (xpos, ((Sample[xpos]&B00000001)*4)+4, xpos, ((Sample[xpos+1]&B00000001)*4)+4);
u8g.drawLine (xpos, ((Sample[xpos]&B00000010)*2)+14, xpos, ((Sample[xpos+1]&B00000010)*2)+14);
u8g.drawLine (xpos, ((Sample[xpos]&B00000100)*1)+24, xpos, ((Sample[xpos+1]&B00000100)*1)+24);
u8g.drawLine (xpos, ((Sample[xpos]&B00001000)/2)+34, xpos, ((Sample[xpos+1]&B00001000)/2)+34);
u8g.drawLine (xpos, ((Sample[xpos]&B00010000)/4)+44, xpos, ((Sample[xpos+1]&B00010000)/4)+44);
u8g.drawLine (xpos, ((Sample[xpos]&B00100000)/8)+54, xpos, ((Sample[xpos+1]&B00100000)/8)+54);
}
}
void setup(void) {
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
pinMode(A4, INPUT);
pinMode(A5, INPUT);
// assign default color value
if ( u8g.getMode() == U8G_MODE_R3G3B2 )
u8g.setColorIndex(255); // RGB=white
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT )
u8g.setColorIndex(3); // max intensity
else if ( u8g.getMode() == U8G_MODE_BW )
u8g.setColorIndex(1); // pixel on, black
}
void loop(void) {
// picture loop
// u8g.firstPage();
do { draw(); }
while( u8g.nextPage() );
// rebuild the picture after some delay
delay(100);
}
Thursday, June 13, 2013
Help my Arduino Logic Analyzer crashes when I display more than 2 channels
My two channel logic analizer works very well, the video is even on youTube. Here is a link to it: http://www.youtube.com/watch?v=lrrpdXiO8Nc
This is what it looks like:
However when I try to display more than two channels the display crashes. I wonder if it is a bug in the display software. Perhaps there is a problem with the UTFT library displaying that much information?
Here is a picture of the crashed display:
Any suggestions or ideas? I have already made the memory reducing change in the UTFT library and that did not fix the problem.
SOLUTION? The Arduino will crash if you open and access more that 5 arrays at a time. Basically is is a bug in the Arduino code. My solution was to only use one array for a six channel logic analyzer and now it is working great. I will post something about it soon.
This is what it looks like:
However when I try to display more than two channels the display crashes. I wonder if it is a bug in the display software. Perhaps there is a problem with the UTFT library displaying that much information?
Here is a picture of the crashed display:
Any suggestions or ideas? I have already made the memory reducing change in the UTFT library and that did not fix the problem.
SOLUTION? The Arduino will crash if you open and access more that 5 arrays at a time. Basically is is a bug in the Arduino code. My solution was to only use one array for a six channel logic analyzer and now it is working great. I will post something about it soon.
Friday, June 7, 2013
Arduino LCD Projects book
Update: "Arduino LCD Projects" is now on Amazon, eBay and CreateSpace. Here is a cover shot:
My Arduino LCD Projects book is almost ready to publish!
Here is a YouTube video of one of the projects,
Here is the Table of Contents so far:
My Arduino LCD Projects book is almost ready to publish!
Here is a YouTube video of one of the projects,
Here is the Table of Contents so far:
Introduction
1. Introduction to
LCD’s
2. Installing the
Arduino Drivers
3. Single Line LCD 16
by 1
Temperature Display
4. Two Line LCD 16 by
2
Indoor/Outdoor temperature display
Simulated analog meter
Bar graph meter
5. Two Line LCD 40 by
2
Six analog inputs
Stereo bar graph meter
6. Four Line LCD 20
by 4
Four temperature display
Dual simulated analog meter
7. Low Resolution
Graphics LCD 48 by 84
Text display test program
Six analog inputs displayed
Simple Arduino oscilloscope
Analog meter simulation
8. Medium Resolution
Graphics LCD 128 by 64
Analog meter simulation
Six channel Logic Analyzer
Better Arduino oscilloscope
Better Arduino oscilloscope
9. High Resolution
Graphics LCD 320 by 240
Analog meter simulation
Six channel logic analyzer
External AtoD Oscilloscope
Analog meter simulation
Six channel logic analyzer
External AtoD Oscilloscope
Bibliography
Tuesday, May 28, 2013
Silent Radio LED sign, removing the three Green LED arrays
I decided to saw off the three Green LED arrays. To my surprise, I lost three columns of the red Arrays as well as clock and data. To get the clock and data going again I had to tap into the first 4015 clock and data in. To fix the three missing columns I had to tap into the first three outputs of the first 4015 and route them through inverters and resistors to the first three columns. You can see those mods in the picture below.
Then I also added 82 ohm resistors across the 100 ohm resistors to get a little more brightness. They can be seen in this picture.
Then I also added 82 ohm resistors across the 100 ohm resistors to get a little more brightness. They can be seen in this picture.
Wednesday, May 15, 2013
16 by 40 Dual Color LED Sign being sold on eBay Part 2
I have finally made the sign work! It takes a slight trick in the code to send the serial bit to the 4015's for the rows. It is " if (row= =0) digitalWrite(OutEnable, LOW);" in the code.
Here is what it looked like when it first came to life. I was sending the code for making a smiley face.
This is what it looks like with an Arduino running the code that is listed below.
This is what it looks like connected to an Arduino Pins 1-6, and a 5 volt 2.5 amp AC adapter. For the schematic and pin connections see my older post on this sign.
Here is the code to make it work;
Here is what it looked like when it first came to life. I was sending the code for making a smiley face.
This is what it looks like with an Arduino running the code that is listed below.
This is what it looks like connected to an Arduino Pins 1-6, and a 5 volt 2.5 amp AC adapter. For the schematic and pin connections see my older post on this sign.
Here is the code to make it work;
//********************************************//
// Name : LED 24x40 array Driver
// Author : Bob Davis
// Date : 12 May, 2013
// Version : 1.0
//********************************************//
// Pins for the clocks and data
int TCLK = 1;
int TSerial = 5;
int BCLK = 6;
int BSerial = 3;
int Strobe = 4;
int OutEnable = 2;
// arrays to say Arduino
byte Tbitmap[][8] = { //red characters
{0, 4, 10, 17, 17, 31, 17, 17}, //A
{0, 0,0,0,0,0,0,0},
{0, 28, 18, 17, 17, 17, 18, 28}, //D
{0, 0,0,0,0,0,0,0},
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 14, 17, 17, 17, 17, 17, 14}, //O
};
byte Bbitmap[][8] = { //green characters
{0, 4, 10, 17, 17, 31, 17, 17}, //A
{0, 30, 17, 17, 30, 20, 18, 17}, //R
{0, 0,0,0,0,0,0,0},
{0, 17, 17, 17, 17, 17, 17, 14}, //U
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 0,0,0,0,0,0,0},
{0, 14, 17, 17, 17, 17, 17, 14}, //O
};
// Set the pins to output to the array
void setup() {
pinMode(TCLK, OUTPUT);
pinMode(TSerial, OUTPUT);
pinMode(BCLK, OUTPUT);
pinMode(BSerial, OUTPUT);
pinMode(Strobe, OUTPUT);
pinMode(OutEnable, OUTPUT);
}
void loop() {
for (int row = 0; row < 8; row++){ //there are actually 16 rows
for (int character = 7; character >=0; character--){
for (int shiftbit = 0; shiftbit < 6; shiftbit++){
digitalWrite(TSerial, HIGH);
digitalWrite(BSerial, HIGH);
if bitRead(Tbitmap[character][row],shiftbit) digitalWrite(TSerial, LOW);
if bitRead(Bbitmap[character][row],shiftbit) digitalWrite(BSerial, LOW);
digitalWrite(TCLK, HIGH);
digitalWrite(TCLK, LOW);
digitalWrite(BCLK, HIGH);
digitalWrite(BCLK, LOW);
} }
digitalWrite(OutEnable, HIGH); // turns off display
if (row==0) digitalWrite(OutEnable, LOW); // turns on display
//latch the data
digitalWrite(Strobe, LOW);
digitalWrite(Strobe, HIGH);
digitalWrite(OutEnable, LOW); // turns on display
delay(.5);
} }
Thursday, May 9, 2013
Dual Color Scrolling LED sign using Cadaces modules and Arduino.
A lot of people have requested that I write a dual color scrolling program for the Cadaces modules. Well I have done that! I have also reversed the scrolling by turning the sign over. Turn the sign over so that the Arduino now connects on the left side. This also uses the new quick and easy connection pinout.
Here is a link to the video on YouTube:
http://youtu.be/znCA6V8arLw
Here is the code (If blogger will let me upload it).
Here is a link to the video on YouTube:
http://youtu.be/znCA6V8arLw
Here is the code (If blogger will let me upload it).
//**************************************************************//
// Name : Cadaces dual color Scrolling //
// Author : Bob Davis //
// Date : 2 May, 2013 //
// Version : 1.0 //
// Based on work of Hari Wiguna - http://g33k.blogspot.com/ //
//****************************************************************
// Pins for the row and data drivers
int row1Pin = 2;
int row2Pin = 7;
int row3Pin = 1;
int rowEnable = 8;
int rclockPin = 6;
int clockPin = 3;
int dataPin = 5;
int gdataPin = 4;
// Set the pins to output to the circuit
void setup() {
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(row1Pin, OUTPUT);
pinMode(row2Pin, OUTPUT);
pinMode(row3Pin, OUTPUT);
pinMode(rowEnable, OUTPUT);
pinMode(rclockPin, OUTPUT);
pinMode(gdataPin, OUTPUT);
}
//=== B I T M A P ===
// Bits in this array represents one LED of the matrix
// 8 is number of rows, 10 is number of LED matrixes we have
byte bitmap[8][10]; // Change the 10 to however many matrices you want to use.
byte gbitmap[8][10]; // Change the 10 to however many matrices you want to use.
int numZones = sizeof(bitmap) / 8;
//int numZones = sizeof(gbitmap) / 8;
// I will refer to each group of 8 columns (represented by one matrix) as a Zone.
int maxZoneIndex = numZones-1;
int numCols = numZones * 8;
//=== F O N T ===
// Font courtesy of aspro648
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203747843/22
// First char is @, next is A, B, etc. Only upper case, no symbols.
// The @ will display as space character.
byte alphabets[][5] = {
{0,0,0,0,0},
{31, 36, 68, 36, 31},
{127, 73, 73, 73, 54},
{62, 65, 65, 65, 34},
{127, 65, 65, 34, 28},
{127, 73, 73, 65, 65},
{127, 72, 72, 72, 64},
{62, 65, 65, 69, 38},
{127, 8, 8, 8, 127},
{0, 65, 127, 65, 0},
{2, 1, 1, 1, 126},
{127, 8, 20, 34, 65},
{127, 1, 1, 1, 1},
{127, 32, 16, 32, 127},
{127, 32, 16, 8, 127},
{62, 65, 65, 65, 62},
{127, 72, 72, 72, 48},
{62, 65, 69, 66, 61},
{127, 72, 76, 74, 49},
{50, 73, 73, 73, 38},
{64, 64, 127, 64, 64},
{126, 1, 1, 1, 126},
{124, 2, 1, 2, 124},
{126, 1, 6, 1, 126},
{99, 20, 8, 20, 99},
{96, 16, 15, 16, 96},
{67, 69, 73, 81, 97},
};
//=== F U N C T I O N S ===
// This routine takes whatever we've setup in the bitmap array and display it on the matrix
void RefreshDisplay()
{
for (int row = 0; row < 8; row++) {
//-- turn off the display --
digitalWrite(rowEnable, HIGH);
//-- Shift out to each matrix (zone is 8 columns represented by one matrix)
for (int zone = maxZoneIndex; zone >= 0; zone--) {
for (int shiftbit = 7; shiftbit > -1; shiftbit--){
digitalWrite(gdataPin, LOW);
digitalWrite(dataPin, LOW);
if bitRead(gbitmap[row][zone],shiftbit) digitalWrite(gdataPin, HIGH);
if bitRead(bitmap[row][zone],shiftbit) digitalWrite(dataPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}
digitalWrite(rclockPin, LOW);
digitalWrite(rclockPin, HIGH);
//-- turn the current row on NOTE - INVERTED high=on --
digitalWrite(row1Pin, HIGH);
digitalWrite(row2Pin, HIGH);
digitalWrite(row3Pin, HIGH);
if bitRead(row,0) digitalWrite (row1Pin, LOW);
if bitRead(row,1) digitalWrite (row2Pin, LOW);
if bitRead(row,2) digitalWrite (row3Pin, LOW);
digitalWrite(rowEnable, LOW);
//-- Wait a little bit to let humans see what we've pushed out onto the matrix ;
delayMicroseconds(500);
}
}
// Converts row and colum to actual bitmap bit and turn it off/on
void Plot(int col, int row, bool isOn)
{
int zone = col / 8;
int colBitIndex = col % 8;
byte colBit = 1 << colBitIndex;
if (isOn) bitmap[row][zone] = bitmap[row][zone] | colBit;
else bitmap[row][zone] = bitmap[row][zone] & (~colBit);
}
void GPlot(int col, int row, bool isOn)
{
int zone = col / 8;
int colBitIndex = col % 8;
byte colBit = 1 << colBitIndex;
if (isOn)gbitmap[row][zone] = gbitmap[row][zone] | colBit;
else gbitmap[row][zone] = gbitmap[row][zone] & (~colBit);
}
// Plot each character of the message one column at a time, updated the display, shift bitmap left.
void AlphabetSoup()
{
//load in the characters
char msg[] = "AR U NO LED SIGN ";
char gmsg[] = "A D I O LED SIGN ";
for (int charIndex=0; charIndex < (sizeof(msg)-1); charIndex++)
{
int alphabetIndex = msg[charIndex] - '@';
int galphabetIndex = gmsg[charIndex] - '@';
if (alphabetIndex < 0) alphabetIndex = 0;
if (galphabetIndex < 0) galphabetIndex = 0;
//-- Draw one character of the message --
for (int col = 0; col < 6; col++)
{
for (int row = 0; row < 8; row++)
{
// Set the pixel to the alphabet for columns 0 thru 4
bool isOn = 0;
if (col<5) isOn = bitRead( alphabets[alphabetIndex][col], 7-row ) == 1;
Plot( numCols-1, row, isOn);
isOn = 0;
if (col<5) isOn = bitRead( alphabets[galphabetIndex][col], 7-row ) == 1;
GPlot( numCols-1, row, isOn);
}
//-- The more times you repeat this loop, the slower we would scroll --
for (int refreshCount=0; refreshCount < 50; refreshCount++)
RefreshDisplay();
//-- Shift the bitmap one column to left --
for (int row=0; row<8; row++) //right shift
{
for (int zone=0; zone < numZones; zone++)
{
// This right shift would show a left scroll on display.
bitmap[row][zone] = bitmap[row][zone] >> 1; //right shift
gbitmap[row][zone] = gbitmap[row][zone] >> 1; //right shift
// Roll over lowest bit from the next zone as highest bit of this zone.
if (zone < maxZoneIndex) bitWrite(bitmap[row][zone], 7, bitRead(bitmap[row][zone+1], 0));
if (zone < maxZoneIndex) bitWrite(gbitmap[row][zone], 7, bitRead(gbitmap[row][zone+1], 0));
}
}
}
}
}
//=== L O O P ===
void loop() {
AlphabetSoup();
}
Silent Radio LED sign to Arduino Continued
I am playing with the Silent Radio LED sign once again. There are two problems to fix, the brightness
and the scrolling.
See a Sunrise Systems sign converted with newer software at: https://bobdavis321.blogspot.com/2019/04/arduino-uno-interfaced-to-sunrise.html
See a Sunrise Systems sign converted with newer software at: https://bobdavis321.blogspot.com/2019/04/arduino-uno-interfaced-to-sunrise.html
Working on the brightness problem, I know that the 4017
design did not work well because there was no way to turn off the sign while
updating the shift registers. As a
result I went back to having the Arduino directly drive the TIP120
drivers. Another possible solution might
be to use an ULN2003’s as a level shifter.
That would require a 6 or 7 volt power supply as well. I wanted to stay with a 5 volt power
supply. I have observed that the Cadaces
modules use 22 ohm current limiting resistors.
The Silent Radio signs use 100 ohm resistors. Maybe changing the resistors is a better
solution? Here is the schematic.
This is what it looks like, the Arduino is underneath the circuit board.
On the scrolling issue, I have suspects that the sign
scrolls backwards because it is upside down.
So I changed two lines of code so the sigh would work upside down and
viola, it works. It now scrolls from
right to left like it should have been doing.
Here is the code to make it work.
//**************************************************************//
// Name : Silent Radio Driver //
// Author : Bob Davis //
// Date : 25 April, 2011 //
// Version : 1.0 //
// Based on work of Hari Wiguna - http://g33k.blogspot.com/ //
//****************************************************************
// Pins for the row drivers
int row1Pin = 1;
int row2Pin = 2;
int row3Pin = 3;
int row4Pin = 4;
int row5Pin = 5;
int row6Pin = 6;
int row7Pin = 7;
// Pins for column shift registers
int clockPin = 8;
int dataPin = 9;
// Set the pins to output to the circuit
void setup() {
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(row1Pin, OUTPUT);
pinMode(row2Pin, OUTPUT);
pinMode(row3Pin, OUTPUT);
pinMode(row4Pin, OUTPUT);
pinMode(row5Pin, OUTPUT);
pinMode(row6Pin, OUTPUT);
pinMode(row7Pin, OUTPUT);
}
//=== B I T M A P ===
//Bits in this array represents one LED of the matrix
// 8 is # of rows, 7 is # of LED matrix we have
byte bitmap[8][12]; // Change the 7 to however many matrices you want to use.
int numZones = sizeof(bitmap) / 8;
// I will refer to each group of 8 columns (represented by one matrix) as a Zone.
int maxZoneIndex = numZones-1;
int numCols = numZones * 8;
//=== F O N T ===
// Font courtesy of aspro648
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1203747843/22
// First char is @, next is A, B, etc. Only lower case, no symbols.
// The @ will display as space character.
byte alphabets[][5] = {
{0,0,0,0,0},
{31, 36, 68, 36, 31},
{127, 73, 73, 73, 54},
{62, 65, 65, 65, 34},
{127, 65, 65, 34, 28},
{127, 73, 73, 65, 65},
{127, 72, 72, 72, 64},
{62, 65, 65, 69, 38},
{127, 8, 8, 8, 127},
{0, 65, 127, 65, 0},
{2, 1, 1, 1, 126},
{127, 8, 20, 34, 65},
{127, 1, 1, 1, 1},
{127, 32, 16, 32, 127},
{127, 32, 16, 8, 127},
{62, 65, 65, 65, 62},
{127, 72, 72, 72, 48},
{62, 65, 69, 66, 61},
{127, 72, 76, 74, 49},
{50, 73, 73, 73, 38},
{64, 64, 127, 64, 64},
{126, 1, 1, 1, 126},
{124, 2, 1, 2, 124},
{126, 1, 6, 1, 126},
{99, 20, 8, 20, 99},
{96, 16, 15, 16, 96},
{67, 69, 73, 81, 97},
};
//=== F U N C T I O N S ===
// This routine takes whatever we've setup in the bitmap array and display it on the matrix
void RefreshDisplay()
{
for (int row = 0; row < 8; row++) {
//-- turn off the display --
digitalWrite(row1Pin, LOW);
digitalWrite(row2Pin, LOW);
digitalWrite(row3Pin, LOW);
digitalWrite(row4Pin, LOW);
digitalWrite(row5Pin, LOW);
digitalWrite(row6Pin, LOW);
digitalWrite(row7Pin, LOW);
//-- Shift out to each matrix (zone is 8 columns represented by one matrix)
for (int zone = maxZoneIndex; zone >= 0; zone--) {
shiftOut(dataPin, clockPin, MSBFIRST, bitmap[row][zone]);
}
//-- turn the current row on --
if (row == 1) digitalWrite (row7Pin, HIGH);
if (row == 2) digitalWrite (row6Pin, HIGH);
if (row == 3) digitalWrite (row5Pin, HIGH);
if (row == 4) digitalWrite (row4Pin, HIGH);
if (row == 5) digitalWrite (row3Pin, HIGH);
if (row == 6) digitalWrite (row2Pin, HIGH);
if (row == 7) digitalWrite (row1Pin, HIGH);
//-- Wait a little bit to let humans see what we've pushed out onto the matrix --
delayMicroseconds(500);
}
}
// Converts row and colum to actual bitmap bit and turn it off/on
void Plot(int col, int row, bool isOn)
{
int zone = col / 8;
int colBitIndex = col % 8;
byte colBit = 1 << colBitIndex;
if (isOn)
bitmap[row][zone] = bitmap[row][zone] | colBit;
else
bitmap[row][zone] = bitmap[row][zone] & (~colBit);
}
// Plot each character of the message one column at a time, updated the display, shift bitmap left.
void AlphabetSoup()
{
char msg[] = "ARDUINO LED SIGN ";
for (int charIndex=0; charIndex < (sizeof(msg)-1); charIndex++)
{
int alphabetIndex = msg[charIndex] - '@';
if (alphabetIndex < 0) alphabetIndex=0;
//-- Draw one character of the message --
// Each character is only 5 columns wide
for (int col = 0; col < 6; col++)
{
for (int row = 0; row < 8; row++)
{
// Set the pixel to the alphabet for columns 0 thru 4
bool isOn = 0;
if (col<5 --="" 1="" 50="" 7-row="" alphabetindex="" alphabets="" bitmap="" col="" column="" for="" int="" ison="" left="" loop="" more="" numcols-1="" one="" plot="" refreshcount="" refreshdisplay="" repeat="" row="" scroll="" shift="" slower="" the="" this="" times="" to="" we="" would="" you="" zone=""> 0; zone--)
for (int zone=0; zone < numZones; zone++)
{
// This right shift would show a left scroll on display.
bitmap[row][zone] = bitmap[row][zone] >> 1;
// Roll over lowest bit from the next zone as highest bit of this zone.
if (zone < maxZoneIndex) bitWrite(bitmap[row][zone], 7, bitRead(bitmap[row][zone+1],0));
}
}
}
}
}
//=== L O O P ===
void loop() {
AlphabetSoup();
}
5>
Wednesday, April 24, 2013
16 by 40 Dual color LED sign being sold on eBay by RDR Electronics.
They are advertising this sign as "10 - LED 8x8 5mm Dot Matrix Array Module Common Anode Red & Green 60mm". The sign has a two pin power connector and a six pin pass through connector. The pass through connector comes in on the right and leaves on the left. The six signals pass through two 4049's on the way through the board.
Here is a picture of the back of the sign. WO/32779/1 might mean something to someone?
Here is a picture of the front side of the sign:
The six pin connector on the right has pin one at the top, here is what they connect to:
1 - CD4094 Pin 3 Clock top row.
2 - CD4094 Pin 15 Output Enable for all 4094's (And bottom 4015 pin 7 as data)
3 - CD4094 Pin 2 Serial Data bottom row
4 - CD4094 Pin 1 Strobe for all 4094's (And both 4015 pin 9 and 1 as clock)
5 - CD4094 Pin 2 Serial Data top row
6 - CD4094 Pin 3 Clock bottom row
CD4094 Eight bit shift registers are used throughout the sign. They then used TD62083 drivers to drive the sign. I do not know how it drives the rows as the CD4094's only are used for the columns. There are some CD4015's that appear to be used for the rows. The next step is to interface it to a Arduino.
You might notice that there are no references to the row selection hardware. I have tried to get the sign working, but then I took it all back apart to trace out some more runs. Here is what I found. Pin 2 goes to the 4049's pin 15 as "output enable", but it also goes to the bottom 4015A pin 7 as "Data". Pin 4 goes to the 4049's Pin 1 as "strobe" but it also goes to both 4015's pin 9 and 1 as "Clock".
Here I am working on it. It may not run off a 5 volt 2.5V AC adapter, it needs more power!
*** Update - it works on 5 volts at 2.5 amps when displaying text ***
Here is a picture of the back of the sign. WO/32779/1 might mean something to someone?
Here is a picture of the front side of the sign:
The six pin connector on the right has pin one at the top, here is what they connect to:
1 - CD4094 Pin 3 Clock top row.
2 - CD4094 Pin 15 Output Enable for all 4094's (And bottom 4015 pin 7 as data)
3 - CD4094 Pin 2 Serial Data bottom row
4 - CD4094 Pin 1 Strobe for all 4094's (And both 4015 pin 9 and 1 as clock)
5 - CD4094 Pin 2 Serial Data top row
6 - CD4094 Pin 3 Clock bottom row
CD4094 Eight bit shift registers are used throughout the sign. They then used TD62083 drivers to drive the sign. I do not know how it drives the rows as the CD4094's only are used for the columns. There are some CD4015's that appear to be used for the rows. The next step is to interface it to a Arduino.
You might notice that there are no references to the row selection hardware. I have tried to get the sign working, but then I took it all back apart to trace out some more runs. Here is what I found. Pin 2 goes to the 4049's pin 15 as "output enable", but it also goes to the bottom 4015A pin 7 as "Data". Pin 4 goes to the 4049's Pin 1 as "strobe" but it also goes to both 4015's pin 9 and 1 as "Clock".
Here I am working on it. It may not run off a 5 volt 2.5V AC adapter, it needs more power!
*** Update - it works on 5 volts at 2.5 amps when displaying text ***
Tuesday, April 23, 2013
Dell Inspiron Ultrabook 14Z Hard drive removal
Recently I had the fun of removing the hard drive from a Dell Inspiron Ultrabook 14Z. The hard drive is located under the battery. Where is the battery you may ask??
First you need to remove the memory cover and the memory modules. Under one of the memory modules is a hidden screw. With that screw removed you can remove the keyboard by pushing up on the three clips at the top of the keyboard.
Once the memory cover is removed the CD ROM is free to be removed as well. There is one screw above the CD ROM that has to be removed.
There are seven screws under plastic covers underneath the laptop and four screws under the keyboard that need to be removed. Three are near the front edge and one is near the CPU fan as seen in the picture below.
Next release the four ribbon cables. Then the top cover comes off by releasing catches all around the edges. Now you can see the battery. There are two screws holding the battery in. The hard drive is then reachable.
First you need to remove the memory cover and the memory modules. Under one of the memory modules is a hidden screw. With that screw removed you can remove the keyboard by pushing up on the three clips at the top of the keyboard.
Once the memory cover is removed the CD ROM is free to be removed as well. There is one screw above the CD ROM that has to be removed.
There are seven screws under plastic covers underneath the laptop and four screws under the keyboard that need to be removed. Three are near the front edge and one is near the CPU fan as seen in the picture below.
Next release the four ribbon cables. Then the top cover comes off by releasing catches all around the edges. Now you can see the battery. There are two screws holding the battery in. The hard drive is then reachable.
Monday, April 22, 2013
Removing the CNet Download virus
Recently while working on a website, I noticed that some words were being underlined. I did not make them links so I scrolled over the words and this popped up:
I immediately realized that I had a virus in my computer. What on earth does "Sermons" have to do with eating bananas? What total nonsense? I tried scanning my computer with MSE and MBAM to no avail. So I went to add/remove programs and there it was "GetSavin". It easily removed itself that way.
I did some research and this virus comes from going to download.com (download.cnet.com) and they install it on your computer. There was the day when I trusted download.com, I have long since learned to steer clear of them. They install things on your computer without your permission and then activate it whenever they want.
I immediately realized that I had a virus in my computer. What on earth does "Sermons" have to do with eating bananas? What total nonsense? I tried scanning my computer with MSE and MBAM to no avail. So I went to add/remove programs and there it was "GetSavin". It easily removed itself that way.
I did some research and this virus comes from going to download.com (download.cnet.com) and they install it on your computer. There was the day when I trusted download.com, I have long since learned to steer clear of them. They install things on your computer without your permission and then activate it whenever they want.
Wednesday, April 17, 2013
My new book called "Arduino LED Projects"
I have been working on a new book called "Arduino LED Projects". Now I am looking for a publisher. It has a dozen projects from electronic dice, to a "wheel of prizes", to a quiz lockout machine, to a meter, and even a 8 by 8 dual color LED array. It is already listed on Amazon.com.
Here is a picture of the table of contents:
This is a peak at one of the pages:
Here I am playing with one of the projects, a two digit meter:
Here is a picture of the table of contents:
This is a peak at one of the pages:
Here is a picture of the front cover:
Here I am playing with one of the projects, a two digit meter:
Monday, April 15, 2013
Signature Electronic Sign to Arduino Adapter Part who knows?
I have not given up on the idea of using an Arduino to power a 120 by 32 LED sign. In fact I have it working, but the Arduino is still not fast enough. The display flickers. I made a quick adapter by taking the old controller and cutting the jacks off the circuit board. Then I soldered a header onto it so that it plugs into the Arduino. Here is what the adapter looks like;
Here is what it looks like when it is working:
Here is what it looks like when it is working:
Here is the code to make it work. I got rid of the "Shift out" command, each shift clock sends eight bits to the signs eight shift registers. That makes it run much faster.
//**********************************
// Name : 120x32 Cadaces Driver
// Author : Bob Davis
// Date : 23 February, 2013
// Version : 1.0
//**********************************
// Pins for the row drivers
int row1Pin = 2; //R1
int row2Pin = 7; //R2
int row3Pin = 1; //R3
int rowEnable = 8; //REN
int rclockPin = 6; //RCK
int clockPin = 3; //SCK
int dataPin = 5; //RSD
int gdataPin = 4; //GSD
int dataPin1 = 9; //RSD
int gdataPin1 = 10; //GSD
int dataPin2 = 12; //RSD
int gdataPin2 = 11; //GSD
int dataPin3 = 13; //RSD
int gdataPin3 = 14; //GSD
// Set the pins to output to the sign
void setup() {
pinMode(row1Pin, OUTPUT);
pinMode(row2Pin, OUTPUT);
pinMode(row3Pin, OUTPUT);
pinMode(rowEnable, OUTPUT);
pinMode(rclockPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(gdataPin, OUTPUT);
pinMode(dataPin1, OUTPUT);
pinMode(gdataPin1, OUTPUT);
pinMode(dataPin2, OUTPUT);
pinMode(gdataPin2, OUTPUT);
pinMode(dataPin3, OUTPUT);
pinMode(gdataPin3, OUTPUT);
}
//=== Character Array ===
// Characters are A, B, C, etc. Only upper case.
byte alphabets[][8] = {
{0, 04, 10, 17, 17, 31, 17, 17}, //A
{0, 30, 17, 17, 30, 17, 17, 30}, //B
{0, 14, 17, 16, 16, 16, 17, 14}, //C
{0, 28, 18, 17, 17, 17, 18, 28}, //D
{0, 31, 16, 16, 31, 16, 16, 31}, //E
{0, 31, 16, 16, 31, 16, 16, 16}, //F
{0, 14, 17, 16, 16, 19, 17, 14}, //G
{0, 17, 17, 17, 31, 17, 17, 17}, //H
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 07, 02, 02, 02, 02, 10, 14}, //J
{0, 17, 18, 20, 24, 20, 18, 17}, //K
{0, 16, 16, 16, 16, 16, 16, 31}, //L
{0, 10, 21, 21, 21, 17, 17, 17}, //M
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 14, 17, 17, 17, 17, 17, 14}, //O
{0, 30, 17, 17, 30, 16, 16, 16}, //P
{0, 14, 17, 17, 17, 17, 19, 15}, //Q
{0, 30, 17, 17, 30, 20, 18, 17}, //R
{0, 14, 17, 16, 14, 01, 17, 14}, //S
{0, 31, 04, 04, 04, 04, 04, 04}, //T
{0, 17, 17, 17, 17, 17, 17, 14}, //U
{0, 17, 17, 17, 10, 10, 10, 04}, //V
{0, 17, 17, 17, 21, 21, 21, 10}, //W
{0, 17, 17, 10, 04, 10, 17, 17}, //X
{0, 17, 10, 10, 04, 04, 04, 04}, //Y
{0, 31, 8, 04, 02, 04, 8, 31}, //Z
{0, 0, 21, 14, 31, 14, 21, 0}, //*
};
byte numbers[][8] = {
{0, 04, 12, 04, 04, 04, 04, 14}, //1
{0, 14, 17, 01, 02, 04, 8, 31}, //2
{0, 14, 01, 01, 06, 01, 01, 14}, //3
{0, 17, 17, 17, 31, 01, 01, 01}, //4
{0, 31, 16, 16, 14, 01, 17, 14}, //5
{0, 14, 16, 16, 30, 17, 17, 14}, //6
{0, 31, 01, 01, 02, 04, 8, 16}, //7
{0, 14, 17, 17, 14, 17, 17, 14}, //8
{0, 14, 17, 17, 15, 01, 01, 01}, //9
{0, 14, 17, 17, 17, 17, 17, 14}, //0
};
byte bitmap[][8] = { //red characters
{0, 0,0,0,0,0,0,0},
{0, 04, 12, 04, 04, 04, 04, 14}, //1
{0, 14, 17, 01, 02, 04, 8, 31}, //2
{0, 14, 17, 17, 17, 17, 17, 14}, //0
{0, 17, 17, 10, 04, 10, 17, 17}, //X
{0, 14, 01, 01, 06, 01, 01, 14}, //3
{0, 14, 17, 01, 02, 04, 8, 31}, //2
{0, 0,0,0,0,0,0,0},
{0, 4, 10, 17, 17, 31, 17, 17}, //A
{0, 0,0,0,0,0,0,0},
{0, 28, 18, 17, 17, 17, 18, 28}, //D
{0, 0,0,0,0,0,0,0},
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 14, 17, 17, 17, 17, 17, 14}, //O
{0, 0,0,0,0,0,0,0},
{0, 14, 17, 16, 14, 01, 17, 14}, //S
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 14, 17, 16, 16, 19, 17, 14}, //G
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 0,0,0,0,0,0,0},
};
byte gbitmap[][8] = { //green characters
{0, 0,0,0,0,0,0,0},
{0, 04, 12, 04, 04, 04, 04, 14}, //1
{0, 14, 17, 01, 02, 04, 8, 31}, //2
{0, 14, 17, 17, 17, 17, 17, 14}, //0
{0, 17, 17, 10, 04, 10, 17, 17}, //X
{0, 14, 01, 01, 06, 01, 01, 14}, //3
{0, 14, 17, 01, 02, 04, 8, 31}, //2
{0, 0,0,0,0,0,0,0},
{0, 4, 10, 17, 17, 31, 17, 17}, //A
{0, 30, 17, 17, 30, 20, 18, 17}, //R
{0, 0,0,0,0,0,0,0},
{0, 17, 17, 17, 17, 17, 17, 14}, //U
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 0,0,0,0,0,0,0},
{0, 14, 17, 17, 17, 17, 17, 14}, //O
{0, 0,0,0,0,0,0,0},
{0, 14, 17, 16, 14, 01, 17, 14}, //S
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 14, 17, 16, 16, 19, 17, 14}, //G
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 0,0,0,0,0,0,0},
};
void RunSign(){
for (int row = 7; row > 0; row--) {
// turn off display
digitalWrite(rowEnable, HIGH);
digitalWrite(rclockPin, LOW);
// send serial data to display 20 = number of characters
for (int character = 0; character < 21; character++){
for (int shiftbit = 5; shiftbit > -1; shiftbit--){
digitalWrite(gdataPin, LOW);
digitalWrite(dataPin, LOW);
digitalWrite(gdataPin1, LOW);
digitalWrite(dataPin1, LOW);
digitalWrite(gdataPin2, LOW);
digitalWrite(dataPin2, LOW);
digitalWrite(gdataPin3, LOW);
digitalWrite(dataPin3, LOW);
if bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin, HIGH);
if bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin, HIGH);
if bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin1, HIGH);
if bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin1, HIGH);
if bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin2, HIGH);
if bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin2, HIGH);
if bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin3, HIGH);
if bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin3, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
} }
//latch the data
digitalWrite(rclockPin, HIGH);
// set up 74138 row sesection and turn display back on
digitalWrite(row1Pin, LOW);
digitalWrite(row2Pin, LOW);
digitalWrite(row3Pin, LOW);
if bitRead(row,0) digitalWrite (row1Pin, HIGH);
if bitRead(row,1) digitalWrite (row2Pin, HIGH);
if bitRead(row,2) digitalWrite (row3Pin, HIGH);
digitalWrite(rowEnable, LOW);
// Wait to see what we sent to the display ;
delayMicroseconds(500);
}
}
//=== L O O P ===
void loop() {
RunSign();
}
// Name : 120x32 Cadaces Driver
// Author : Bob Davis
// Date : 23 February, 2013
// Version : 1.0
//**********************************
// Pins for the row drivers
int row1Pin = 2; //R1
int row2Pin = 7; //R2
int row3Pin = 1; //R3
int rowEnable = 8; //REN
int rclockPin = 6; //RCK
int clockPin = 3; //SCK
int dataPin = 5; //RSD
int gdataPin = 4; //GSD
int dataPin1 = 9; //RSD
int gdataPin1 = 10; //GSD
int dataPin2 = 12; //RSD
int gdataPin2 = 11; //GSD
int dataPin3 = 13; //RSD
int gdataPin3 = 14; //GSD
// Set the pins to output to the sign
void setup() {
pinMode(row1Pin, OUTPUT);
pinMode(row2Pin, OUTPUT);
pinMode(row3Pin, OUTPUT);
pinMode(rowEnable, OUTPUT);
pinMode(rclockPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(gdataPin, OUTPUT);
pinMode(dataPin1, OUTPUT);
pinMode(gdataPin1, OUTPUT);
pinMode(dataPin2, OUTPUT);
pinMode(gdataPin2, OUTPUT);
pinMode(dataPin3, OUTPUT);
pinMode(gdataPin3, OUTPUT);
}
//=== Character Array ===
// Characters are A, B, C, etc. Only upper case.
byte alphabets[][8] = {
{0, 04, 10, 17, 17, 31, 17, 17}, //A
{0, 30, 17, 17, 30, 17, 17, 30}, //B
{0, 14, 17, 16, 16, 16, 17, 14}, //C
{0, 28, 18, 17, 17, 17, 18, 28}, //D
{0, 31, 16, 16, 31, 16, 16, 31}, //E
{0, 31, 16, 16, 31, 16, 16, 16}, //F
{0, 14, 17, 16, 16, 19, 17, 14}, //G
{0, 17, 17, 17, 31, 17, 17, 17}, //H
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 07, 02, 02, 02, 02, 10, 14}, //J
{0, 17, 18, 20, 24, 20, 18, 17}, //K
{0, 16, 16, 16, 16, 16, 16, 31}, //L
{0, 10, 21, 21, 21, 17, 17, 17}, //M
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 14, 17, 17, 17, 17, 17, 14}, //O
{0, 30, 17, 17, 30, 16, 16, 16}, //P
{0, 14, 17, 17, 17, 17, 19, 15}, //Q
{0, 30, 17, 17, 30, 20, 18, 17}, //R
{0, 14, 17, 16, 14, 01, 17, 14}, //S
{0, 31, 04, 04, 04, 04, 04, 04}, //T
{0, 17, 17, 17, 17, 17, 17, 14}, //U
{0, 17, 17, 17, 10, 10, 10, 04}, //V
{0, 17, 17, 17, 21, 21, 21, 10}, //W
{0, 17, 17, 10, 04, 10, 17, 17}, //X
{0, 17, 10, 10, 04, 04, 04, 04}, //Y
{0, 31, 8, 04, 02, 04, 8, 31}, //Z
{0, 0, 21, 14, 31, 14, 21, 0}, //*
};
byte numbers[][8] = {
{0, 04, 12, 04, 04, 04, 04, 14}, //1
{0, 14, 17, 01, 02, 04, 8, 31}, //2
{0, 14, 01, 01, 06, 01, 01, 14}, //3
{0, 17, 17, 17, 31, 01, 01, 01}, //4
{0, 31, 16, 16, 14, 01, 17, 14}, //5
{0, 14, 16, 16, 30, 17, 17, 14}, //6
{0, 31, 01, 01, 02, 04, 8, 16}, //7
{0, 14, 17, 17, 14, 17, 17, 14}, //8
{0, 14, 17, 17, 15, 01, 01, 01}, //9
{0, 14, 17, 17, 17, 17, 17, 14}, //0
};
byte bitmap[][8] = { //red characters
{0, 0,0,0,0,0,0,0},
{0, 04, 12, 04, 04, 04, 04, 14}, //1
{0, 14, 17, 01, 02, 04, 8, 31}, //2
{0, 14, 17, 17, 17, 17, 17, 14}, //0
{0, 17, 17, 10, 04, 10, 17, 17}, //X
{0, 14, 01, 01, 06, 01, 01, 14}, //3
{0, 14, 17, 01, 02, 04, 8, 31}, //2
{0, 0,0,0,0,0,0,0},
{0, 4, 10, 17, 17, 31, 17, 17}, //A
{0, 0,0,0,0,0,0,0},
{0, 28, 18, 17, 17, 17, 18, 28}, //D
{0, 0,0,0,0,0,0,0},
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 14, 17, 17, 17, 17, 17, 14}, //O
{0, 0,0,0,0,0,0,0},
{0, 14, 17, 16, 14, 01, 17, 14}, //S
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 14, 17, 16, 16, 19, 17, 14}, //G
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 0,0,0,0,0,0,0},
};
byte gbitmap[][8] = { //green characters
{0, 0,0,0,0,0,0,0},
{0, 04, 12, 04, 04, 04, 04, 14}, //1
{0, 14, 17, 01, 02, 04, 8, 31}, //2
{0, 14, 17, 17, 17, 17, 17, 14}, //0
{0, 17, 17, 10, 04, 10, 17, 17}, //X
{0, 14, 01, 01, 06, 01, 01, 14}, //3
{0, 14, 17, 01, 02, 04, 8, 31}, //2
{0, 0,0,0,0,0,0,0},
{0, 4, 10, 17, 17, 31, 17, 17}, //A
{0, 30, 17, 17, 30, 20, 18, 17}, //R
{0, 0,0,0,0,0,0,0},
{0, 17, 17, 17, 17, 17, 17, 14}, //U
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 0,0,0,0,0,0,0},
{0, 14, 17, 17, 17, 17, 17, 14}, //O
{0, 0,0,0,0,0,0,0},
{0, 14, 17, 16, 14, 01, 17, 14}, //S
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 14, 17, 16, 16, 19, 17, 14}, //G
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 0,0,0,0,0,0,0},
};
void RunSign(){
for (int row = 7; row > 0; row--) {
// turn off display
digitalWrite(rowEnable, HIGH);
digitalWrite(rclockPin, LOW);
// send serial data to display 20 = number of characters
for (int character = 0; character < 21; character++){
for (int shiftbit = 5; shiftbit > -1; shiftbit--){
digitalWrite(gdataPin, LOW);
digitalWrite(dataPin, LOW);
digitalWrite(gdataPin1, LOW);
digitalWrite(dataPin1, LOW);
digitalWrite(gdataPin2, LOW);
digitalWrite(dataPin2, LOW);
digitalWrite(gdataPin3, LOW);
digitalWrite(dataPin3, LOW);
if bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin, HIGH);
if bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin, HIGH);
if bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin1, HIGH);
if bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin1, HIGH);
if bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin2, HIGH);
if bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin2, HIGH);
if bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin3, HIGH);
if bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin3, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
} }
//latch the data
digitalWrite(rclockPin, HIGH);
// set up 74138 row sesection and turn display back on
digitalWrite(row1Pin, LOW);
digitalWrite(row2Pin, LOW);
digitalWrite(row3Pin, LOW);
if bitRead(row,0) digitalWrite (row1Pin, HIGH);
if bitRead(row,1) digitalWrite (row2Pin, HIGH);
if bitRead(row,2) digitalWrite (row3Pin, HIGH);
digitalWrite(rowEnable, LOW);
// Wait to see what we sent to the display ;
delayMicroseconds(500);
}
}
//=== L O O P ===
void loop() {
RunSign();
}
How to make a quick Arduino to Cadaces adapter.
Some people asked me for a simpler way to interface the Cadaces modules to an Arduino, so here it is!
All you need to do this is a five pin header and four jumper
wires. Insert the five pin header into D1
through D5. Then plug the cable from the
display into those five pins so the other five pins hang off to the right. Add the four jumper wires according to the
schematic.
Here is a picture of the quick adapter in operation. The green wire if 5 volts going to power the sign.
Here are the pin number changes to the code to make it work;
// Pins for the row drivers
int row1Pin = 2; //R1
int row2Pin = 7; //R2
int row3Pin = 1; //R3
int rowEnable = 8; //REN
int rclockPin = 6; //RCK
int clockPin = 3; //SCK
int dataPin = 5; //RSD
int gdataPin = 4; //GSD
Here is the total code for 8 x 40 array:
//**********************************
// Name
: Cadaces Driver
// Author
: Bob Davis
// Date
: 23 February, 2013
// Version : 1.0
//**********************************
// Pins for the row drivers
int row1Pin = 2; //R1
int row2Pin = 7; //R2
int row3Pin = 1; //R3
int rowEnable = 8; //REN
int rclockPin = 6; //RCK
int clockPin = 3; //SCK
int dataPin = 5; //RSD
int gdataPin = 4; //GSD
// Set the pins to output to
the sign
void setup() {
pinMode(row1Pin, OUTPUT);
pinMode(row2Pin, OUTPUT);
pinMode(row3Pin, OUTPUT);
pinMode(rowEnable, OUTPUT);
pinMode(rclockPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(gdataPin, OUTPUT);
}
byte bitmap[][8] = { //red characters
{0, 0,0,0,0,0,0,0},
{0, 4,
10, 17, 17, 31, 17, 17}, //A
{0, 30, 17, 17, 30, 20, 18, 17}, //R
{0, 28, 18, 17, 17, 17, 18, 28}, //D
{0, 0,0,0,0,0,0,0},
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 14, 17, 17, 17, 17, 17, 14}, //O
{0, 0,0,0,0,0,0,0},
};
byte gbitmap[][8] = { //green characters
{0, 0,0,0,0,0,0,0},
{0, 4,
10, 17, 17, 31, 17, 17}, //A
{0, 30, 17, 17, 30, 20, 18, 17}, //R
{0, 0,0,0,0,0,0,0},
{0, 17, 17, 17, 17, 17, 17, 14}, //U
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 0,0,0,0,0,0,0},
{0, 14, 17, 17, 17, 17, 17, 14}, //O
{0, 0,0,0,0,0,0,0},
};
void RunSign(){
for (int row = 7; row > 0; row--) {
// turn off display
digitalWrite(rowEnable, HIGH);
digitalWrite(rclockPin, LOW);
// send serial data to display 8 = number
of characters
for (int character = 0; character < 8;
character++){
for (int shiftbit = 5; shiftbit > -1;
shiftbit--){
digitalWrite(gdataPin, LOW);
digitalWrite(dataPin, LOW);
if
bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin, HIGH);
if
bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
} }
//latch the data
digitalWrite(rclockPin, HIGH);
// set up 74138 row selection and turn
display back on
digitalWrite(row1Pin, LOW);
digitalWrite(row2Pin, LOW);
digitalWrite(row3Pin, LOW);
if bitRead(row,0) digitalWrite (row1Pin,
HIGH);
if bitRead(row,1) digitalWrite (row2Pin,
HIGH);
if bitRead(row,2) digitalWrite (row3Pin,
HIGH);
digitalWrite(rowEnable, LOW);
// Wait to see what we sent to the display
;
delayMicroseconds(500);
}
}
//=== L O O P ===
void loop() {
RunSign();
}
Wednesday, March 27, 2013
Dell Inspiron 1501 1505 Hinge and LCD Bracket repair
I have become a fan of the Dell Inspiron 1501 and 1503 laptops. I first fixed up one for a friend. Then someone gave me one for free. I cleaned out the cooling fan and replaced the keyboard and now it is my main computer. Recently I purchased two Dell E1505 laptops for $40 each. Their hinges were completely broken and one of the screens was even damaged because of the hinge problem. You can buy a hinge/LCD bracket assembly on eBay, or you can fix it yourself.
To fix it yourself remove the rubber stops and the screws that are located behind them. Remove the front bezel. Optionally remove the plastic over that is at the top of the keyboard to expose the bottoms of the hinges. Remove the broken hinge mounts, you should now see what is in the picture below.
To modify it first use a 1/4 inch drill bit to remove any burs on the three holes that are behind each hinge mounting bracket, so that the bracket will now fit flush against the aluminum behind it. Then use a 5/64 inch drill bit to drill the top hole in the bracket right through the back cover. Next, from the back side, drill a 3/32 inch hole through the cover and the aluminum, but NOT into the hinge bracket. Next put a screw into the new hole and thread it into the hinge mounting bracket. Before tightening that screw, you can optionally put a drop of glue or epoxy behind the bracket and then quickly tighten the screw.
If everything goes well the bracket is now glued and screwed back into place. Do not use extra super glue, the fumes off it can glue everything together and even melt plastic nearby. A tiny drop is all that is needed. I have done this repair without using any glue and it works fine.
While you are in there be sure to take out the cooling fan and clean off the heat exchanger!
To fix it yourself remove the rubber stops and the screws that are located behind them. Remove the front bezel. Optionally remove the plastic over that is at the top of the keyboard to expose the bottoms of the hinges. Remove the broken hinge mounts, you should now see what is in the picture below.
To modify it first use a 1/4 inch drill bit to remove any burs on the three holes that are behind each hinge mounting bracket, so that the bracket will now fit flush against the aluminum behind it. Then use a 5/64 inch drill bit to drill the top hole in the bracket right through the back cover. Next, from the back side, drill a 3/32 inch hole through the cover and the aluminum, but NOT into the hinge bracket. Next put a screw into the new hole and thread it into the hinge mounting bracket. Before tightening that screw, you can optionally put a drop of glue or epoxy behind the bracket and then quickly tighten the screw.
If everything goes well the bracket is now glued and screwed back into place. Do not use extra super glue, the fumes off it can glue everything together and even melt plastic nearby. A tiny drop is all that is needed. I have done this repair without using any glue and it works fine.
While you are in there be sure to take out the cooling fan and clean off the heat exchanger!
Thursday, March 7, 2013
Mini Cadaces 8 by 10 LED to Arduino
I have written some code to work with the small 8 by 10 LED array boards made by Cadaces/Signature Electronic signs. Here is a picture of one of them working:
Here is the code for the Arduino to make it work, the interface is that same as was used in previous posts.
//****************************************************//
// Name : Cadaces Driver //
// Author : Bob Davis //
// Date : 23 February, 2013 //
// Version : 1.0 //
//****************************************************//
// Pins for the row drivers
int row1Pin = 1;
int row2Pin = 2;
int row3Pin = 3;
int rowEnable = 4;
int rclockPin = 5;
int clockPin = 6;
int dataPin = 7;
int gdataPin = 8;
// Set the pins to output to the sign
void setup() {
pinMode(row1Pin, OUTPUT);
pinMode(row2Pin, OUTPUT);
pinMode(row3Pin, OUTPUT);
pinMode(rowEnable, OUTPUT);
pinMode(rclockPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(gdataPin, OUTPUT);
}
//=== Character Array ===
// Characters are A, B, C, etc. Only upper case, no symbols.
byte alphabets[][8] = {
{0, 04, 10, 17, 17, 31, 17, 17}, //A
{0, 30, 17, 17, 30, 17, 17, 30}, //B
{0, 14, 17, 16, 16, 16, 17, 14}, //C
{0, 28, 18, 17, 17, 17, 18, 28}, //D
{0, 31, 16, 16, 31, 16, 16, 31}, //E
{0, 31, 16, 16, 31, 16, 16, 16}, //F
{0, 14, 17, 16, 16, 19, 17, 14}, //G
{0, 17, 17, 17, 31, 17, 17, 17}, //H
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 07, 02, 02, 02, 02, 10, 14}, //J
{0, 17, 18, 20, 24, 20, 18, 17}, //K
{0, 16, 16, 16, 16, 16, 16, 31}, //L
{0, 10, 21, 21, 21, 17, 17, 17}, //M
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 14, 17, 17, 17, 17, 17, 14}, //O
{0, 30, 17, 17, 30, 16, 16, 16}, //P
{0, 14, 17, 17, 17, 17, 19, 15}, //Q
{0, 30, 17, 17, 30, 20, 18, 17}, //R
{0, 14, 17, 16, 14, 01, 17, 14}, //S
{0, 31, 04, 04, 04, 04, 04, 04}, //T
{0, 17, 17, 17, 17, 17, 17, 14}, //U
{0, 17, 17, 17, 10, 10, 10, 04}, //V
{0, 17, 17, 17, 21, 21, 21, 10}, //W
{0, 17, 17, 10, 04, 10, 17, 17}, //X
{0, 17, 10, 10, 04, 04, 04, 04}, //Y
{0, 31, 8, 04, 02, 04, 8, 31}, //Z
{0, 0, 21, 14, 31, 14, 21, 0}, //*
};
byte bitmap[][8] = { //red characters
{0, 0,0,0,0,0,0,0},
{0, 17, 17, 17, 31, 17, 17, 17}, //H
};
byte gbitmap[][8] = { //green characters
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 0,0,0,0,0,0,0},
};
void RunSign()
{
for (int row = 7; row > 0; row--)
{
// turn off display
digitalWrite(rowEnable, HIGH);
digitalWrite(rclockPin, LOW);
// send serial data to display 2 = number of characters
for (int character = 0; character < 2; character++)
{
for (int shiftbit = 5; shiftbit >=0; shiftbit--){
if bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin, HIGH);
else digitalWrite(gdataPin, LOW);
if bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin, HIGH);
else digitalWrite(dataPin, LOW);
digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW);
}
}
//latch the data
digitalWrite(rclockPin, HIGH);
// set up 74138 row sesection and turn display back on
if bitRead(row,0) digitalWrite (row1Pin, HIGH); else digitalWrite(row1Pin, LOW);
if bitRead(row,1) digitalWrite (row2Pin, HIGH); else digitalWrite(row2Pin, LOW);
if bitRead(row,2) digitalWrite (row3Pin, HIGH); else digitalWrite(row3Pin, LOW);
digitalWrite(rowEnable, LOW);
// Wait to see what we sent to the display ;
delayMicroseconds(500);
}
}
//=== L O O P ===
void loop() {
RunSign();
}
Here is the code for the Arduino to make it work, the interface is that same as was used in previous posts.
//****************************************************//
// Name : Cadaces Driver //
// Author : Bob Davis //
// Date : 23 February, 2013 //
// Version : 1.0 //
//****************************************************//
// Pins for the row drivers
int row1Pin = 1;
int row2Pin = 2;
int row3Pin = 3;
int rowEnable = 4;
int rclockPin = 5;
int clockPin = 6;
int dataPin = 7;
int gdataPin = 8;
// Set the pins to output to the sign
void setup() {
pinMode(row1Pin, OUTPUT);
pinMode(row2Pin, OUTPUT);
pinMode(row3Pin, OUTPUT);
pinMode(rowEnable, OUTPUT);
pinMode(rclockPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
pinMode(gdataPin, OUTPUT);
}
//=== Character Array ===
// Characters are A, B, C, etc. Only upper case, no symbols.
byte alphabets[][8] = {
{0, 04, 10, 17, 17, 31, 17, 17}, //A
{0, 30, 17, 17, 30, 17, 17, 30}, //B
{0, 14, 17, 16, 16, 16, 17, 14}, //C
{0, 28, 18, 17, 17, 17, 18, 28}, //D
{0, 31, 16, 16, 31, 16, 16, 31}, //E
{0, 31, 16, 16, 31, 16, 16, 16}, //F
{0, 14, 17, 16, 16, 19, 17, 14}, //G
{0, 17, 17, 17, 31, 17, 17, 17}, //H
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 07, 02, 02, 02, 02, 10, 14}, //J
{0, 17, 18, 20, 24, 20, 18, 17}, //K
{0, 16, 16, 16, 16, 16, 16, 31}, //L
{0, 10, 21, 21, 21, 17, 17, 17}, //M
{0, 17, 25, 25, 21, 19, 19, 17}, //N
{0, 14, 17, 17, 17, 17, 17, 14}, //O
{0, 30, 17, 17, 30, 16, 16, 16}, //P
{0, 14, 17, 17, 17, 17, 19, 15}, //Q
{0, 30, 17, 17, 30, 20, 18, 17}, //R
{0, 14, 17, 16, 14, 01, 17, 14}, //S
{0, 31, 04, 04, 04, 04, 04, 04}, //T
{0, 17, 17, 17, 17, 17, 17, 14}, //U
{0, 17, 17, 17, 10, 10, 10, 04}, //V
{0, 17, 17, 17, 21, 21, 21, 10}, //W
{0, 17, 17, 10, 04, 10, 17, 17}, //X
{0, 17, 10, 10, 04, 04, 04, 04}, //Y
{0, 31, 8, 04, 02, 04, 8, 31}, //Z
{0, 0, 21, 14, 31, 14, 21, 0}, //*
};
byte bitmap[][8] = { //red characters
{0, 0,0,0,0,0,0,0},
{0, 17, 17, 17, 31, 17, 17, 17}, //H
};
byte gbitmap[][8] = { //green characters
{0, 14, 04, 04, 04, 04, 04, 14}, //I
{0, 0,0,0,0,0,0,0},
};
void RunSign()
{
for (int row = 7; row > 0; row--)
{
// turn off display
digitalWrite(rowEnable, HIGH);
digitalWrite(rclockPin, LOW);
// send serial data to display 2 = number of characters
for (int character = 0; character < 2; character++)
{
for (int shiftbit = 5; shiftbit >=0; shiftbit--){
if bitRead(gbitmap[character][row],shiftbit) digitalWrite(gdataPin, HIGH);
else digitalWrite(gdataPin, LOW);
if bitRead(bitmap[character][row],shiftbit) digitalWrite(dataPin, HIGH);
else digitalWrite(dataPin, LOW);
digitalWrite(clockPin, HIGH); digitalWrite(clockPin, LOW);
}
}
//latch the data
digitalWrite(rclockPin, HIGH);
// set up 74138 row sesection and turn display back on
if bitRead(row,0) digitalWrite (row1Pin, HIGH); else digitalWrite(row1Pin, LOW);
if bitRead(row,1) digitalWrite (row2Pin, HIGH); else digitalWrite(row2Pin, LOW);
if bitRead(row,2) digitalWrite (row3Pin, HIGH); else digitalWrite(row3Pin, LOW);
digitalWrite(rowEnable, LOW);
// Wait to see what we sent to the display ;
delayMicroseconds(500);
}
}
//=== L O O P ===
void loop() {
RunSign();
}
Friday, March 1, 2013
Dunlap Clarke Rebuild part 3
A while back I rebuilt a Dunlap-Clark amplifier using some TDA7294 modules. I was disappointed with the anemic results of about 150 watts per channel. I searched eBay and found a pre-assembled circuit that claimed about 350 watts per channel. They advertise it as "1PC L20 350W Mono Audio Power Amplifier Kit AMP Board".
Here are the specifications:
You might note that the specifications are very poor translations. The big shock to me was the price, it was only $17.50 plus $7 shipping. That is less than the cost of two of the old TO-3 metal power transistors! The circuit board does not come with a heat sink, and the transistors certainly do not fit the old TO-3 power transistor holes. So I made a "heat sink adapter" out of a piece of aluminum.
Here is what it looks like mounted inside the Dunlap Clark Cabinet:I am still using the 50 volt center tapped power transformer although the board can use up to 62 volts center tapped.
Next I need to add a bridge rectifier and some filter caps so I can start testing it out.
I connected the power supply and it works. I am limited to about 150 watts by the 1 volt output of the signal generator program running on my laptop. That 1 volt input produces 25 volts peak to peak into 4 ohms with this setup.
Here are the specifications:
Power 200W (8R) 350W (4R)
Voltage: DC + - 45V
Rectified AC voltage range AC 12V to AC dual dual 32V;
THD = 0.009% 1K HZ 50W 8R
SR = 35V / US
Noise 92DBU
EIN = 114 DB
Frequency Response 20-20KHZ + - 0.5 DB
34 times the voltage gain
All resistors are 1% precision high precision resistors
PCB size: 116MM * 72 MM*1.6MM
All capacitors are imported original.
KEC original imported audio power tube.
Promote the use of KEC B817 D1047 and Toshiba A1930 C5171
Package including: 1X L20 Mono Amplifier Board
You might note that the specifications are very poor translations. The big shock to me was the price, it was only $17.50 plus $7 shipping. That is less than the cost of two of the old TO-3 metal power transistors! The circuit board does not come with a heat sink, and the transistors certainly do not fit the old TO-3 power transistor holes. So I made a "heat sink adapter" out of a piece of aluminum.
Here is what it looks like mounted inside the Dunlap Clark Cabinet:I am still using the 50 volt center tapped power transformer although the board can use up to 62 volts center tapped.
Next I need to add a bridge rectifier and some filter caps so I can start testing it out.
I connected the power supply and it works. I am limited to about 150 watts by the 1 volt output of the signal generator program running on my laptop. That 1 volt input produces 25 volts peak to peak into 4 ohms with this setup.
Subscribe to:
Posts (Atom)









