ЦАП+Mega

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Доброго времени суток!
Спрашивал на многих форумах, но мне либо ни где не отвечали, либо отправляли в гугл. Вы моя последняя надежда.
Есть Arduino Mega, ЦАП - AD420AN, ОУ - LM358.

Суть задачи:
Подключить ЦАП к Arduino через SPI и очень-очень плавно повышать напряжение. 

Что сделал:
1. Собрал все это вкучу по даташиту на ЦАП(http://www.analog.com/static/imported-files/data_sheets/AD420.pdf) Схема на 10-ой странице под заголовком VOLTAGE-MODE OUTPUT. 6 лапу ЦАПа(Clear) кинул на +5В, 7 лапу(Lath) на 53 пин ардуино, 8 лапу(Clock) на 52 и 9(Data in) на 51 пин.
2. Написал скетч (но он почему-то не работает):

#include <SPI.h>

void setup()
{
  pinMode(SS, OUTPUT);
  SPI.begin();
  digitalWrite(SS,LOW);
}

void setLevel(int level)
{
  digitalWrite(SS, LOW);
  SPI.transfer(level);
  digitalWrite(SS, HIGH);
}

void loop()
{
  for(int i=0; i<65535;i+=5)
  {
    setLevel(i);
    delay(5);
  }
  delay(1000);
}

Вопросы:
1. Правильно ли я подключил ЦАП к Arduino.
2. Можете привести пример кода для управления ЦАПом?

maksim
Offline
Зарегистрирован: 12.02.2012

Не вдаваясь в подробности даташита, вопрос такой на выходе ЦАП что нибудь получаете?

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

maksim пишет:

Не вдаваясь в подробности даташита, вопрос такой на выходе ЦАП что нибудь получаете?

Постоянно около 1,2 вольта. 
Но там не сразу с ЦАПа, а через ОУ.

maksim
Offline
Зарегистрирован: 12.02.2012

Первое что вам нужно сделать это прочитать про типы данных особенно про intunsigned int и byte, зетем обязательно почитать про SPI.

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

maksim пишет:

Первое что вам нужно сделать это прочитать про типы данных особенно про intunsigned int и byte, зетем обязательно почитать про SPI.

Про int, это да, напортачил. Переправил в программе на unsigned int, но это так и не спасло.
По поводу раздела SPI - я его читал, все что я из него понял, есть в моем коде.
Мне пока сложно с ним разобраться, поэтому и прошу помочь с кодом.

maksim
Offline
Зарегистрирован: 12.02.2012

 Затем подробнее изучить даташит и воспользовавшись функциями lowByte() и highByte() продвинуться ближе к решению данной задачи.

maksim
Offline
Зарегистрирован: 12.02.2012

AlexSMGr54 пишет:

maksim пишет:

Первое что вам нужно сделать это прочитать про типы данных особенно про intunsigned int и byte, зетем обязательно почитать про SPI.

Про int, это да, напортачил. Переправил в программе на unsigned int, но это так и не спасло.
По поводу раздела SPI - я его читал, все что я из него понял, есть в моем коде.
Мне пока сложно с ним разобраться, поэтому и прошу помочь с кодом.

Плохо значит читали, потому как SPI.transfer() отправляет/принимает данные типа byte, а вам нужно отправить unsigned int - это два байта.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

 

7 строка. Непонятно зачем включать разрешение SS (устанавливается в LOW), не вдаваясь в подробности - это выглядит странно.

 

void writeShiftRegister16(int ss_pin, uint16_t value)
{
  digitalWrite(ss_pin, LOW);
  /* Фокус вот в чём: сначала шлём старший байт */
  SPI.transfer(highByte(value));
  /* А потом младший */
  SPI.transfer(lowByte(value));
  digitalWrite(ss_pin, HIGH);
}

Это кусок кода отсюда: http://nnm.ru/blogs/e-troll/arduino-spi/

 

maksim
Offline
Зарегистрирован: 12.02.2012

В даташите есть пример кода на асме, так вот все то что после  ;  это комментарии.
Вот вам комментарии по которым можно написать код на СИ:

// DABL INTRPTS, SPI IS MASTER & ON  
// CPOL = 0, CPHA = 0, 1MHZ BAUDRATE  
// INFINITE LOOP 
// DRIVE SS (LATCH) LOW 
// SEND MS-BYTE TO SPI DATA REG  
// SEND LS-BYTE TO SPI DATA REG  
// DRIVE SS HIGH TO LATCH DATA 
AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Спасибо, что отозвались, но мне ни один из ваших вариантов не помог, увы.
На одном из американских сайтов нашел пример кода для работы с ЦАПом:

void writeValue(uint16_t value)
{
  digitalWrite(LATCH,LOW);
  digitalWrite(CLOCK,LOW);

  for(int i=15;i>=0;i--)
{
    digitalWrite(DATA,((value&(1<<i)))>>i);
    delayMicroseconds(HALF_CLOCK_PERIOD);
    digitalWrite(CLOCK,HIGH);
    delayMicroseconds(HALF_CLOCK_PERIOD);
    digitalWrite(CLOCK,LOW);
  }

  digitalWrite(DATA,LOW);
  digitalWrite(CLOCK,LOW);
  digitalWrite(LATCH,HIGH);
  delayMicroseconds(HALF_CLOCK_PERIOD);
  digitalWrite(LATCH,LOW);
 
}

Устройство с этим кодом у меня работает. Я так понимаю, тут число передается по 1 биту. Но я не совсем понимаю, что именно, точнее почему именно так, тут происходит.
Не могли бы вы помочь мне разобраться с этим кодом?

maksim
Offline
Зарегистрирован: 12.02.2012

В этом примере интерфейс реализован програмно.

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

maksim пишет:

В этом примере интерфейс реализован програмно.

Т.е. весь код, который я привел можно заменить этим:

void writeShiftRegister16(int ss_pin, uint16_t value)
{
  digitalWrite(ss_pin, LOW);
  /* Фокус вот в чём: сначала шлём старший байт */
  SPI.transfer(highByte(value));
  /* А потом младший */
  SPI.transfer(lowByte(
  digitalWrite(ss_pin, HIGH);
}

 

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Всем спасибо!
Разобрался со всеми кодами, все из приведенных выше работают.

Теперь умею плавно поднимать напряжение от 0 до +5В.

Ещё вопрос. Чтобы изменять напряжение от -5 до 0В нужно переделывать плату или это можно решить программно?

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

up

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

А почитать в даташите 10 страницу "VOLTAGE-MODE OUTPUT" религия не позволяет? В чем проблема? Более того там постоянно  твердят о выходных напряжениях.

 

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Понимаете, 10 страницу даташита я уже до дыр истер и я не слепой, раздел "VOLTAGE-MODE OUTPUT" я читал, религия мне не запрещает читать.
Проблема, уважаемый, в том, что если я собираю схему вточности, как указано в вышеупомянутом разделе, прибор не выдает +\-5В, он выдает даже больше чем должен, от приблизительно 0,6 до 12,5В, что я нормальным не считаю.

Собственно поэтому я вопрос и задал, решается ли моя проблема программно или же нужно что-то делать с самой схемой

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Вот теперь вопрос понятен, почему не работает режим +-5 В по схеме с 10 страницы даташита.

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Я разобрался, как можно сделать отрицательно напряжение, но мне нужна помощь, т.к. своими силами я тут не справляюсь.
Чтобы изменять напряжение от 0 до 5В я пользуюсь следующей схемой:

На выходе ОУ IC2A мы будем получять такое напряжение, которое подаем на 15 лапу (Reference Input),
Сейчас я получаю напряжение от 0 до 5В, т.к. 14 лапа - это +5В  замкнута с 15, т.е мы подаем +5В. Значит если подать на 15 лапу -5В, то я должен получать напряжение от 0 до -5В.

Собственно вопрос - как это можно сделать?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

ИМНО, чтобы получить двуполярное напряжение, нужно выходной усилитель включить по дифференциальной схеме, подав на инвертирующий вход подпорку в 2,5 В и коэффициент усиления 2. Тогда 0 на 17 ноге будет давать на выходе -5В, а +5В (на17 ноге) - даст на выходе те же +5В. Если же всё питание однополярное, то нужно брать виртуальную землю не с земли схемы, а с другой точки.

Кстати, если добился на выходе от 0 до 12 В, то можно померять напряжение между REF OUT и выходом операционника, по моему там и получится от -5В до +5В, т.е. REF OUT и есть вритуальная земля.

Могу ошибаться, давно отошел от схемотехники.

UPD: Да, я рассматривал схему включения с 10 страницы, а не та, что выше.

Serjeant
Offline
Зарегистрирован: 08.11.2018

Добрый день.

Не могли бы поделиться куском рабочего кода? Пытаюсь получить с ad420 ток 4-20 мА.  Все что нашел, перепробовал ничего не заработало, микросхема выдает с подключенной ардуиной 20 мА, если обесточить ардуину то 4 мА. Микросхема б/у но вроде должна работать, откуда вытащил там токовые выхода не использовались.

SPI mode 0, скорость 100 кГц, ЦАП - 16 бит, передача данных в SPI по 8  бит, сначала старший бит вроде такие параметры. Даташит на Ad420 читал, про SPI читал, но опыта нет.

Duino A.R.
Offline
Зарегистрирован: 25.05.2015

Serjeant пишет:
Добрый день.  Не могли бы поделиться куском рабочего кода? Пытаюсь получить с ad420 ток 4-20 мА.  Все что нашел, перепробовал ничего не заработало, микросхема выдает с подключенной ардуиной 20 мА, если обесточить ардуину то 4 мА. Микросхема б/у но вроде должна работать, откуда вытащил там токовые выхода не использовались.

SPI mode 0, скорость 100 кГц, ЦАП - 16 бит, передача данных в SPI по 8  бит, сначала старший бит вроде такие параметры. Даташит на Ad420 читал, про SPI читал, но опыта нет.

Добрый. Serjeant, обратите внимание на даты постов. Тема, в которую Вы написали, за(у)мерла 8(!) лет назад.

Я рекомендую завести новую тему, где обязательно сразу привести:

1. Полную схему Вашего устройства. Не из Интернета, не кусочек, а вот именно полную, и именно Вашего. Что и как подключено именно у Вас.

2. В соответствии с правилами форума привести один из кодов, который Вы пробовали, который должен был, по Вашему мнению, заработать, но не заработал. Описать, что именно было не так. Если проб было много, приведите тот вариант, который лучше всего понимаете.

Микросхему можно спалить 100500 способами, даже к ней не прикасаясь. Есть заведомо рабочая AD420 или   способ проверить работоспособность Вашего экземпляра?

 

Serjeant
Offline
Зарегистрирован: 08.11.2018

Ok, спасибо. Может автор откликнется. Если нет  соберусь с мыслями заведу тему. Схема наипростейшая по даташиту, в основном совпадает с заводской схемой в приборе.

Нет, проверить пока нет возможности, микросхему можно еще одну так же вытащить с прибора, но проверить никак, без датчика сигнал не выдается, а датчиков нет

Duino A.R.
Offline
Зарегистрирован: 25.05.2015

Serjeant пишет:

Ok, спасибо. Может автор откликнется. Если нет  соберусь с мыслями заведу тему. Схема наипростейшая по даташиту, в основном совпадает с заводской схемой в приборе.

Дело не в сложности схемы. В даташите всё работает, а у Вас - нет. Поэтому обсуждать нужно именно Вашу схему, вплоть до самой последней ножки. Кстати, когда рисуешь схему по живому образцу, чаще выявляются ошибки, включая, например, коротыш при пайке и т.п.

Serjeant пишет:
Нет, проверить пока нет возможности, микросхему можно еще одну так же вытащить с прибора, но проверить никак, без датчика сигнал не выдается, а датчиков нет

Если у Вас есть некий прибор, работающий с датчиками 4-20 мА, то датчик в таком случае можно имитировать парой резисторов. Переменным и постоянным, включенными последовательно. С учетом напряжения питания постоянный рассчитывают так, чтобы максимальный ток не превышал 22-25 мА, а переменный - чтобы при его максимальном сопротивлении ток был в районе 2-3 мА. Если питание подаётся на датчик от прибора, то резисторов оказывается достаточно, если датчик предполагается активным, то нужен ещё и внешний источник питания. Чаще, это =24 В, но лучше уточнить по РЭ на прибор.

Лучше потратить силы и убедиться, что микросхема - рабочая. Поскольку лечить "трупик" по переписке... Сами понимаете.

 

AlexSMGr54
Offline
Зарегистрирован: 19.12.2012

Добрый! Давно тут не был. Про эту схему даже забыть уже успел. Не уверен остались ли исходники, т.к. это была одна из моих курсовых работ в универе. Постараюсь поискать, если что что осталось, обязательно поделюсь, если нет, то попробуем разобраться.

Gobo107
Offline
Зарегистрирован: 29.04.2020

Пример для меги

#include <SPI.h> 
const int chipSelectPin = 53; // SS подключаем к 7 пину ad420, SCK к 8 пину и MOSI к 9 пину
uint16_t value;

void setup()
{
  pinMode(chipSelectPin, OUTPUT);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.setDataMode(SPI_MODE1);
  SPI.begin();
}

void loop()
{
  value = 0x8000;  // проверяем, в токовой петле - 8 мА
  digitalWrite(chipSelectPin, HIGH);
  SPI.transfer(highByte(value));
  SPI.transfer(lowByte(value));
  digitalWrite(chipSelectPin, LOW);
  SPI.end;   
}

Все соединения как в даташите - Figure 6. Standart Configuration + 6 пин(CLEAR) на GND, R load = 500 Ом, ну и не забыть объединить земли ардуины и ad420