0

Help converting code from bs2 to Arduino
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Help converting code from bs2 to Arduino

by franklin97355 on Mon Jun 23, 2008 12:35 am

I'm trying to convert a program from the BasicStamp to the Arduino. Any questions on the bs2 code just ask. I think the problem might be with the shiftout or converting int to byte.

[code]' HC4LED.BS2
' This program demonstrates the use of the HC4LED display module
' HC4LED Pinout:
' Pin1 = +5VDC (White wire)
' Pin2 = Gnd
' Pin3 = Blank (Must connect to Gnd to enable display)
' Pin4 = No Connection
' Pin5 = Clock (Connect to pin 1 for this demo program)
' Pin6 = Data (Connect to pin 0 for this demo program)
'
'
' To display values:
' Set the "zeros" variable to 0=No leading zeros; or 1=Show leading zeros
' Set the variable "value" to 0 to 9999
' Then use "GOSUB DisplayValue" to show the value on the display
'
' Each segment of the display is addressable, so you can create letters
' and symbols.
' To display custom symbols:
' Set the variables "segments(0)" thru "segments(3)" (segments(0) is on the left)
' simply add the segment values that you want on
' Then use "GOSUB DisplaySegments" to show the segments on the display
'
' ---4---
' | |
' 2 8
' | |
' |---1--- |
' | |
' 64 16
' | |
' ---32---
'
' For example "F" would be 4+2+1+64 = 71
'
this is what I have so far
[code]// HC4LED.pde
int Clock = 3; // HC4LED module's Clock pin
int Dat = 2; // HC4LED modules's Data pin
int value; // Required; Holds value to display
int zeros; // Required; Determines if leading zeros are displayed
int cnt; // Required; Used by display routines
int segment[4]; // Required; Used by display routines & custom chars
byte digit[10] = {126, 24, 109, 61, 27, 55, 115, 28, 127, 31};
bool debug = true;
void setup()
{
pinMode (Clock, OUTPUT);
pinMode (Dat, OUTPUT);
Serial.begin(9600);
}

void loop()
{
int x;
for(x = 0; x <= 1000; x++) // Count from 0 to 1000
{
DisplayValue(x, 0); // Display count on HC4LED module
delay (1000); // Wait 1.0 seconds
} // Next count
delay(1000); // Wait 1 second
}

void DisplayValue(int value, int zeros)
{
// Call with:
// value = (value to display)
// zeros = (0=No leading zeros; 1=Show leading zeros)

segment[0] = digit[value / 1000];
segment[1] = digit[(value - (segment[3] * 1000)) / 100];
segment[2] = digit[(value - ((segment[3] * 1000)+(segment[2] * 100))) / 10];
segment[3] = digit[value - ((segment[3] * 1000)+(segment[2] * 100)+(segment[1] * 10))];


if (zeros = 0)
{
if (segment[0] = 126)
{
segment[0] = 0;
if (segment[1] = 126)
{
segment[1] = 0;
if (segment[2] = 126)
{
segment[2] = 0;
}
}
}
}
DisplaySegments();
}

void DisplaySegments()
{
int seg;
// Call with:
// segment[0] thru segment[3] set to custom character values
// segment[0] is on the left; segment[3] is on the right
for(seg = 3;seg > 0;seg--)
{
if (debug)
{
// Serial.print(seg);
Serial.print(" - ");
Serial.print(segment[seg]);
}
shiftOut(Dat, Clock, MSBFIRST,segment[seg]);
}
if (debug)
{
// Serial.print(seg);
Serial.print(" - ");
Serial.println((segment[0] >> 1) / 7);
}
shiftOut(Dat, Clock, MSBFIRST, (segment[0] >> 1) / 7);
digitalWrite (Clock, HIGH);
// Clock MUST remain high for at LEAST 1 millisecond for the
// new data to be latched onto the display.
delay (10);
}
[/code]
Last edited by franklin97355 on Wed Jul 02, 2008 9:26 pm, edited 1 time in total.

franklin97355
 
Posts: 21488
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

by westfw on Fri Jun 27, 2008 4:35 am

You didn't say what sort of problems you're having with it, but you need a double equals for testing in C - what you will unconditionally set most of your segment to 0.

Code: Select all | TOGGLE FULL SIZE
if (zeros = 0)
  {
    if (segment[0] = 126)
    {
      segment[0] = 0;
      if (segment[1] = 126)
      {
        segment[1] = 0;
        if (segment[2] = 126)
        {
          segment[2] = 0;
        }
      }
    }
  }


Should be:

Code: Select all | TOGGLE FULL SIZE
if (zeros == 0)
  {
    if (segment[0] == 126)
    {
      segment[0] = 0;
      if (segment[1] == 126)
      {
        segment[1] = 0;
        if (segment[2] == 126)
        {
          segment[2] = 0;
        }
      }
    }
  }

(however, since the first test will set "zeros" to zero and then fail, you shouldn't get to the other segment destroying code.)

You probably want segment to be a byte array.

And ah hah! This digit extraction won't work because the segment values you're subtracting are SEGMENT values and not numeric values any more!

Code: Select all | TOGGLE FULL SIZE
 segment[0] = digit[value / 1000];
   segment[1] = digit[(value - (segment[3] * 1000)) / 100];
   segment[2] = digit[(value - ((segment[3] * 1000)+(segment[2] * 100))) / 10];
   segment[3] = digit[value - ((segment[3] * 1000)+(segment[2] * 100)+(segment[1] * 10))];
 

[/code][/u]

westfw
 
Posts: 1603
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

by Silver on Mon Jun 30, 2008 2:19 am

You might want to check out the code on the Arduino Playground for the HC4LED module.

http://www.arduino.cc/playground/ComponentLib/Hc4led
Silver
 
Posts: 12
Joined: Mon Apr 21, 2008 1:39 am

by franklin97355 on Wed Jul 02, 2008 12:51 am

Thanks westfw and Silver, I got the code from that link but it wouldn't work either so I rewrote it. The bit I didn't have was the 'bit bang' out to the device. It's working now and I can go on to the next step. Again, thanks.
Code: Select all | TOGGLE FULL SIZE
#define CLOCK  3  //change this to the pin where the clock is going in to
#define DATA   2  // change to the pin where the data wire is plugged in to
#define LED   13  // status led

int led_state;
byte digit[4];
byte number[] = {  126,   //0  numerals (0-9)
                    24,   //1
                   109,   //2
                    61,   //3
                    27,   //4
                    55,   //5
                   115,   //6
                    28,   //7
                   127,   //8
                    31,   //9
                    96,   //A
                    60,   //C
                   103,   //E
                    71,   //F
                   
};

void setup() {
  pinMode(DATA, OUTPUT);
  pinMode(CLOCK, OUTPUT);   
}

void dispDigit(byte dig, byte flash) {
   for(int i = 0; i < 8; i++) {
      digitalWrite(DATA, (dig & B10000000));     // select high bit
      dig = dig << 1;                                // next bit
      digitalWrite(CLOCK, HIGH);                  // clock high
       if (flash) delay(1);                          // wait to set display on
      digitalWrite(CLOCK, LOW);
   }
}

void parseValue(int value, int zeros){
     // Call with:
     // value = (value to display)
     // zeros = (0=No leading zeros; 1=Show leading zeros)

   digit[0] = number[value / 1000];
   digit[1] = number[(value % 1000) / 100];
   digit[2] = number[((value % 1000) % 100) / 10];
   digit[3] = number[((value % 1000) % 100) % 10];
   if (zeros == 0) {
    if (digit[0] == 126) digit[0] = 0;
    if (digit[1] == 126) digit[1] = 0;
    if (digit[2] == 126) digit[2] = 0;
  }
}

void displayValue(int value, int zeros) {
  int i;
  parseValue(value, zeros);
  for (int i = 3; i > 0; i--) {
    dispDigit((byte)digit[i],0);
  } 
  dispDigit((byte)digit[0],1); 


void loop() {

  for(int j = 0; j < 1000; j++) { 
      displayValue(j, 0);
      led_state = !led_state;
      digitalWrite(LED, led_state);
      delay(1000);
    }
}

franklin97355
 
Posts: 21488
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

by westfw on Wed Jul 02, 2008 5:20 am

I would have thought you'd be able to get shiftout to work once you were shifting the right data, but I doubt that the code you have is any bigger than shiftout would have been...

westfw
 
Posts: 1603
Joined: Fri Apr 27, 2007 1:01 pm
Location: SF Bay area

by franklin97355 on Wed Jul 02, 2008 11:37 am

I'll try shiftout again now that I have working code and let you know what I find.

franklin97355
 
Posts: 21488
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

by franklin97355 on Wed Jul 02, 2008 9:28 pm

Well it must be a timing problem with shiftOut() because I just replaced 2 lines of code calling the function and it doesn't work correctly now. I think shiftOut() is just too fast.

franklin97355
 
Posts: 21488
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

by mtbf0 on Thu Jul 03, 2008 4:44 pm

according to the hc4led datasheet, the data aren't latched to the display until the clock input is held high for 1ms, so, ideally, you'd want to clock out everything but the last bit as fast as you can then hold clock high for 1 ms when you clock out that very last one last bit. if you don't mind the waste of 31ms every time you update the display this won't be an issue.

the need for a 1 ms hold on the clock is why the shiftOut routine won't work.
"i want to lead a dissipate existence, play scratchy records and enjoy my decline" - iggy pop, i need more
User avatar
mtbf0
 
Posts: 1645
Joined: Sat Nov 10, 2007 12:59 am
Location: oakland ca

by franklin97355 on Fri Jul 04, 2008 10:54 pm

Good point mtbf0, there is code in the stamp side I didn't understand where the last digit is shifted before being output and if I go back and look at that I bet I'll find my answer. Thanks.

franklin97355
 
Posts: 21488
Joined: Mon Apr 21, 2008 2:33 pm
Location: Lacomb, OR.

Please be positive and constructive with your questions and comments.