Pergunta

I am using a Nano Arduino (ATMega 328) to communicate to two 12-bit MCP3208 ADC chips based on this code. I have another device (LED driver TLC5940) tied to the pins that are suggested on this page but since I am using bit banging, it should not matter what pins I use. So, my configuration is the same as the above example except that:

    For ADC 1:
    CLK -> Arduino D6
    DOUT (MISO) -> Arduino D5
    DIN (MOSI) -> Arduino D12
    SS -> Arduino D7

    For ADC 2:
    CLK -> Arduino D6
    DOUT (MISO) -> Arduino D5
    DIN (MOSI) -> Arduino D12
    SS -> Arduino D8

So, the problem is that I get data from ADC 1 but not from ADC 2. I should be able to select ADC 2 by by pulling the selection pin low but all I get is 0. There are 16 photodiodes connected to 4 TLC2274 op-amps. Here is the Arduino code:

//Scott Little, BrainGoggles, 2013, GNU GPL v3
#include <SoftwareSerial.h>
#include "Tlc5940.h"
SoftwareSerial bluetooth(4,2);  //TX 4, RX 2

#define SELPIN 7 //Selection Pin for 1st ADC
#define SELPIN2 8 //Selection Pin for 2nd ADC
#define DATAOUT 12//MOSI 
#define DATAIN  5//MISO 
#define SPICLOCK  6//Clock 
int readvalue;
byte readvaluearray[32];
int intensity = 0;

void setup()
{
  /* Call Tlc.init() to setup the tlc.
     You can optionally pass an initial PWM value (0 - 4095) for all channels.*/
  Tlc.init();  //interferes with other SPI
  Tlc.clear();  //set pin modes 

  pinMode(SELPIN, OUTPUT); //adc 1 selection pin
  pinMode(SELPIN2, OUTPUT); //adc 2 selection pin
  pinMode(DATAOUT, OUTPUT); 
  pinMode(DATAIN, INPUT); 
  pinMode(SPICLOCK, OUTPUT); 
  //disable devices to start with 
  digitalWrite(SELPIN,HIGH); 
  digitalWrite(SELPIN2,HIGH);
  digitalWrite(DATAOUT,LOW); 
  digitalWrite(SPICLOCK,LOW); 
  bluetooth.begin(9600); 
  Serial.begin(9600);

}

void loop()
{
  if (bluetooth.available()) // Wait until a character is received
  {
    char val = (char)bluetooth.read();
    Serial.println(val);

    switch(val) // Perform an action depending on the command
    {
      case 't'://increase intensity when an 'e' is received
    intensity = plus(intensity);
      break;      

      case 'y'://decrease intensity when an 'r' is received
    intensity = minus(intensity);
      break;

      case 'q'://turn the light on when a 'q' is received
    on();
      break;

      case 'w'://turn the light off when a 'w' is received
    off();
      break;
    }
  }

  for (int i=0; i<8; i++){        //read from ADC 1
    readvalue = read_adc(i+1);
    readvaluearray[2*i] = highByte(readvalue);
    readvaluearray[2*i+1] = lowByte(readvalue);
  }

  for (int i=8; i<16; i++){        //read from ADC 2
    readvalue = read_adc2(i-7);
    readvaluearray[2*i] = highByte(readvalue);
    readvaluearray[2*i+1] = lowByte(readvalue);
  }

  bluetooth.write(readvaluearray,32);
  Serial.println("new");
  for (int i=0;i<16;i++){
    Serial.println(word(readvaluearray[2*i],readvaluearray[2*i+1]));
  }

  delay(2000);
}


int read_adc(int channel){
  int adcvalue = 0;
  byte commandbits = B11000000; //command bits - start, mode, chn (3), dont care (3)

  //allow channel selection
  commandbits|=((channel-1)<<3);

  digitalWrite(SELPIN,LOW); //Select adc

  // setup bits to be written
  for (int i=7; i>=3; i--){
    digitalWrite(DATAOUT,commandbits&1<<i);
    //cycle clock
    digitalWrite(SPICLOCK,HIGH);
    digitalWrite(SPICLOCK,LOW);    
  }

  digitalWrite(SPICLOCK,HIGH);    //ignores 2 null bits
  digitalWrite(SPICLOCK,LOW);
  digitalWrite(SPICLOCK,HIGH);  
  digitalWrite(SPICLOCK,LOW);

  //read bits from adc
  for (int i=11; i>=0; i--){
    adcvalue+=digitalRead(DATAIN)<<i;
    //cycle clock
    digitalWrite(SPICLOCK,HIGH);
    digitalWrite(SPICLOCK,LOW);
  }
  digitalWrite(SELPIN, HIGH); //turn off device

  return adcvalue;
}

int read_adc2(int channel){
  int adcvalue = 0;
  byte commandbits = B11000000; //command bits - start, mode, chn (3), dont care (3)

  //allow channel selection
  commandbits|=((channel-1)<<3);

  digitalWrite(SELPIN2,LOW); //Select adc

  // setup bits to be written
  for (int i=7; i>=3; i--){
    digitalWrite(DATAOUT,commandbits&1<<i);
    //cycle clock
    digitalWrite(SPICLOCK,HIGH);
    digitalWrite(SPICLOCK,LOW);    
  }

  digitalWrite(SPICLOCK,HIGH);    //ignores 2 null bits
  digitalWrite(SPICLOCK,LOW);
  digitalWrite(SPICLOCK,HIGH);  
  digitalWrite(SPICLOCK,LOW);

  //read bits from adc
  for (int i=11; i>=0; i--){
    adcvalue+=digitalRead(DATAIN)<<i;
    //cycle clock
    digitalWrite(SPICLOCK,HIGH);
    digitalWrite(SPICLOCK,LOW);
  }
  digitalWrite(SELPIN2, HIGH); //turn off device

  return adcvalue;
}

void on(void)
{
  Tlc.set(1, 4095);  //set pin 5 to max brightness
  Tlc.update();  //execute set
  //bluetooth.println("on");
  //Serial.println("on");
}

void off(void)
{
  Tlc.set(1, 0);  //set pin 5 to min brightness
  Tlc.update();  //execute set
  //bluetooth.println("off");
  //Serial.println("off");
}

int plus(int value)
{
  value = value + 64;
  if (value > 4095){value = 4095;}
  Tlc.set(1, value);  //set pin 5 to min brightness
  Tlc.update();  //execute set
  Serial.println(value);
  return value;
}

int minus(int value)
{
  value = value - 64;
  if (value < 0){value = 0;}
  Tlc.set(1, value);  //set pin 5 to min brightness
  Tlc.update();  //execute set
  Serial.println(value);
  return value;
}

Here is sample output that I am getting:

new
374
372
311
313
356
276
337
387
0
0
0
0
0
0
0
0
Foi útil?

Solução 2

It is working now. I physically changed the pin on the ADC corresponding to DOUT (ADC 12) to the pin on the Arduino corresponding to MISO (Arduino 12) and changed the code as such:

#define DATAOUT 5  //MOSI 
#define DATAIN  12 //MISO 

It should have worked as I had it before since I am bit banging, but it seems to work now as MISO is on the "correct" pin.

Outras dicas

I have designed a sketch for driving 10 (or more) RGB LEDs with the TLC5940 on my Arduino uno. This may also work on the nano. I am drive 10 common anode rgb leds on 30 channels with two TLC5940's daisy chained together. We can achieve more so long as you configure how many TLC5940 chips you are using. This works with the 12 bit duty cycle control (0 - 4095).

  1. In arduino IDE you must import the TLC5940 Library by Paul Stoffregen from here: https://github.com/PaulStoffregen/Tlc5940.

  2. Edit the tlc_config.h file where NUM_TLCs should equal 2 (by default it is 1):

    "#define NUM_TLCS 2"

  3. Now we can take a look at the sketch to run the thing

Here is the Wiring for the sketch: enter image description here

Although this depicts single color leds I will map my rgb pins 0-2, 3-5, 6-8, 9-11...Etc.

CODE:

#include "Tlc5940.h"

int rgbChannels = 30;//total channels used one the TLC5940's
int rgb[30]; ///should be the same as the number of channels
int rgbLights = 10;/// this is the number of rgb leds possible on 2 TLC5940's but you could always daisy chain more...
int colorArray[10];//this sets the number of colors to use (one per rgb led)

void setup() {
  // put your setup code here, to run once
  Tlc.init(0); // Initiates the TLC5940 and set all channels off
  Serial.begin(250000);
  Serial.println("Total Channels: " + String(rgbChannels) + "  Total
RGB Ligts: " + String(rgbLights));
  float divisor = 360 / (rgbChannels / 3); //degrees of color to
display divided by the number of rgb lights
  Serial.println("Divisor: " + String(divisor) );
  float Step = divisor;
  for (int i = 0; i < rgbLights; i++) {
    colorArray[i] = Step;
    Serial.println("colorArray[" + String(i) + "]: " + String(colorArray[i]));
    Step = Step + divisor;
  }
}

void ledColor(int channel, int red, int green, int blue)
{
  Tlc.set(channel, red);
  Tlc.set(channel + 1, green);
  Tlc.set(channel + 2, blue);
}

///convert hsi color to rgb
void hsi_to_rgb(int startChannel, float H, float S, float I) {
  int r, g, b;
  if (H > 360) {
    H = H - 360;
  }
  // Serial.println("H: "+String(H));
  H = fmod(H, 360); // cycle H around to 0-360 degrees
  H = 3.14159 * H / (float)180; // Convert to radians.
  S = S > 0 ? (S < 1 ? S : 1) : 0; // clamp S and I to interval [0,1]
  I = I > 0 ? (I < 1 ? I : 1) : 0;
  if (H < 2.09439) {
    r = 4095 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
    g = 4095 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
    b = 4095 * I / 3 * (1 - S);
  } else if (H < 4.188787) {
    H = H - 2.09439;
    g = 4095 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
    b = 4095 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
    r = 4095 * I / 3 * (1 - S);
  } else {
    H = H - 4.188787;
    b = 4095 * I / 3 * (1 + S * cos(H) / cos(1.047196667 - H));
    r = 4095 * I / 3 * (1 + S * (1 - cos(H) / cos(1.047196667 - H)));
    g = 4095 * I / 3 * (1 - S);
  }
  rgb[0 + startChannel] = r;
  rgb[1 + startChannel] = g;
  rgb[2 + startChannel] = b;

}


void rainbowShift() {
  float brightness = .4;
  float saturation = 1;
  for (int n = 0; n <= 360; n++) {
    for (int i = 0, j = 0; i < rgbLights; i++) {
      hsi_to_rgb(j, colorArray[i] + n, saturation, brightness);
      //Serial.println("rgb"+String(i)+":"+String(rgb[j])+","+String(rgb[j+1])+","+String(rgb[j+2]));
      ledColor(j, rgb[j], rgb[j + 1], rgb[j + 2]);
      j = j + 3;
    }
    Tlc.update();
    Tlc.clear();
    delayMicroseconds(500);
  }
}



void loop() {
  // put your main code here, to run repeatedly:
rainbowShift();////perform the function a few times

}

When all is done you should end up with a shifting rainbow of color over your RGB LEDs

Check out this video:

<iframe width="560" height="315" src="https://www.youtube.com/embed/CWdL9i8U8U0" frameborder="0" allowfullscreen></iframe>

Here is an Image of the result: enter image description here

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top