В связи с этим был разработан ряд из трех плат прототипирования, об одной из них, самой простой я расскажу в этой статье.
Итак, что мне было необходимо:
- Работа с GPIO как со входами так и с выходами;
- Управление нагрузкой;
- Подключение датчиков температуры по шине 1-Wire;
- Измерение напряжения;
- Часы реального времени;
- Контроль и управление внешним устройством по шине RS485;
- Отдельный источник питания для платы расширения;
Согласно вышеприведенному списку была разработана схема электрическая принципиальная:
> Схема из хранилища с высоким разрешением
В схеме используется трансформаторный источник питания с двумя выходными обмотками. Первая обмотка работает на линейный стабилизатор напряжения с выходом 5В, для питания микросхемы драйвера RS485 и часов реального времени. Вторая обмотка используется для питания электромагнитных реле и сборки с транзисторами Дарлингтона.
Температурный датчик DS18B20 питается от +3.3В с платы Raspberry Pi, на плате предусмотрен разъем для подключения внешних датчиков DS18B20, это же напряжение берется для АЦП и согласования уровней с часами реального времени. В схеме использованы четыре кнопки S1-S4 для управления какими-либо действиями, работают по низкому логическому уровню. Для управления нагрузками используется транзисторная сборка DD1 ULN2003 со встроенными защитными диодами. К выводам 16, 15 транзисторной сборки подключены реле K1 и K2, к выводам 14-12 подключены светодиоды для индикации, выводы 11, 10 предназначены для подключения к внешним устройствам по схеме с общим коллектором или дополнительных реле с напряжением обмотки +12В.
Для измерения напряжения используется два канала 10 битного АЦП DD3 MCP3008 с интерфейсом SPI, со входным НЧ фильтром. Аналоговый узел сделан примитивно, для академических целей или быстрой отладки. Если встанет вопрос о качественном измерении аналогового сигнала, придется развязать цифровую и аналоговую землю, использовать внешний источник опорного напряжения. Как вариант, аналоговую часть можно сделать так:
Только необходимо будет использовать преобразователь уровней TTL > LVTTL на шине SPI.
Часы реального времени DD4 выполнены на микросхеме DS1307, для тактирования используется кварцевый резонатор Q1 на 32,768 КГц. Для питания RAM микросхемы часов используется литиевая батарея на 3 вольта, впаянная в плату. Микросхема подключается через преобразователь уровней 5В-3,3В выполненных на МДП-транзисторах VT2, VT3 к Raspberry Pi по шине I2C (В САПР использовано подключение к линиям без явной связи).
В качестве драйвера UART > RS485 использована микросхема DD2 ST485. Схемное решения с применением транзистора VT1 позволило отказаться от отдельного выхода для управления приемопередатчиком. Он переключается в режим передачи, только когда UART передает данные, остальное время ST485 находится в режиме приема. Команда управления приемопередатчиком снимается с коллектора транзистора VT1.
Помимо преобразования интерфейсов, данная схема также выполняет функцию согласования уровней LVTTL интерфейса UART Raspberry Pi с уровнями TTL драйвера ST485. Сигнал снятый с коллектора транзистора VT1 подтягивает уровень на входе DI до 5В, а резистор R16 и стабилитрон VD8 ограничивают уровень с выхода R0 до 3,3В. Не обращайте внимание на резистор R11, он остался в схеме при отладке. RS485 испробован с протоколом ModBus RTU на скорости 115200 бод.
Соответственно далее была разработана печатная плата:
Вариант схемы соединения с внешними устройствами:
Для проверки узлов платы расширения я использовал пару скриптов на языке python (я этот язык не знаю, писал методом проб и ошибок, параллельно подглядывая в коды специалистов)
Для измерения напряжения от потенциометра подключенного к каналам АЦП я написал простой скрипт:
#!/usr/bin/python
# Example program to read data from MCP3008 10 bit ADC
import spidev
import time
import os
# Open SPI bus
spi = spidev.SpiDev()
spi.open(0,0)
# Function to read SPI data from MCP3008 chip
# Channel must be an integer 0-7
def ReadChannel(channel):
adc = spi.xfer2([1,(8+channel)<<4,0])
data = ((adc[1]&3) << 8) + adc[2]
return data
# Function to convert data to voltage level,
# rounded to specified number of decimal places.
def ConvertVolts(data,places):
volts = (data * 3.3) / float(1023)
volts = round(volts,places)
return volts
# Define sensor channels
first_channel = 0
second_channel = 1
# Define delay between readings
delay = 5
print "------------------------------------------------------"
while True:
# Read the first channel data
first_level = ReadChannel(first_channel)
first_channel_volts = ConvertVolts(first_level,2)
# Read the second channel data
second_level = ReadChannel(second_channel)
second_channel_volts = ConvertVolts(second_level,2)
# Print out results
print "------------------------------------------------------"
print("First ADC channel: {} ({}V)".format(first_level,first_channel_volts))
print("Second ADC channel : {} ({}V)".format(second_level,second_channel_volts))
# Wait before repeating loop
time.sleep(delay)
Для работы с термометрами DS18B20 использован следующий скрипт:
# Example program to read data from DS18B20
# This code taken from
# https://kropochev.com/?go=all/raspberry-pi-and-onewire-sensor/
import os
import glob
import time
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '10*')[0]
device_file = device_folder + '/w1_slave'
def read_temp_raw():
f = open(device_file, 'r')
lines = f.readlines()
f.close()
return lines
def read_temp():
lines = read_temp_raw()
while lines[0].strip()[-3:] != 'YES':
time.sleep(0.2)
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_c, temp_f
while True:
print(read_temp())
time.sleep(1)
Также я задокументировал настройки в Raspbian:
— 1 Wire settings:
— Raspbian wheezy
Enter command in console:
pi@raspberrypi~$ sudo modprobe w1-gpio
pi@raspberrypi~$ sudo modprobe w1_therm
Then check sensor in system:
pi@raspberrypi ~ $ sudo ls /sys/bus/w1/devices/w1_bus_master1/
You can see the tabel below entered comman and
there you should find HEX like 28-000002da8328;
This is DS18B20 address;
Next read the data from DS18B20 sensor using command:
pi@raspberrypi ~ $ cat /sys/bus/w1/devices/w1_bus_master1/28-000002da8328/w1_sla
And you are going see temperature in console like:
6f 01 4b 46 7f ff 01 10 67: crc=67 YES
6f 01 4b 46 7f ff 01 10 67 t=22937
t=22937 — you should divide this number on 1000 and you will have temperature in Celsius;
— Raspbian Jezzy
Enter command:
pi@raspberrypi~$ sudo nano /boot/config.txt
On next step you should write in config file
dtoverlay=w1-gpio,gpiopin=4
dtoverlay=w1-gpio-pullup
Then you should reboot your raspberry Pi;
— I2C Real Time Clock settings:
— Update your system if it needed and install i2c-tools:
pi@raspberrypi~$ sudo apt-get update
pi@raspberrypi~$ sudo apt-get -y upgrade
pi@raspberrypi~$ sudo apt-get i2c-tools:
Enter command:
pi@raspberrypi~$ sudo nano /etc/modules
Add these lines:
i2c-bcm2708
i2c-dev
rtc_ds1307
Comment one line in file:
pi@raspberrypi~$ sudo nano /etc/modprobe.d/raspi-blacklist.conf
Add # Symbol in beginning of line
blacklist i2c-bcm2708
________________________________________________________
Reboot system;
Enter command:
pi@raspberrypi~$ sudo lsmod
You will see lines like:
rtc_ds1307 7715 0
i2c_dev 5277 0
i2c_bcm2708 4719 0
________________________________________________________
Get DS1307 address:
pi@raspberrypi~$ sudo i2cdetect -y 1
You will see table in console:
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — -- — -- — -- — -- — -- — -- — 10: — -- — -- — -- — -- — -- — -- — -- — --
20: — -- — -- — -- — -- — -- — -- — -- — --
30: — -- — -- — -- — -- — -- — UU — -- — --
40: — -- — -- — -- — -- — -- — -- — -- — --
50: — -- — -- — -- — -- — -- — -- — -- — --
60: — -- — -- — -- — -- 68 — -- — -- — -- — 70: — -- — -- — -- — --
In address 0x3b some device without driver and 0x68 perhaps DS1307 clock address.
Enter command:
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
Read clock:
pi@raspberrypi~$ sudo hwclock -r
Set time:
pi@raspberrypi~$ sudo hwclock -w
Set system time from RTC:
pi@raspberrypi~$ sudo hwclock -s
Automatic RTC start;
Add lines in /etc/rc.local file
echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device
sudo hwclock -s
Before last line in file looks like:
exit 0
— Uart settings:
— Back up files:
cp /boot/cmdline.txt /boot/cmdline.bak
cp /etc/inittab /etc/inittab.bak
Delete «console=ttyAMA0,115200» и «kgdboc=ttyAMA0,115200» lines from configuration file:
pi@raspberrypi~$ nano /boot/cmdline.txt
Comment last line looks like «T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100: in /etc/inittab file: using # symbol:
pi@raspberrypi~$ nano /etc/inittab
Печатная плата была нужна в срочном порядке, поэтому изготавливал сам, используя ЛУТ технологию и пару часов свободного времени. Дабы облегчить труд и сэкономить время, печатную плату сделал одностороннюю с перемычками из МГШВ 0,5. Проект схемы и печатной платы в DipTrace, тестовые исходные коды, перечень комплектующих и туториал с командами для конфигурации в
репозитории.
PS: в приведенном ниже видеоролике используется самая первая плата для моделирования, она была собрана на макетной плате с кнопками и светодиодами за 20 минут, на базе нее появились следующие версии:
Комментарии (14)
vchs
26.01.2017 17:49+1Нормально. Но по RS485 уж совсем ни защиты ни согласования волнового сопротивления хотя бы в примитивном виде. В домашних условиях и на скорости 9600 проблем не будет, а вот выйти из режима «квартиры», да повысив скорость можно будет поймать неприятные плавающие проблемы.
Jmann
26.01.2017 17:51Абсолютно с вами согласен, правда эта плата используется только на столе, на коротких линиях. В промышленном исполнении шина RS485 защищена TVS-диодами и гальванически развязана.
beho1der
26.01.2017 19:02Очень интересная разработка, таких плат кстати мало, насколько знаю их всех более-менее функциональных только PiFace 2, но по мне там не хватает многих функций. Не хотели бы попробовать сделать более расширенную плату с увеличением входов\выходов? Кстати эти платы подходят также под Orange Pi, единственное программный код возможно придется переделать.
Jmann
26.01.2017 19:30На element14 есть разные платы, включая adafruit, piFace и тд, одну из adafruit плат мне даже пришлось клонировать, так понравилась =). По существу, я уже разработал несколько таких плат расширения. Некоторые остались на бумаге, некоторые воплотил в жизнь, например эту ->
Единственное что пока не реализовывал из популярных тюнинг обвесов Raspberry Pi, аппаратный ШИМ и управление двигателями.
beho1der
26.01.2017 20:21Самое интересное, что все эти платы дороже чем сама Raspberry Pi не говоря уже о OrangePI. Не думали попробовать сделать свою версию для продажи? Вижу опыт у вас есть, у меня тоже есть наброски схемы доп платы для Raspberry Pi\OrangePI которая позволит сразу разрабатывать системы автоматизации, но опыта изготовления плат нету.
REPISOT
26.01.2017 21:18В схеме используется трансформаторный источник питания с двумя обмотками.
Одна первичная, две вторичных. Итого — 3.
100n на входе АЦП – это очень низкая полоса частот.
По описанию ADR02 требует от 7В на входе, у вас – 5В
Обмотка реле не зашунтирована диодом
Это то, что бросилось в глаза.
так что я бы на вашем месте не сталделать свою версию для продажи
Jmann
26.01.2017 21:37Одна первичная, две вторичных. Итого — 3.
Имелось ввиду две вторичные обмотки, спасибо что указали подправил.
100n на входе АЦП – это очень низкая полоса частот.
Пощупать и понять работу АЦП, измерив напряжение от движка потенциометра. Думаю достаточно и среза в 160Гц.
По описанию ADR02 требует от 7В на входе, у вас – 5В
Ошибся, исправлю на ADR03. Схема не использовалась в реальном изделии, а была указана только как пример.
Обмотка реле не зашунтирована диодом
Диоды встроен в ULN2003
так что я бы на вашем месте не сталНу вы способны сделать такое и сами =)
VT100
28.01.2017 13:13По схемотехнике:
- Согласование уровней у DS1307 — лишнее. Поскольку у DS1307 минимальное входное напряжение «лог. 1» равно 2.2 В, то достаточно подключить подтягивающие резисторы SDA и SCL (R18 и R17) не к 5, а к 3.3 вольтам.
Схемное решения с применением транзистора VT1 позволило отказаться от отдельного выхода для управления приемопередатчиком. Он переключается в режим передачи, только когда UART передает данные, остальное время ST485 находится в режиме приема.
Не айс… Фактически, такая схема не передаёт «лог. 1» в линию, а оставляет её в высокоимпедансном состоянии — чем-то подобно CAN'У получается, но там обязательны резисторы на линиях, формирующие рецессивный уровень сигнала (ЕМНИП). В итоге — страдает совместимость (в подключенном устройстве может не оказаться нужных резисторов) и помехозащищённость.
P.S. Схема — весьма подслеповатая, может я у ST485 не разглядел нумерацию выводов?
Jmann
28.01.2017 16:14По шине RS485 вы правы, выше уже писал. И да, это:
Плата расширения для моделирования
По согласованию, ну привык я так. Не люблю резисторы на линиях, нравится использовать ключи или буферные. микросхемы.
webzuweb
Т.е. самой первой плате уже более 1.5 лет?
Jmann
Получается так.