2015-02-17 2 views
0

Я получаю сообщение об ошибке при чтении с mcp3008 ADC. Функция ниже возвращает 127 при приеме 3.3В входа. Так как это 10-битный АЦП, он должен вернуться 1023.MCP3008 малина pi ошибка ADC

Я правильно определил свои номера контактов и включил как stdio.h, так и wiringPi.h. Любая помощь приветствуется.

int main(void) { 

    int adcValue = 0; 

    wiringPiSetup(); 

    pinMode(csPin, OUTPUT); 
    pinMode(sclkPin, OUTPUT); 
    pinMode(mosiPin, OUTPUT); 
    pinMode(misoPin, INPUT); 

    while(1) { 
     delay(10); 
     adcValue = readADC(CHAN0); 
     if (adcValue == -1) 
      printf("Error reading from %i \n", CHAN0); 
     else 
      printf("Chan0: %i \n", adcValue); 
    } 

} 

int readADC(int adcChan) { 

    // Variables 
    unsigned char dataOut = 0; 
    unsigned char adcout = 0; 
    int i, j = 0; 

    if ((adcChan > 7) || (adcChan < 0)) { 
     return -1; 
    } 

    digitalWrite(csPin, HIGH); 

    digitalWrite(sclkPin, LOW); 
    digitalWrite(csPin, LOW); 

    dataOut = adcChan; 
    dataOut |= 0x18; 
    dataOut <<= 3; 

    for (i = 0; i < 5; i++) { 
     if (dataOut & 0x80) { 
      digitalWrite(mosiPin, HIGH); 
     } else { 
      digitalWrite(mosiPin, LOW); 
     } 

     dataOut <<= 1; 
     digitalWrite(sclkPin, HIGH); 
     digitalWrite(sclkPin, LOW); 
    } 
    adcout = 0; 
    for (j = 0; j < 12; j++) { 
     digitalWrite(sclkPin, HIGH); 
     digitalWrite(sclkPin, LOW); 
     adcout <<= 1; 
     if (digitalRead(misoPin)) { 
      adcout |= 0x1; 
     } 
    } 

    digitalWrite(csPin, HIGH); 

    adcout >>= 1; 
    return adcout; 
} 

ответ

1

Вы возвращаете переменную unsigned char adcout = 0;, которая имеет размер 8 бит НЕ 10 бит. Кроме того, вы правы сдвигая его на 1, прежде чем вернуться, поэтому, скорее всего, вы получаете:

255 Right shifted by 1 = 127. 
2

Ваш adcout является char и не может держать 10-битное значение. Вместо этого используйте unsigned int. Кроме того, вы не должны отбрасывать свое значение с adcout >>= 1;, это уже хорошо.

+1

Я бы поднял, если бы не совет, чтобы использовать 'int', который никогда не должен использоваться для побитовых операций. Вместо этого используйте неподписанный тип, предпочтительно 'uint16_t' в этом случае. – Lundin

+0

Изменение типа данных на adcout сделало трюк! По-прежнему нужен adcout >> = 1 tho. Mcp3008 возвращает нулевой бит в наименее значимой позиции. Благодаря! –

+0

@ DylanCornell Вы действительно это испытали? В техническом описании mcp3008 четко указано, что из 12 бит, которые вы читаете, первое не определено, второе - null, а последние 10 (наименее значимые) - это значение. Это означает, что даже последний бит является частью значения. – ElderBug

1

использовать python и модуль spidev! Он будет выглядеть примерно так!

import spidev 

spi = spidev.SpiDev() 
spi.open(0,0) 

def read(ch): 
    adc = (spi.xfer2([1,(8+ch)<<4,0]) 
    data = ((adc[1]&3 << 8) + adc[2] 

Это должно дать правильные показания с чипа mcp3008. В настоящее время я использую этот чип в сенсорном модуле для подключения аналоговых датчиков. Ch является каналом на mcp3008 (0-7)

+0

NOte! прочитайте spidev man для получения информации о функции xfer2! –

Смежные вопросы