UTAS

Forum Replies Created

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • in reply to: Redirecting output to crude display device #1053
    UTAS
    Member

    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.

    in reply to: Redirecting output to crude display device #1051
    UTAS
    Member

    It 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?

    in reply to: Redirecting output to crude display device #1118
    UTAS
    Member

    Firstly 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.

Viewing 3 posts - 1 through 3 (of 3 total)