Help converting code from bs2 to Arduino

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
Franklin97355
 
Posts: 23911
Joined: Mon Apr 21, 2008 2:33 pm

Help converting code from bs2 to Arduino

Post by Franklin97355 »

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: Select all

' 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);
}
Last edited by Franklin97355 on Wed Jul 02, 2008 9:26 pm, edited 1 time in total.

User avatar
westfw
 
Posts: 2008
Joined: Fri Apr 27, 2007 1:01 pm

Post by westfw »

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

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

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

 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]

Silver
 
Posts: 12
Joined: Mon Apr 21, 2008 1:39 am

Post by Silver »

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

http://www.arduino.cc/playground/ComponentLib/Hc4led

User avatar
Franklin97355
 
Posts: 23911
Joined: Mon Apr 21, 2008 2:33 pm

Post by Franklin97355 »

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

#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);
    }
}

User avatar
westfw
 
Posts: 2008
Joined: Fri Apr 27, 2007 1:01 pm

Post by westfw »

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

User avatar
Franklin97355
 
Posts: 23911
Joined: Mon Apr 21, 2008 2:33 pm

Post by Franklin97355 »

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

User avatar
Franklin97355
 
Posts: 23911
Joined: Mon Apr 21, 2008 2:33 pm

Post by Franklin97355 »

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.

mtbf0
 
Posts: 1645
Joined: Sat Nov 10, 2007 12:59 am

Post by mtbf0 »

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.

User avatar
Franklin97355
 
Posts: 23911
Joined: Mon Apr 21, 2008 2:33 pm

Post by Franklin97355 »

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.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”