Forum Replies Created
-
AuthorPosts
-
UTASMember
Thank you so much Michael. It was entirely issues with the limited memory. By using a res of 128*32 and only trying to display the picture on two info boards it works just fine now.
UTASMemberIt is specified in the include as
byte shadowram[64][(4 * Number_of_Displays)] = {0};
So the size depends on the numbr of displays involved. I am currently using 4 displays, but I can get away with just 2 for this experiment. I never thought about the memory restriction. I am so used to programming for PC’s.
Exactly how much memory would be left if I used the 128×96 dimensions specified in VideoFrameCapture?
How hard do you think it will be to keep the two uses of the memory seperate?
UTASMemberFirstly thanks for the speedy reply. The project I am working on is quite time sensitive. I tried your code change suggestion but no luck. It definately seems to be something about the initOverlay() method though cause I only have to comment that line out and my display lights up fine.
I am very new to this so it is entirely possible I am making stupid mistakes. As far as I am aware there is no use of timers in my code. That said my code was borrowed and modified from others so I’m confident there are things I don’t know or understand about it. See code below.
#include "HT1632C_1_4.h"
TVout tv;
unsigned char x,y;
char s[32];
void initOverlay()
{
TCCR1A = 0;
// Enable timer1. ICES0 is set to 0 for falling edge detection on input capture pin.
TCCR1B = _BV(CS10);
// Enable input capture interrupt
TIMSK1 |= _BV(ICIE1);
// Enable external interrupt INT0 on pin 2 with falling edge.
EIMSK = _BV(INT0);
EICRA = _BV(ISC01);
}
void initInputProcessing()
{
// Analog Comparator setup
ADCSRA &= ~_BV(ADEN); // disable ADC
ADCSRB |= _BV(ACME); // enable ADC multiplexer
ADMUX &= ~_BV(MUX0); // select A2 for use as AIN1 (negative voltage of comparator)
ADMUX |= _BV(MUX1);
ADMUX &= ~_BV(MUX2);
ACSR &= ~_BV(ACIE); // disable analog comparator interrupts
ACSR &= ~_BV(ACIC); // disable analog comparator input capture
}
ISR(INT0_vect) {//looks like it is an external interupt of sorts
display.scanLine = 0;//seems to effect the sensitivity of the scan
}
//**************************************************************************************************
//Function Name: OutputCLK_Pulse
//Function Feature: enable CLK_74164 pin to output a clock pulse
//Input Argument: displayNumber - which display to send to.
//Output Argument: void
//**************************************************************************************************
void OutputCLK_Pulse(byte displayNumber)
{
switch(displayNumber){
case 1:
digitalWrite(clk1, HIGH);
digitalWrite(clk1, LOW);
break;
case 2:
digitalWrite(clk2, HIGH);
digitalWrite(clk2, LOW);
break;
}
}
//**************************************************************************************************
//Function Name: OutputA_74164
//Function Feature: enable pin A of 74164 to output 0 or 1
//Input Argument: x: if x=1, 74164 outputs high. If x?1, 74164 outputs low.
//Output Argument: void
//**************************************************************************************************
void OutputA_74164(byte displayNumber, byte x)
{
switch(displayNumber)
{
case 1:
if (x == 1)
digitalWrite(cs1, HIGH);
else
digitalWrite(cs1, LOW);
break;
case 2:
if (x == 1)
digitalWrite(cs2, HIGH);
else
digitalWrite(cs2, LOW);
break;
}
}
//**************************************************************************************************
//Function Name: Chip_Select
//Function Feature: Enable the various HT1632C chips on the 3216 info boards.
//Input Argument: select: HT1632C to be selected
// If select = 0, select none.
// If s < 0, select all.
//**************************************************************************************************
void Chip_Select(byte displayNumber, byte select)
{
byte i = 0;
if (select < 0){ //Enable all HT1632Cs
OutputA_74164(displayNumber, 0);
for(i = 0; i < CHIP_MAX; i++)
OutputCLK_Pulse(displayNumber);
}
else if(select == 0){ //Disable all HT1632Cs
OutputA_74164(displayNumber, 1);
for(i = 0; i < CHIP_MAX; i++)
OutputCLK_Pulse(displayNumber);
}
else{
OutputA_74164(displayNumber, 1);
for(i = 0; i < CHIP_MAX; i++)
OutputCLK_Pulse(displayNumber);
OutputA_74164(displayNumber, 0);
OutputCLK_Pulse(displayNumber);
OutputA_74164(displayNumber, 1);
for(i = 1; i < select; i++)
OutputCLK_Pulse(displayNumber);
}
}
//**************************************************************************************************
//Function Name: Write_Bits
//Function Feature: Write bits (up to 8) to h1632 on pins data, wrclk Chip is assumed to already be
//chip-selected. Bits are shifted out from MSB to LSB, with the first bit sent being
//(bits & firstbit), shifted till firsbit is zero.
//Input Argument: displayNumber
// : bits
// : firstbit
//**************************************************************************************************
void Write_Bits (byte displayNumber, byte bits, byte firstbit)
{
switch(displayNumber){
case 1:
while(firstbit){
digitalWrite(wrclk1, LOW);
if (bits & firstbit)
digitalWrite(data1, HIGH);
else
digitalWrite(data1, LOW);
digitalWrite(wrclk1, HIGH);
firstbit >>= 1;
}
break;
case 2:
while(firstbit){
digitalWrite(wrclk2, LOW);
if(bits & firstbit)
digitalWrite(data2, HIGH);
else
digitalWrite(data2, LOW);
digitalWrite(wrclk2, HIGH);
firstbit >>= 1;
}
break;
}
}
//**************************************************************************************************
//Function Name: Send_Command
//Function Feature: Send a command to the ht1632 chip.
//Input Argument: displayNumber
// : chipNo
// : command
//**************************************************************************************************
static void Send_Command(byte displayNumber, byte chipNo, byte command)
{
Chip_Select(displayNumber, chipNo);
Write_Bits(displayNumber, HT1632_ID_CMD, 0x04); //Send 3 bits of id: COMMMAND
Write_Bits(displayNumber, command, 0x80); //Send the actual command
Write_Bits(displayNumber, 0, 0x01); //One extra don't-care bit in commands.
Chip_Select(displayNumber, 0);
}
//**************************************************************************************************
//Function Name: Send_Data
//Function Feature: send a nibble (4 bits) of data to a particular memory location of the ht1632.
//The command has 3 bit ID, 7 bits of address, and 4 bits of data.
//Select 1 0 1 A6 A5 A4 A3 A2 A1 A0 D0 D1 D2 D3 Free
//Note that the address is sent MSB first, while the data is sent LSB first! This means that
//somewhere a bit reversal will have to be done to get zero-based addressing of words and dots
//within words.
//Input Argument: displayNumber
// : chipNo
// : address
// : data
//**************************************************************************************************
static void Send_Data(byte displayNumber, byte chipNo, byte address, byte data)
{
Chip_Select(displayNumber, chipNo);
Write_Bits(displayNumber, HT1632_ID_WR, 0x04); // send ID: WRITE to RAM
Write_Bits(displayNumber, address, 0x40); // Send address
Write_Bits(displayNumber, data, 0x08); // send 4 bits of data
Chip_Select(displayNumber, 0);
}
//**************************************************************************************************
//Function Name: Get_Chip_Number
//Function Feature: Takes a set of coordinates and returns the corresponding chip number.
//Input Argument: x
// : y
//**************************************************************************************************
byte Get_Chip_Number(byte x, byte y)
{
byte nChip;
if(x >= 96)
nChip = 7 + x / 16 + (y > 7 ? 2 : 0);
else if(x >= 64)
nChip = 5 + x / 16 + (y > 7 ? 2 : 0);
else if(x >= 32)
nChip = 3 + x / 16 + (y > 7 ? 2 : 0);
else
nChip = 1 + x / 16 + (y > 7 ? 2 : 0);
return nChip;
}
//**************************************************************************************************
//Function Name: xyToIndex
//Function Feature: Get the value of (x, y)
//Input Argument: x: X coordinate
// y: Y coordinate
//Output Argument: address of (x, y)
//**************************************************************************************************
byte xyToIndex(byte x, byte y)
{
byte addr;
x = x % 16;
y = y % 8;
addr = (x << 1) + (y >> 2);
return addr;
}
//**************************************************************************************************
//Function Name: Calculate_Bit
//Function Feature: calculate the bitval of y
//Input Argument: y: Y coordinate
//Output Argument: bitval
//**************************************************************************************************
byte Calculate_Bit(byte y)
{
return ( 8 >> (y & 3) );
}
//**************************************************************************************************
//Function Name: Get_Pixel
//Function Feature: get the value of (x, y)
//Input Argument: x: X coordinate
// y: Y coordinate
//Output Argument: colour settled on (x,y) coordinates
//**************************************************************************************************
byte Get_Pixel(byte x, byte y)
{
byte addr, bitval, nChip;
nChip = Get_Chip_Number(x, y);
addr = xyToIndex(x, y);
bitval = Calculate_Bit(y);
if ( (shadowram[addr][nChip-1] & bitval) && (shadowram[addr+32][nChip-1] & bitval) )
return ORANGE;
else if (shadowram[addr][nChip-1] & bitval)
return GREEN;
else if (shadowram[addr+32][nChip-1] & bitval)
return RED;
else
return 0;
}
//**************************************************************************************************
//Function Name: Plot
//Function Feature: Plot a pobyte on the display, with the upper left hand corner being (0, 0), and
//the lower right hand corner being (X_MAX, Y_MAX).
//The parameter "colour" could have one of the 4 values: black (off), red, green or yellow.
//Input Argument: displayNumber:
// x: X coordinate
// y: Y coordinate
// colour:
//Output Argument: Colour set at the specified (x, y) coordinates.
//**************************************************************************************************
void Plot (byte displayNumber, byte x, byte y, byte colour)
{
byte nChip, addr, bitval;
if (x < 0 || x > X_MAX || y < 0 || y > Y_MAX)
return;
if (colour != BLACK && colour != GREEN && colour != RED && colour != ORANGE)
return;
nChip = Get_Chip_Number (x, y);
addr = xyToIndex (x, y);
bitval = Calculate_Bit (y);
switch(colour){
case BLACK:
if (Get_Pixel(x, y) != BLACK){
// compare with memory to only set if pixel is other colour
// clear the bit in both planes;
shadowram[addr][nChip-1] &= ~bitval;
Send_Data(displayNumber, nChip, addr, shadowram[addr][nChip-1]);
addr = addr + 32;
shadowram[addr][nChip-1] &= ~bitval;
Send_Data(displayNumber, nChip, addr, shadowram[addr][nChip-1]);
}
break;
case GREEN:
if (Get_Pixel(x, y) != GREEN){
// compare with memory to only set if pixel is other colour
// set the bit in the green plane and clear the bit in the red plane;
shadowram[addr][nChip-1] |= bitval;
Send_Data(displayNumber, nChip, addr, shadowram[addr][nChip-1]);
addr = addr + 32;
shadowram[addr][nChip-1] &= ~bitval;
Send_Data(displayNumber, nChip, addr, shadowram[addr][nChip-1]);
}
break;
case RED:
if (Get_Pixel(x, y) != RED){
// compare with memory to only set if pixel is other color
// clear the bit in green plane and set the bit in the red plane;
shadowram[addr][nChip-1] &= ~bitval;
Send_Data(displayNumber, nChip, addr, shadowram[addr][nChip-1]);
addr = addr + 32;
shadowram[addr][nChip-1] |= bitval;
Send_Data(displayNumber, nChip, addr, shadowram[addr][nChip-1]);
}
break;
case ORANGE:
if (Get_Pixel(x, y) != ORANGE){
// compare with memory to only set if pixel is other color
// set the bit in both the green and red planes;
shadowram[addr][nChip-1] |= bitval;
Send_Data(displayNumber, nChip, addr, shadowram[addr][nChip-1]);
addr = addr + 32;
shadowram[addr][nChip-1] |= bitval;
Send_Data(displayNumber, nChip, addr, shadowram[addr][nChip-1]);
}
break;
}
}
//**************************************************************************************************
//Function Name: Plot
//Function Feature: Plot a pobyte on the display, with the upper left hand corner being (0, 0), and
//the lower right hand corner being (X_MAX, Y_MAX).
//The parameter "colour" could have one of the 4 values: black (off), red, green or yellow.
//Input Argument: displayNumber:
// x: X coordinate
// y: Y coordinate
// colour:
//Output Argument: Colour set at the specified (x, y) coordinates.
//**************************************************************************************************
void Paint (byte displayNumber, byte chipNo, byte addr, byte colour)
{
if(chipNo < 0 || chipNo > CHIP_MAX || addr < 0 || addr > 64)
return;
if(colour != BLACK && colour != GREEN && colour != RED && colour != ORANGE)
return;
Send_Data(displayNumber, chipNo, addr, 15);
}
//**************************************************************************************************
//Function Name: Clear_Screen
//Function Feature: Clear the display, and the shadow memory, and the snapshot memory. This uses
//the "write multiple words" capability of the chipset by writing all 96 words of memory without
//raising the chipselect signal.
//**************************************************************************************************
void Clear_Screen(byte displayNumber)
{
byte i, j, c;
for(j = 1; j <= CHIP_MAX; j++){
for(i = 0; i <= 96; i++)
Send_Data(1, j, i, 0); // clear the display!
}
for(i = 0; i < 64; i++){
for(j = 0; j < CHIP_MAX; j++)
shadowram[j] = 0;
}
}
void Test_Refresh_Rate(byte displayNumber)
{
int x, y;
for (y = Y_MAX; y > -1; y--){
for ( x = X_MAX; x > -1; x--){
Plot(displayNumber, x, y, 1);
//delay(4);
}
}
//delay(1000);
Clear_Screen(1);
for (y = 0; y <= Y_MAX; y++){
for ( x = 0; x <= X_MAX; x++){
Plot(displayNumber, x, y, 2);
}
}
Clear_Screen(displayNumber);
for (y = 0; y <= Y_MAX; y++){
for ( x = 0; x <= X_MAX; x++){
Plot(displayNumber, x, y, 3);
}
}
Clear_Screen(1);
}
void Test_Loop(byte displayNumber)
{
int x, y, c;
for (c = 1; c < 4; c++){
for (x = 0; x <= X_MAX; x++) {
for (y = 0; y <= Y_MAX; y++) {
Plot (displayNumber, x, y, c);
//delay(2);
}
}
}
Clear_Screen (displayNumber);
}
void Test_Plot(byte displayNumber)
{
Plot(1, 15, 15, 2);
Plot(1, 31, 15, 3);
Plot(1, 47, 15, 2);
Plot(1, 63, 15, 3);
Plot(1, 79, 15, 2);
Plot(1, 95, 15, 3);
Plot(1, 111, 15, 2);
Plot(1, 127, 15, 3);
Plot(1, 15, 0, 1);
Plot(1, 31, 0, 1);
Plot(1, 47, 0, 1);
Plot(1, 63, 0, 1);
Plot(1, 79, 0, 1);
Plot(1, 95, 0, 1);
Plot(1, 111, 0, 1);
Plot(1, 127, 0, 1);
}
void Test_Paint(byte displayNumber)
{
byte c, a, colour;
for (colour = 1; colour < 4; colour++){
for (c = 1; c <= CHIP_MAX; c++){
for (a = 0; a < 64; a++){
Paint (displayNumber, c, a, colour);
}
}
Clear_Screen(displayNumber);
}
}
void setup()
{
byte i, j;
pinMode(cs1, OUTPUT);
pinMode(clk1, OUTPUT);
pinMode(wrclk1, OUTPUT);
pinMode(data1, OUTPUT);
for (j = 1; j <= CHIP_MAX; j++)
{
Send_Command(1, j, RC_MASTER_MODE);//Select on chip RC as the clocks master mode.
Send_Command(1, j, N_MOS_COM_8);
Send_Command(1, j, SYS_EN);//System on
Send_Command(1, j, LED_ON);//LEDs on
Send_Command(1, j, PWM_07);//7 is the sweet spot. Higher values produce more garbage on screen.
//Clears the display quickly
for (i = 0; i < 96; i++)
{
Send_Data(1, j, i, 0);
}
}
tv.begin(PAL, W, H);
//initOverlay();
initInputProcessing();
tv.fill(0);
}
void loop()
{
//tv.capture();
//tv.fill(INVERT);
//Test_Refresh_Rate (1);
// tv.resume();
// tv.delay_frame(5);
//Test_Refresh_Rate (1);
Test_Loop(1);
//Test_Plot(1);
//Test_Paint(1);
}
Inside of HT1632C_1_4.h there is nothing else included other than TVout.h and fontALL.h
As it stands the code posted here paints a grid of pixels of different colours no worries. As soon as I remove the comment characters from initOverlay() nothing seems to work anymore.
Once again your help with this is very much appreciated.
-
AuthorPosts