2013-11-10 7 views
0

Я использую Nano Arduino (ATMega 328) для связи с двумя 12-битными чипами АЦП MCP3208 на основе this code. У меня есть другое устройство (светодиодный драйвер TLC5940), привязанный к контактам, которые предлагаются на этой странице, но поскольку я использую бит-стук, не важно, какие контакты я использую. Таким образом, моя конфигурация такая же, как в приведенном выше примере, за исключением того:Несколько аналого-цифровых преобразователей на Arduino с использованием бит-бит SPI

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 

Таким образом, проблема заключается в том, что я получаю данные из АЦП 1, но не от АЦП 2. Я должен быть в состоянии выбрать АЦП 2 путем, потянув вывод выбора низкий, но все, что я получаю, равно 0. Есть 16 фотодиодов, подключенных к 4 операционным усилителям TLC2274. Вот код Arduino:

//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; 
} 

Вот пример вывода, что я получаю:

new 
374 
372 
311 
313 
356 
276 
337 
387 
0 
0 
0 
0 
0 
0 
0 
0 
+0

Обновление (11/12/2013): если я отключу каждую строку с помощью TLC (отключите TLC), я могу читать данные с обоих АЦП. У меня нет конденсаторов или резисторов, подключенных к АЦП. Кто-нибудь еще видел эту проблему? – scottlittle

+0

Обновление (11/13/2013, 12:37 утра CT): Если я отключу только tlc.init(), я могу читать оба АЦП, но светодиоды не включаются. Комментарий к tlc.init() говорит, что он вмешивается в SPI, но мне интересно, почему это будет сделано, если контакты полностью разные. Я использую стандартные контакты для TLC: https://code.google.com/p/tlc5940arduino/wiki/ArduinoDiecimilaHardwareSetup – scottlittle

+0

Кроме того, если вы посмотрите комментарии к коду google (комментарий выше), вы увидите, что соединение на D7 предполагается, что D11. Я правильно подключен к D11. – scottlittle

ответ

0

Он работает в настоящее время. Я физически изменил булавку на АЦП, соответствующий DOUT (АЦП 12) к контакту на Arduino, соответствующие MISO (Arduino 12) и изменил код, например:

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

Это должно было сработать, как у меня было раньше, так как я немного стучаюсь, но, похоже, теперь он работает, поскольку MISO находится на «правильном» штыре.

1

Я разработал эскиз для управления 10 (или более) светодиодами RGB с TLC5940 на моем Arduino uno. Это может также работать на нано. Я диск 10 общих анодов rgb светодиодов на 30 каналов с двумя TLC5940 в маргаритки вместе. Мы можем достичь большего, пока вы настраиваете количество чипов TLC5940, которые вы используете. Это работает с 12-битным управлением рабочим циклом (0 - 4095).

  1. В Arduino IDE необходимо импортировать TLC5940 библиотеку Пола Stoffregen отсюда: https://github.com/PaulStoffregen/Tlc5940.

  2. Отредактируйте tlc_config.h файл, в котором NUM_TLCs должен быть равен 2 (по умолчанию это 1):

    "#define NUM_TLCS 2"

  3. Теперь мы посмотрим на эскиз можно запустить вещь

Вот Проводка эскиза: enter image description here

Хотя это де picts single color leds Я буду отображать свои контакты rgb 0-2, 3-5, 6-8, 9-11 ... Etc.

КОД:

#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 

} 

Когда все будет сделано, вы должны закончить с смещаемой радугой цвета над вашим RGB светодиодами

Проверь это видео:

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

Вот изображение результат: enter image description here