USB vs External Power - A different Issue...

I am experimenting with a MAX6952 4-digit 5x7 Matrix LED driver using the Arduino UNO. The MAX6952 is powered externally and I use this external power to power the UNO thru the VIN pin on the Power Connector. The USB cable is also connected to my PC (to load my Sketch) but when the UPLOAD completes, the LED display does not work. If I remove the USB cable and reset the UNO, the display works fine. If I plug the USB cable back in, the display stops again. Don't know if this is a USB/External power problem or something else. Any ideas?

Don't know if this is a USB/External power problem or something else. Any ideas?

I suspect something else. Why don't you post your code (use a # code window) and let us see what you have going on.

Lefty

Generally, commands are sent to the MAX6592 as a 16-bit string with the MSB byte the Register Address
and the LSB byte the Data – Commands are sent via the “writeit” routine. It takes the Register Address
byte and Data byte as arguments. The first “command” is to set the MAX6592 mode to “normal”
(writeit(0x04, 0x01)); This is followed by a command to turn all the LED’s on (writeit(0x07, 0x01))
delays a bit then turns all LED’s off (writeit(0x07, 0x00)).

[quote]
#include <[color=#CC6600]SPI[/color].h>

[color=#7E7E7E]/* * * * * * * * * * * * * * * * *[/color]
[color=#7E7E7E] * ARDUINO driving MAX6952 and 4 5x7 LED Modules[/color]
[color=#7E7E7E]*/[/color]
#define cs 10
#define clk 12
#define din 11
#define indicator 8
#define pulse 5

[color=#CC6600]void[/color] [color=#CC6600][b]setup[/b][/color]() {
  [color=#CC6600]pinMode[/color](cs, [color=#006699]OUTPUT[/color]);
  [color=#CC6600]pinMode[/color](clk, [color=#006699]OUTPUT[/color]);
  [color=#CC6600]pinMode[/color](din, [color=#006699]OUTPUT[/color]);
  [color=#CC6600]pinMode[/color](indicator, [color=#006699]OUTPUT[/color]);
}

[color=#CC6600]void[/color] [color=#CC6600][b]loop[/b][/color]() {
  [color=#7E7E7E]//[/color]
  [color=#7E7E7E]// set config to normal mode[/color]
  [color=#7E7E7E]//[/color]
  [color=#CC6600]digitalWrite[/color](indicator, [color=#006699]HIGH[/color]); [color=#7E7E7E]//turn indicator on start op[/color]
  writeit(0x04, 0x01);
  [color=#CC6600]while[/color](1)
  {
    [color=#7E7E7E]//[/color]
    [color=#7E7E7E]//turn all leds on [/color]
    [color=#7E7E7E]//[/color]
    [color=#CC6600]digitalWrite[/color](indicator, [color=#006699]HIGH[/color]); [color=#7E7E7E]//turn indicator on start op[/color]
    writeit(0x07, 0x01);
    [color=#CC6600]digitalWrite[/color](indicator, [color=#006699]LOW[/color]); [color=#7E7E7E]//turn indicator off end op[/color]
    [color=#CC6600]delay[/color](250 );
    [color=#7E7E7E]//[/color]
    [color=#7E7E7E]//turn all leds off[/color]
    [color=#7E7E7E]// [/color]
    [color=#CC6600]digitalWrite[/color](indicator, [color=#006699]HIGH[/color]); [color=#7E7E7E]//turn indicator on start op[/color]
    writeit(0x07, 0x00);
    [color=#CC6600]digitalWrite[/color](indicator, [color=#006699]LOW[/color]);  [color=#7E7E7E]//indicator off op complete[/color]
    [color=#CC6600]delay[/color](1000);
  }
  [color=#CC6600]delay[/color](1000);
}

[color=#CC6600]void[/color] loadit( [color=#CC6600]boolean[/color] val, [color=#CC6600]int[/color] pulse_no )
{
  [color=#CC6600]if[/color]( val == 0 )
    [color=#CC6600]digitalWrite[/color](din, [color=#006699]LOW[/color]);
  [color=#CC6600]else[/color]
    [color=#CC6600]digitalWrite[/color](din, [color=#006699]HIGH[/color]);
  [color=#CC6600]delay[/color](pulse);
  [color=#CC6600]digitalWrite[/color](clk, [color=#006699]HIGH[/color]);
  [color=#CC6600]delay[/color](pulse);
  [color=#CC6600]if[/color]( pulse_no != 1 )
    [color=#CC6600]digitalWrite[/color](clk, [color=#006699]LOW[/color]);
  [color=#CC6600]delay[/color](50);
}

[color=#CC6600]void[/color] tobin([color=#CC6600]int[/color] dec, [color=#CC6600]int[/color] *bin)
{
  [color=#CC6600]byte[/color] bitval = 128;
  [color=#CC6600]for[/color]([color=#CC6600]byte[/color] count=0; count<=7; count++)
  {
    [color=#CC6600]if[/color](dec & bitval)
      bin[count]=1;
    [color=#CC6600]else[/color]
      bin[count]=0;
    bitval >>= 1;
  }
}

[color=#CC6600]void[/color] writeit([color=#CC6600]byte[/color] reg, [color=#CC6600]byte[/color] data)
{
    [color=#CC6600]int[/color] r_bits[8];
    [color=#CC6600]int[/color] d_bits[8];
    [color=#CC6600]int[/color] b_stream[16];
    tobin(reg, r_bits);
    tobin(data, d_bits);
    [color=#CC6600]for[/color]([color=#CC6600]int[/color] x=0; x<=7; x++)
    {
      b_stream[x] = r_bits[x];
      b_stream[x+8] = d_bits[x];
    }
    [color=#7E7E7E]//[/color]
    [color=#CC6600]digitalWrite[/color](clk, [color=#006699]LOW[/color]);
    [color=#CC6600]digitalWrite[/color](cs, [color=#006699]LOW[/color]);
    [color=#CC6600]for[/color]([color=#CC6600]int[/color] x=0; x<=15; x++)
    {
      [color=#CC6600]if[/color](x < 15)
        loadit(b_stream[x],0);
      [color=#CC6600]else[/color]
        loadit(b_stream[x],1);
    }
    [color=#CC6600]digitalWrite[/color](cs, [color=#006699]HIGH[/color]);
    [color=#CC6600]digitalWrite[/color](clk, [color=#006699]LOW[/color]);
}

[color=#CC6600]void[/color] initIO()
{
  [color=#7E7E7E]// initialize spi interface[/color]
  [color=#CC6600]digitalWrite[/color](cs, [color=#006699]HIGH[/color]);
  [color=#CC6600]digitalWrite[/color](clk, [color=#006699]LOW[/color]);
  [color=#CC6600]digitalWrite[/color](din, [color=#006699]LOW[/color]);
}

[/quote]

miker, don't use the copy for forum option, it makes a botchery of the code.

I noticed that - try this one…

#include <SPI.h>

/* * * * * * * * * * * * * * * * *
 * ARDUINO driving MAX6952 and 4 5x7 LED Modules
*/
#define cs 10
#define clk 12
#define din 11
#define indicator 8
#define pulse 5

void setup() {
  pinMode(cs, OUTPUT);
  pinMode(clk, OUTPUT);
  pinMode(din, OUTPUT);
  pinMode(indicator, OUTPUT);
}

void loop() {
  //
  // set config to normal mode
  //
  digitalWrite(indicator, HIGH); //turn indicator on start op
  writeit(0x04, 0x01);
  while(1)
  {
    //
    //turn all leds on 
    //
    digitalWrite(indicator, HIGH); //turn indicator on start op
    writeit(0x07, 0x01);
    digitalWrite(indicator, LOW); //turn indicator off end op
    delay(250 );
    //
    //turn all leds off
    // 
    digitalWrite(indicator, HIGH); //turn indicator on start op
    writeit(0x07, 0x00);
    digitalWrite(indicator, LOW);  //indicator off op complete
    delay(1000);
  }
}

void writeit(byte reg, byte data)
{
    int r_bits[8];
    int d_bits[8];
    int b_stream[16];
    tobin(reg, r_bits);
    tobin(data, d_bits);
    for(int x=0; x<=7; x++)
    {
      b_stream[x] = r_bits[x];
      b_stream[x+8] = d_bits[x];
    }
    //
    digitalWrite(clk, LOW);
    digitalWrite(cs, LOW);

    for(int x=0; x<=15; x++)
    {
      if(x < 15)
        loadit(b_stream[x],0);
      else
        loadit(b_stream[x],1);
    }
    
    digitalWrite(cs, HIGH);
    digitalWrite(clk, LOW);
}

void tobin(int dec, int *bin)
{
  byte bitval = 128;
  for(byte count=0; count<=7; count++)
  {
    if(dec & bitval)
      bin[count]=1;
    else
      bin[count]=0;
    bitval >>= 1;
  }
}

void loadit( boolean val, int pulse_no )
{
  if( val == 0 )
    digitalWrite(din, LOW);
  else
    digitalWrite(din, HIGH);
  delay(pulse);
  digitalWrite(clk, HIGH);
  delay(pulse);
  if( pulse_no != 1 )
    digitalWrite(clk, LOW);
  delay(25);
}

void initIO()
{
  // initialize spi interface
  digitalWrite(cs, HIGH);
  digitalWrite(clk, LOW);
  digitalWrite(din, LOW);
}

Why not use the actual SPI hardware pins and send the data out via SPI.transfer() commands>?

I've tried using the SPI functions but they don'tseem to work. The MAX6592 requires two bytes to be clocked in (an 8-bit register address followed by an 8-bit data byte). When the SS line goes from low to high, the MAX6592 assumes that 16-bits have been clocked in. When SPI.transfer sends the 8th bit, it takes SS high. This signals to the MAX6592 to latch and process the data. With SPI.transfer, it only gets 8-bits to process.

?? So give it 2 transfers between SS transitions.

  digitalWrite(SS,LOW);  // take the SS pin low to select the chip
  SPI.transfer(address);  // select the Address,
  SPI.transfer(number_to_display);      // select the data
  digitalWrite(SS,HIGH);   // take the SS pin high to de-select the chip

Is there a spec I can access that defines
The state of the CLK and SS lines when
SPI.transfer completes? It is my impression
it returns SS to HIGH?

It is my impression it returns SS to HIGH?

It is my experience that the SPI library and commands take no and have no control over the SS signal(s). It is up to user code to activate a single SS output pin before issuing SPI commands and deactivate the same SS signal when done with SPI commands. That is why the other SPI signals (clock and data pins) can be wired as a bus to multiple SPI slave modules, because the user can define as many separate output pin SS signals as required and only issue SPI commands after selecting which SS output pin to activate.

CrossRoads and retrolefty are right. The SPI.transfer command does not do anything to the SS signal. For example, here is my code for a routine to send two-byte commands using SPI. This code works.

int digitalPotWrite(int value, int slaveSelectPin) {

  unsigned char level, commandMask, byteOne, byteTwo;  

  commandMask = 0x30;
  byteOne = commandMask | (value/16);
  byteTwo = value * 16;
  
  // take the SS pin low to select the chip:
  digitalWrite(slaveSelectPin,LOW);

  //  send in the value via SPI:
  SPI.transfer(byteOne);
  SPI.transfer(byteTwo);

  // take the SS pin high to de-select the chip:
  digitalWrite(slaveSelectPin,HIGH); 

}

Back to your original problem, though, I'm not sure why switching between USB power and external power would affect your sketch. That's puzzling.

My bad then. For some reason I thought I saw a timing chart showing how SPI.transfer clocked data in. Probably was looking at the MAX6592 SPI implementation. For sure, if SPI.transfer is not touching SS, then that explains why I could not get it to work!

Thanks for all your help...