Паяльная станция из ардуино

SergAG
Offline
Зарегистрирован: 22.12.2012

a5021, какая мощность сопротивления в RC цепи? Я имею в виду этот пост.

a5021
Offline
Зарегистрирован: 07.07.2013

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

За счет кратковременности импульса нет необходимости ставить сопротивление расчитанное на полную мощность, но импульсные характеристики при выборе знать было бы очень не плохо.

В условиях недостатка информации и в качестве полумеры, можно исходить из положения, что даже плохой и неправильный снаббер это лучше, чем ничего. Совершенно точно, что для подобных цепей плохо подходят резисторы в SMD исполнении, как раз по причине плохой переносимости высоких импульсных нагрузок. Классические выводные сопротивления мощностью 1-2 Вт довольно часто можно встретить в симисторных схемах управления небольшими нагрузками в сети 220 вольт. Обычно лампами, моторчиками и чем-то подобным. К сожалению, без полного расчета нет иного способа проверить правильность подбора, кроме как по факту сгорания семистора, часто вместе со снабберной цепью. С другой стороны, правило "чам больше, тем лучше" здесь может оказаться весьма кстати, с учетом, правда, что за это решение придется платить габаритами и ценой.

Halvalife
Offline
Зарегистрирован: 20.04.2015

Ребята, есть несколько вопросов:

1. Резисторы какой мощности ставить в блок схемы с напряжением в 220в (R10, R11, R12, R14)&

2. Транзисторов IRL530n в магазине нету, посмотрел по аналогам, одним из них (не полный) значится STP24NF10 - можно ли заменить? (даташит IRL530n - http://www.e-voron.dp.ua/files/pdf/ir/tr/irl530n.pdf и даташит STP24NF10 - http://www.elenota.pl/datasheet-pdf/134599/STMicroelectronics/STP24NF10).

3. На плате уважаемого DimaD под потенциометрами две кнопки, с виду, как тактовые, - так и есть, нефиксированные на замыкание?

4. Платы зеркалить не надо (вопрос к DimaD)?

 

AnarchySaur
Offline
Зарегистрирован: 31.12.2014

Как думаете такой бп пойдет? Там есть выходы 24, 12 и 5. На все выходы 2А. 4 бакса всего.

a5021
Offline
Зарегистрирован: 07.07.2013

Выяснение этого вопроса сродни задаче определения вкуса диковинного фрукта по фотографии. :) Можно угадать, а можно не угадать.

AnarchySaur
Offline
Зарегистрирован: 31.12.2014

a5021

Ну 24 В есть, 2 А на все выводы. Вроде не сильный подвал (вынули из терминала самообслуживания)..)) Ну кондери Хитано, микрухи в панельках, 4 трансформатора.. И размеры у платы немаленькие 14,5*11 см..))

a5021
Offline
Зарегистрирован: 07.07.2013

При включении паяльник однозначно берет ток намного больше 2А. Если в этом БП стоит защита от перегрузки и он вырубается, то он не подойдет. Если он пищит, скрипит, просаживает напряжение, но не уходит в защиту, то можно спокойно брать. Паяльник быстро нагреется и блок будет работать в режиме, на который он и расчитан. Как можно догадаться, определить по фотографии, как поведет себя конкретно этот БП, решительно невозможно.

Илья73
Offline
Зарегистрирован: 06.09.2013

Halvalife пишет:

Ребята, есть несколько вопросов:

1. Резисторы какой мощности ставить в блок схемы с напряжением в 220в (R10, R11, R12, R14)&

2. Транзисторов IRL530n в магазине нету, посмотрел по аналогам, одним из них (не полный) значится STP24NF10 - можно ли заменить? (даташит IRL530n - http://www.e-voron.dp.ua/files/pdf/ir/tr/irl530n.pdf и даташит STP24NF10 - http://www.elenota.pl/datasheet-pdf/134599/STMicroelectronics/STP24NF10).

3. На плате уважаемого DimaD под потенциометрами две кнопки, с виду, как тактовые, - так и есть, нефиксированные на замыкание?

4. Платы зеркалить не надо (вопрос к DimaD)?

Про транзисторы выше писали, можно найти.

r14 можно на 2вт, другие наверно и по 1/2вт можно.

кнопки не фиксированные

Halvalife
Offline
Зарегистрирован: 20.04.2015

220 ом нету, есть 300 ом, не критично заменить? Про транзисторы так и не нашел, просьба ткнуть носом:)

1/2вт - это 1-2вт или 0,5вт?

Илья73
Offline
Зарегистрирован: 06.09.2013

Транзистор логического уровня N - канальный , буковка L в названии как правило, на ток от 5 ампер  и напряжение не менее 30в желательно.

Резистор 300 ом можно  смело ставить, по мощности любой.

 

a5021
Offline
Зарегистрирован: 07.07.2013

Насчет 30в, кстати, тут вспомнилось, как у меня в паялке несколько раз вылетал этот самый силовой мосфет логического уровня. Расследование показало, что ноутбучная зарядка (24в), от которой запитывалась паялка, в момент включения давала короткий всплеск много больше тридцати вольт. Выяснилось, причем, это почти что случайно. При очередной переделке я отпаял со входа здоровущую емкость 10000мкф, которая там стояла с самого начала и предназначалась для уменьшения помех от импульсного характера потребления тока нагрузкой, и тогда мосфеты стали гореть при каждом включении. Хоть и получается, что почти всегда эта емкость справлялась с гашением импульса при включении, но слово "почти" тут употребляется с той стати, что несколько транзисторов в разное время все же приказали долго жить.

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

Илья73
Offline
Зарегистрирован: 06.09.2013

По поводу питания вообще.

После нескольких спаленных ардуин в ходе экспериментов  подумываю заказать у китайцев  супрессоров на пять вольт, (хотя  и на другие напряжения можно) и самовосстанавливающихся предохранителей. А то бывает лазишь щупом по плате, щуп срывается и замыкает питание (разные ситуации бывают) в итоге выходит из строя  7805 в сторону замыкания и выгорает ардуина.

 

Halvalife
Offline
Зарегистрирован: 20.04.2015

IRLZ24NPBF подойдет? N-LogL 55V 18A 45W 0.06R

Чем отличается IRL530N от IRF530N? Что один, что другой 

"Транзистор полевой N-Канальный Vdss = 100 В; Rds = 0.11 Ом; Id25°C = 17 А; Id100°C = 12 А; R°C/W = 1.9 °C/Вт; Pd = 79 Вт"

a5021
Offline
Зарегистрирован: 07.07.2013

Можно сказать, что ничем и не отличаются (IRL530N vs IRF530N). Маркетинг, он такой маркетинг. IRLZ24NPBF подходит по всем параметрам.

Halvalife
Offline
Зарегистрирован: 20.04.2015

Ну, у первого индекс Л - логический уровень, у второго Ф - фет, полевой, я так понял. А как это сказывается в работе?

a5021
Offline
Зарегистрирован: 07.07.2013

Целый эксперимент с точными замерами нужно будет ставить, чтобы увидеть разницу.

a5021
Offline
Зарегистрирован: 07.07.2013

Нет ничего замороченнее, чем писать юзабилити или юзер-интерфейс в программе. Уже весь функционал давно работает, а именно где пикнуть, где пиликнуть, показать одну цифру, если это, а если это, то то... Красивая изначально программа превращается в горы наворотов с кучей условий и абсолютно нечитаемой логикой. Брррр...

a5021
Offline
Зарегистрирован: 07.07.2013

Дописал почти все юзабилити и даже заснял видео, как это работает.

 

a5021
Offline
Зарегистрирован: 07.07.2013

Рисунок печатной платы в полном разрешении. Готово для печати под ЛУТ (зеракалировать не нужно). На случай, если возникнут проблемы с масштабированием, по бокам нанесена линейка для правильного выставления размеров. Картинки кликабельны для просмотра в полном разрешении.

Список компонентов для сборки:

 

Ghisool
Offline
Зарегистрирован: 08.03.2015

Илья73, подскажите.

Мне пришёл паяльник с терморезистором, ечли подключаю его через ОУ по вашей схеме - показывает 0. Если напрямую подключаю к ноге дуины, показывает 1000-2000 градусов и показания сильно скачат туда-сюда.

Помогите попровить скетч, чтобы работало напрямую без ОУ, или подскажите что нужно поменять в ОУ.

Спасибо.

a5021
Offline
Зарегистрирован: 07.07.2013

Подобный вопрос уже задавался и я даже выдавал рекомендации. Правда, так и не известно, воспользовался ли ими хоть кто-то.

Ghisool
Offline
Зарегистрирован: 08.03.2015

a5021 пишет:

Подобный вопрос уже задавался и я даже выдавал рекомендации. Правда, так и не известно, воспользовался ли ими хоть кто-то.

Спасибо.

Т.е. можно воткнуть 2 резистора по 500 Ом, а термопару подтянуть к +5 и всё должно заработать?

Как калибровать в таком случае? Или один резистор подстроечный нужен?

Расскажите подробнее если не сложно.

Egen_M
Egen_M аватар
Offline
Зарегистрирован: 01.05.2015

a5021 пишет:

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

Здравствуйте а5021. Хочу собрать Ваше изделие. И очень бы хотелось посмотреть на новый скеч со всеми вкусностями.

Egen_M
Egen_M аватар
Offline
Зарегистрирован: 01.05.2015

Вот здесь есть схема подключения к ОУ паяльника с терморезистором http://vprl.ru/forum/2-56-3

a5021
Offline
Зарегистрирован: 07.07.2013

Скетч готов на 99.9% и 100% обкатан на реальной (и довольно интенсивной) эксплуатации. На мой взгляд, сей самопал работает весьма прилично, совсем, как "взрослые" станции. От немедленной публикации скетча здесь пока удерживают соображения по оформлению кода. Надо убрать куски отладки и дописать до конца комментарии (сейчас есть примеро 80%). Думаю, в ближайшие дни добью.

Senchurov
Offline
Зарегистрирован: 17.02.2015

Спасибо за труд.

ches10
Offline
Зарегистрирован: 15.03.2015

a5021,Спасибо. Все компоненты уже заказаны, буду собирать

a5021
Offline
Зарегистрирован: 07.07.2013

Обратите внимание на потенциометр. Он имеет не очень широко распространенный конструктив для монтажа на плату. Я как-то сразу об этом не подумал, а теперь переживаю, что с его поисками у кого-то могут возникнуть затруднения. Точно оно называется "ALPS RK09K" и выглядит вот так:

Я в свое время надрал их из старой оргтехники, но не уверен, что все имеют доступ к залежам такого барахла, а покупать оригинал может выйти дороже, чем обойдутся все остальные компоненты вместе взятые. Самое близкое, что я смог найти у китайцев и что бы могло выглядеть приемлемо по ценам можно глянуть тут.

Еще, по неизвестной причине, из списка деталей "выпала" кнопка. В ней нет ничего необычного и такие везде продаются. Просто напоминаю, если кто-то будет заказывать детали кучей.

DimaD
Offline
Зарегистрирован: 26.03.2015

Добрый день всем.

Сломалась термопара паяльника. Не прозванивается. Удалось найти нагреватель с терморезистором. Прочитал первый пост и правильно ли я понял из него подключение резистора вместо ТП?

(+5В) >-------[ 220ом ]--------analog arduino---------терморезистор------->>> (земля)

a5021
Offline
Зарегистрирован: 07.07.2013

Совершенно верно.

kang2k
Offline
Зарегистрирован: 15.05.2015

Уважаемый a5021.

С интересом перечитал всю тему. Хочется повторить Вашу схему, но без скетча не имеет смысла. Поэтому пока подожду.

Возник следующий вопрос, в начале темы, упоминается что схема под паяльник Hakko907, с термистором ?! А последняя Ваша схема под что ? Судя по рисунку, Вы используете компенсатор холодного спая термопары на tl431 ?!

Кстати, по потензиометру, вот здесь такие есть и цена в принципе не дорогая http://chipster.ru/catalog/components/passive-components/resistors/potentiometers/1962.html (не реклама, сам еще не работал с этим магазином, но цены довольно не плохие)

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

a5021 зачем делаешь проводники как волна? на всех углах накапливается заряд, не рекомендуется так делать. дело конечно твое, так на будущее

DimaD
Offline
Зарегистрирован: 26.03.2015

jeka_tm пишет:

a5021 зачем делаешь проводники как волна? на всех углах накапливается заряд, не рекомендуется так делать. дело конечно твое, так на будущее

Я как понимаю это не он, а авторазводка

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

авторазводка так обычно не делает

DimaD
Offline
Зарегистрирован: 26.03.2015

jeka_tm пишет:

авторазводка так обычно не делает

Может настройки софта ИМХО, а так автор расскажет

a5021
Offline
Зарегистрирован: 07.07.2013

Нет, авторазводкой я обычно не пользуюсь. Насчет каких-то емкостных аномалий волны я ничего не знаю. С удовольствием ознакомился бы с аргументированными рекомендациями на этот счет. Расположение проводников таким образом позволяет выкроить чуть-чуть места там, где оно требуется, а так же перераспределить образующиеся "пустоты" в пользу полигонов.

На TL431 сделан не компенсатор, а источник опорного напряжения для запитки термодатчика паяльника. Термодатчик -- термосопротивление, а не термопара. Было бы странно, если бы я прежде никогда не упоминав о термопаре, решил сделать схему под нее.

TL431, не смотря на древность и дешевизну, более стабильный и точный опорник, чем внутренний ИОН атмеги. На схеме есть даже отвод от него (точка REF_1V) для калибровки значений внутренней атмеговской опоры 1.1в, от которой считаются все аналогово-цифровые преобразования в алгоритме. Когда рисовал схему, я предусмотрел это, но пока не использовал в скетче. Если у кого-то возникнет желание добиться поывшенной точности, то такая возможность есть.

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

Насчет сектча даже не знаю, как лучше сделать. Полностью рабочий скетч наличествует, но он по прежнему пребывает в несколько неряшливом виде. Могу положить его туда же, где и все остальные материалы по этой паялке лежат, т.е. на google docs в том виде, как он сейчас существует и править там по мере сил и времени. Не возникла бы только какая-нибудь путаница из-за разных правок. Если кто-то может предложить более лучший и удобный вариант -- подсказывайте.

kang2k
Offline
Зарегистрирован: 15.05.2015

По поводу TL431 понял... Еще не очень в этом разбираюсь.

По поводу выкладывания скетча, а не лучше ли сделать на github ? Своеобразный репозитарий для открытого софта. Там удобно будет правки делать на локальной машине, а потом постить туда. Через спец. софт, будет видно какие изменения сделаны.

Хотя конечно, наверное проще тупо выкладывать на обменник, а здесь постить изменения....

Я сейчас как та обезъяна. Паялка нужна (на моей баку, сдох транс и утянул с собой всю электронику)

Хотелось бы конечно Вашу сделать.

a5021
Offline
Зарегистрирован: 07.07.2013

Ради одного файла заморачиваться с гитхабом, честно сказать, лениво. Я примерно представляю, что это такое, но никогда никаких исходников там не выкладывал. Придется вникать, разбираться.

Насчет паялки с хакдей -- это схема по тем же мотивам, как на первой странице этой ветки. Добавлен импульсный преобразователь 24->12в,  в чем можно усмотреть некий смысл. Добавлены операционники, в чем смысла нет абсолютно никакого. Для питания пятивольтовой части схемы, напряжение берется с хилого стабилизатора ардуины. Я не уверен, что это хорошая идея.

 

kang2k
Offline
Зарегистрирован: 15.05.2015

a5021 пишет:

Ради одного файла заморачиваться с гитхабом, честно сказать, лениво. Я примерно представляю, что это такое, но никогда никаких исходников там не выкладывал. Придется вникать, разбираться.

Насчет паялки с хакдей -- это схема по тем же мотивам, как на первой странице этой ветки. Добавлен импульсный преобразователь 24->12в,  в чем можно усмотреть некий смысл. Добавлены операционники, в чем смысла нет абсолютно никакого. Для питания пятивольтовой части схемы, напряжение берется с хилого стабилизатора ардуины. Я не уверен, что это хорошая идея.

Вчера почитал про гитхаб, действительно не так все просто. Разобраться можно, но не имеет смысла.

По паялке с хакдей, действительно чуть измененная схема с первой страницы. Только скетч более расширен.

Буду делать Вашу. Детали в принципе все есть под рукой, кроме переменника. Но с ним чтонить можно придумать. Думаю за выходные сделаю.

Спасибо Вам, за то что делитесь, своей разработкой

По переменнику, нашел чертеж, размеры похожи

a5021
Offline
Зарегистрирован: 07.07.2013

Подтолкнули вы меня, чтобы я таки этот скетч привел к какому-то более-менее приличному виду. После всех правок залил и проверил еще разок. Вроде новых ошибок при правке не наклепал. Исключать, конечно, ничего нельзя, но у меня оно работает, как и было задумано. В общем, смотрите, пробуйте, ругайте, хвалите, переделывайте под себя, используйте код по своему усмотрению. Отзывы (и плохие и хорошие) приветствуются.

/*
**
**      ARDUINO Soldering Station TH v1.00 (c) a5021
**              march - may 2015
**
**  http://arduino.ru/forum/proekty/payalnaya-stantsiya-iz-arduino
*/

#include <avr/sleep.h>

// ohmic value of the upper resistor in the voltage divider
#define R1   220.0
// external voltage reference (TL431)
#define V_REF  2.495
// calibrated atmega's internal voltage reference
#define REFERENCE_1V1    1.087

/*
**      soldering iron's thermal probe calibration data definitions
**/

#define ADC_CALIBRATION_DATA_LOW     1658 
#define ADC_CALIBRATION_DATA_HIGH    2373
#define CALIBRATION_TEMP_LOW         2950
#define CALIBRATION_TEMP_HIGH        18300

  // low temperature margin  (185C)
#define LOW_TEMP_MARGIN              2382
  // low temperature degree (multiplied by 100)
#define LOW_TEMP_DEGREE              18500  
  // high temperature margin (460C)			 
#define HIGH_TEMP_MARGIN             3661
  // low temperature degree (multiplied by 100)
#define HIGH_TEMP_DEGREE             46000  

  // min timeout in seconds
#define MIN_TIMEOUT_SEC              15
  // max timeout  in seconds
#define MAX_TIMEOUT_SEC              (60 * 60)
  // low power mode duration in seconds
#define LOW_POWER_MODE_DURATION      (15 * 60)
  // num of beeps before go standby
#define TICK_TOCK_COUNT              10
  // time before the display to be dimmed
#define TIME_BEFORE_DIM              10

  // heater control macros
#define   TURN_HEATER_ON   sbi(PORTB, PORTB1)
#define   TURN_HEATER_OFF  cbi(PORTB, PORTB1)
  // LED signaling
#define   TURN_LED_ON      sbi(PORTB, PORTB5)
#define   TURN_LED_OFF     cbi(PORTB, PORTB5)

  // display brightness constants
#define    MIN_BRIGHTNESS  0xE0
#define    DEFAULT_BRIGHTNESS 0xB0

  // where segment's cathodes are connected to
#define  SEG_A  (1 << PORTD5)
#define  SEG_B  (1 << PORTD7)
#define  SEG_C  (1 << PORTD0)
#define  SEG_D  (1 << PORTD3)
#define  SEG_E  (1 << PORTD4)
#define  SEG_F  (1 << PORTD6)
#define  SEG_G  (1 << PORTD1)
#define  SEG_DP (1 << PORTD2)

  // compose digits using separate segments
#define  SIGN_8  (0xFF - SEG_DP)
#define  SIGN_0  (SIGN_8 - SEG_G)
#define  SIGN_1  (SEG_B + SEG_C)
#define  SIGN_2  (SIGN_8 - SEG_C - SEG_F)
#define  SIGN_3  (SIGN_8 - SEG_E - SEG_F)
#define  SIGN_4  (SIGN_1 + SEG_F + SEG_G)
#define  SIGN_6  (SIGN_8 - SEG_B)
#define  SIGN_5  (SIGN_6 - SEG_E)
#define  SIGN_7  (SIGN_1 + SEG_A)
#define  SIGN_9  (SIGN_8 - SEG_E)
#define  SIGN_BLANK  0

  // compose some letters
#define SIGN_E   (SIGN_6 - SEG_C)
#define SIGN_F   (SIGN_E - SEG_D)
#define SIGN_r   (SEG_G + SEG_E)
#define SIGN_n   (SIGN_r + SEG_E)

  // bit manipulation macros
#ifndef cbi
  #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif

#ifndef sbi
  #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

  // number-to-7seg code translation table
const unsigned char codeTable[] = {~SIGN_0, ~SIGN_1, ~SIGN_2, 
                                   ~SIGN_3, ~SIGN_4, ~SIGN_5, 
                                   ~SIGN_6, ~SIGN_7, ~SIGN_8, 
                                                    ~SIGN_9};
                            
  // signs to be displayed      
volatile unsigned char displayBuffer[] = {~SIGN_0, ~SIGN_F, ~SIGN_F},
                       globalEvent = 0,   // bitset for event handling
                       currentDigit = 0;  // active digit at display
                       
volatile unsigned int  softTimer16_1 = 0, // software timer 1 downcounter 
                       softTimer16_2 = 0, // software timer 2 downcounter
                       dimCounter = TIME_BEFORE_DIM, // dim downcounter
                       toCounter1,        // time before low power mode
                       toCounter2,        // low power mode downcounter
                       toneDuration = 0;  // sound duration counter
                      
/*
**   application's event flags
*/

    // keypress flag                      
#define EVENT_BUTTON_PRESSED    (1<<0)
    // button pressed for a long time
#define EVENT_BUTTON_LONG       (1<<1)
    // request tone generation
#define EVENT_BEEPER_REQ        (1<<2)
    // warming up or cooling down request
#define EVENT_TEMP_CHANGE_REQ   (1<<3)
    // audio alarm request
#define EVENT_TICK_TOCK_REQ     (1<<4)
    // low power mode request
#define EVENT_ATTN_REQ          (1<<5)
    // low power mode flag
#define EVENT_LOW_POWER_MODE    (1<<6)
    // go standby flag
#define EVENT_STANDBY_MODE      (1<<7)

/*
**  flag manipulation macros
*/

#define SET_EVENT(EVENT)     cli(); globalEvent |= EVENT; sei()
#define CLEAR_EVENT(EVENT)   cli(); globalEvent &= ~EVENT; sei()
#define CHECK_EVENT(EVENT)   (globalEvent & EVENT)


void resetTimeout(unsigned int temperature) {
  unsigned int m;
  // calculate new timeout value based on current temperature
  
  OCR0B = DEFAULT_BRIGHTNESS;                  // restore display brightness
  if (!CHECK_EVENT(EVENT_TEMP_CHANGE_REQ)) {   // check if warming up flag is active
    globalEvent = 0;                           // reset all event flags
  } else {                                     // when warming up or cooling dowm process is active
    globalEvent = EVENT_TEMP_CHANGE_REQ;       // reset all event flags excluding that
  }

  /* the time before go standby and soldering iron's temperature have an inverse relationship:
     the higher termerature is, the less time it is allowed. */

  m = map(temperature, LOW_TEMP_MARGIN, HIGH_TEMP_MARGIN, MAX_TIMEOUT_SEC, MIN_TIMEOUT_SEC);

  cli();
    // set values for timeout variables
  dimCounter = TIME_BEFORE_DIM;
  toCounter1 = m;
  toCounter2 = LOW_POWER_MODE_DURATION;
  sei();
}

ISR (PCINT0_vect)  {
  // dummy interrupt service routine
  // called when one of pins D8 to D13 has changed
}

ISR(TIMER0_COMPA_vect){
  static unsigned char mSec,                      // millisecond counter   
                       quartSec;                  // 1/4 second counter
  
  PORTC |= (1<<currentDigit);                     // turn off current LED tube
  // ==========================================================================================
  //  Timeout counter routine
  // ==========================================================================================
        
  if (!(globalEvent & EVENT_TEMP_CHANGE_REQ)) {   // count if no TEMP_CHANGE_REQ active
    if (++mSec == 250) {                          // check for millisecond counter overflow
      mSec = 0;                                   // reset msec counter
      if (++quartSec == 4) {                      // check for 1/4 sec counter overflow
        quartSec = 0;                             // reset 1/4 sec counter
        
        // timeout counting
        
        // =======================[ TICK-TOCK Signaling ]==============================================        
        if (dimCounter > 0) if (--dimCounter == 0)  OCR0B = MIN_BRIGHTNESS;  // set display brightness to min.
        
        if (toCounter1 > 0) {            //decrease timout counter till 0
          if (--toCounter1 != 0) {
               // rise tick-tock flag
            if (toCounter1 <= TICK_TOCK_COUNT) globalEvent |= EVENT_TICK_TOCK_REQ;
          } else {
               // rise 'go low power mode' flag
            globalEvent |= EVENT_LOW_POWER_MODE | EVENT_ATTN_REQ;
          }
        } else {                         // in case low power mode is active
          if (toCounter2 > 0) {          // if timeout counter is greater than zero
            if (--toCounter2 != 0) {     // decrease timeout counter
              if (toCounter2 <= TICK_TOCK_COUNT) globalEvent |= EVENT_TICK_TOCK_REQ;
            } else {                     // if timeout counter is equal zero
              globalEvent |= EVENT_STANDBY_MODE;  // rise 'go stamdby' flag
            }
          }
        }
        // ==========================================================================================     
      }
    }
  }
}

ISR(TIMER0_COMPB_vect){
  //
  // displaying data, debouncing the button, tone generation
  //
  
  static unsigned char skipMarker,                   // every 3rd call's counter
                       buttonState,                  // current button state
                       prevButtonState;              // saved button state
  static unsigned int  keypressDuration;             // button press duration

  //================================================================================================
  // display routine
  //================================================================================================
  if (++currentDigit == 3) currentDigit = 0;         // for every digit...
  PORTD = displayBuffer[currentDigit];               // send value
  PORTC &= ~(1<<currentDigit);                       // and switch on

  //================================================================================================
  // Soft timers handling
  //================================================================================================
  if (softTimer16_1 != 0) softTimer16_1--;           // decrease software timer 1
  if (softTimer16_2 != 0) softTimer16_2--;           // decrease software timer 2

  if (++skipMarker == 3) {                           // on every 3rd call
    skipMarker = 0;                                  // reset counter

  //================================================================================================
  // debouncing routine
  //================================================================================================
    buttonState <<= 1;                               // prepare to get a new button state bit
    if ((PINB & (1<<PINB0)) == 0) buttonState |= 1;  // check the button state and save it
    if (buttonState == 0 || buttonState == 0xFF) {   // check the button pressed or released
      if (buttonState != prevButtonState) {          // check the button state changed
        if (buttonState == 0xFF) {                   // is it pressed?
          globalEvent |= EVENT_BUTTON_PRESSED;       // rise 'button pressed' flag
        }
      }
      if (buttonState == 0xFF) {                     // when the button is pressed
        if ((!(globalEvent & EVENT_STANDBY_MODE))    // and device is not in standby
             && (++keypressDuration == 650)) {       // and the button is pressed long enough
          globalEvent |= EVENT_STANDBY_MODE | EVENT_BUTTON_LONG; // rise standby flag
          keypressDuration = 0;                      // reset keypress duration counter
        }
      } else {
        keypressDuration = 0;                        // reset keypress duration counter
      }
    }
    prevButtonState = buttonState;                   // save current button state
  }
  //================================================================================================
  // Tone generation
  //================================================================================================
  if (bit_is_set(TCCR1A, COM1B0)) {                  // check if the tone generation is active
    if (toneDuration > 0) {                          // check if duration counter is above zero
      toneDuration--;                                // decrease the counter
    } else {                                         // in case of durationCounter == 0
      cbi(TCCR1A, COM1B0);                           // stop the tone generation
    }
  }
    
  if (CHECK_EVENT(EVENT_BEEPER_REQ) != 0) {         // check the tone generation request is appeared
    CLEAR_EVENT(EVENT_BEEPER_REQ);                  // reset request flag
    sbi(TCCR1A, COM1B0);                            // enable tone signal output
  }
}

void setSoftTimer(unsigned char tNo, unsigned int tValue) {
  // set 'tNo' soft-timer value
  switch (tNo) {
    case 1:
      cli();
      softTimer16_1 = tValue;
      sei();
      break;
    case 2:
      cli();
      softTimer16_2 = tValue;
      sei();    
      break;
  }
}

unsigned int getSoftTimer(unsigned char tNo) {
  // return specified soft timer coounter value
  unsigned int t;
  
  switch (tNo) {
    case 1:
      cli();
      t = softTimer16_1;
      sei();
      break;
    case 2:
      cli();
      t = softTimer16_2;
      sei();    
      break;
    default:
      t = 0;
      break;
  }
  return t;
}

void playTone(unsigned int pitchHz, unsigned int duration) {
  // make sound
  unsigned int pitch = (F_CPU / pitchHz - 2) / 2;   // calculate timer settings to generate desired pitch
  OCR1AH = highByte(pitch);        // set the new counter restart value high byte
  OCR1AL = lowByte(pitch);         // set the new counter restart value low byte
  cli();                           // disable interrupts to make atomic assignment
  toneDuration = duration;         // set the new tone duration value
  sei();                           // enable interrupst
  SET_EVENT(EVENT_BEEPER_REQ);     // send signal to the timer's ISR 
}
  
void fillDisplayBuffer(int value, unsigned char padChar) {
  // convert int to string and fill the display buffer
  unsigned char i = 3;             // digits at display
  unsigned int dp_req = 0;         // decimal point required flag
  div_t res;                       // conversion divider

    // check if it is the special value to shows the error message
  if (-9999 == value) {
    displayBuffer[0] = SIGN_E;    
    displayBuffer[1] = SIGN_r;    
    displayBuffer[2] = SIGN_r;    
    return;
  }

    // if passed value is smaller than 1000
  if (value < 1000) {
    dp_req = 1;        // dot required
  } else {
    value /= 10;       // devide value to fit to display
  }
  
    // padding left
  if (value < 100) displayBuffer[0] = padChar;
  if (value < 10) displayBuffer[1] = padChar;

    // convert integer to string and place it to the buffer
  do {
    res =  div(value, 10);
    displayBuffer[--i] = codeTable[res.rem];
    value = res.quot;
  } while (value != 0 && i != 0);
    // insert dot if required
  if (dp_req) displayBuffer[1]  &= ~SEG_DP;
 }


void setup() {

  // Input/Output Ports initialization
  // Port B initialization
  // Function: Bit7=In Bit6=In Bit5=Out Bit4=In Bit3=In Bit2=Out Bit1=Out Bit0=In 
  DDRB=(0<<DDB7) | (0<<DDB6) | (1<<DDB5) | (0<<DDB4) | (0<<DDB3) | (1<<DDB2) | (1<<DDB1) | (0<<DDB0);
  // State: Bit7=T Bit6=T Bit5=0 Bit4=T Bit3=T Bit2=1 Bit1=0 Bit0=P 
  PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (1<<PORTB2) | (0<<PORTB1) | (1<<PORTB0);

  // Port C initialization
  // Function: Bit6=In Bit5=In Bit4=In Bit3=In Bit2=Out Bit1=Out Bit0=Out 
  DDRC=(0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (1<<DDC2) | (1<<DDC1) | (1<<DDC0);
  // State: Bit6=T Bit5=P Bit4=P Bit3=T Bit2=0 Bit1=1 Bit0=1 
  PORTC=(0<<PORTC6) | (1<<PORTC5) | (1<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (1<<PORTC1) | (1<<PORTC0);

  // Port D initialization
  // Function: Bit7=Out Bit6=Out Bit5=Out Bit4=Out Bit3=Out Bit2=Out Bit1=Out Bit0=Out 
  DDRD=(1<<DDD7) | (1<<DDD6) | (1<<DDD5) | (1<<DDD4) | (1<<DDD3) | (1<<DDD2) | (1<<DDD1) | (1<<DDD0);
  // State: Bit7=1 Bit6=1 Bit5=1 Bit4=1 Bit3=1 Bit2=1 Bit1=1 Bit0=1 
  PORTD=(1<<PORTD7) | (1<<PORTD6) | (1<<PORTD5) | (1<<PORTD4) | (1<<PORTD3) | (1<<PORTD2) | (1<<PORTD1) | (1<<PORTD0);

  // Timer/Counter 0 initialization
  // Clock source: System Clock
  // Clock value: 250,000 kHz
  // Mode: CTC top=OCR0A
  // OC0A output: Disconnected
  // OC0B output: Disconnected
  // Timer Period: 1 ms
  TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) | (1<<WGM01) | (0<<WGM00);
  TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (1<<CS00);
  TCNT0=0x00;
  OCR0A=0xF9;
  OCR0B = DEFAULT_BRIGHTNESS;

  // Timer/Counter 0 Interrupt(s) initialization
  TIMSK0=(1<<OCIE0B) | (1<<OCIE0A) | (0<<TOIE0);

  // Timer/Counter 1 initialization
  // Clock source: System Clock
  // Clock value: 16000,000 kHz
  // Mode: CTC top=OCR1A
  // OC1A output: Disconnected
  // OC1B output: Disconnected
  // Noise Canceler: Off
  // Input Capture on Falling Edge
  // Timer Period: 0,5 ms
  // Output Pulse(s):
  // Timer1 Overflow Interrupt: Off
  // Input Capture Interrupt: Off
  // Compare A Match Interrupt: Off
  // Compare B Match Interrupt: Off
  TCCR1A=(0<<COM1A1) | (0<<COM1A0) | (0<<COM1B1) | (0<<COM1B0) | (0<<WGM11) | (0<<WGM10);
  TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (1<<WGM12) | (0<<CS12) | (0<<CS11) | (1<<CS10);
  TCNT1H=0x00;
  TCNT1L=0x00;
  ICR1H=0x00;
  ICR1L=0x00;
  OCR1AH=0x1F;
  OCR1AL=0x3F;
  OCR1BH=0x00;
  OCR1BL=0x00;

  // ADC initialization
  // ADC Clock frequency: 125,000 kHz
  // ADC Voltage Reference: Internal 1.1v
  // ADC Auto Trigger Source: Timer0 Compare Match
  // Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: Off, ADC4: On, ADC5: On
  DIDR0=(0<<ADC5D) | (0<<ADC4D) | (1<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (0<<ADC0D);
  ADMUX=((1<<REFS1) | (1<<REFS0) | (0<<ADLAR)) | 7;
  ADCSRA=(1<<ADEN) | (0<<ADSC) | (1<<ADATE) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
  ADCSRB=(0<<ADTS2) | (1<<ADTS1) | (1<<ADTS0);

  // go standby as soon as power is applied
  SET_EVENT(EVENT_STANDBY_MODE);
}

unsigned long int getOversampled(unsigned char ch) {
  unsigned int sSum = 0;
  unsigned char adc_low, adc_high, i = 0;
  /*
  **    AD conversions are started (triggered) by TIMER0 COMPARE MATCH A
  **    The routine waits for ADC data has become available, sums it 
  **    and returns averaged result in 12 bit resolution
  */

  ADMUX=((1<<REFS1) | (1<<REFS0) | (0<<ADLAR)) | ch; // select 1.1v internal reference and set the input channel

  // to avoid some wrong data it needs to skip several ADC cycles

    // ignore two first ADC results
  do {
    loop_until_bit_is_set(ADCSRA, ADIF);   // wait for EoC flag
    sbi(ADCSRA, ADIF);                     // clear EoC flag
    adc_low  = ADCL;                       // get low byte
    adc_high = ADCH;                       // get high byte
  } while (++i == 2);                      // repeat it two times

 
    // get 64 samples after the channel has become stable
  for (i = 0; i < 64; i++) {
    loop_until_bit_is_set(ADCSRA, ADIF);
    sbi(ADCSRA, ADIF);
    
    // read ADCL first; doing so locks both ADCL
    // and ADCH until ADCH is read.  reading ADCL second would
    // cause the results of each conversion to be discarded,
    // as ADCL and ADCH would be locked when it completed.
    adc_low  = ADCL;
    adc_high = ADCH;
    // sum all samples
    sSum += (adc_high << 8) | adc_low;
  }
    
  return sSum >> 4;         // return averaged ADC result in 12 bit representation
} 

/*******************************************************************
***
***   DEBUG-ONLY SECTION
***   NOT USED IN NORMAL CODE FLOW
***
*******************************************************************/

#ifdef USE_DEBUG_CODE

float dV = REFERENCE_1V1 / 4096.0;

float getVoltage(unsigned char ch) {
  // return voltage in channel 'ch;
  unsigned int v = getOversampled(ch);
  
  return v * dV;
}

float getSensorResistance(void) {
  // get soldering iron's probe resistance
  float v = getVoltage(7);
  
  return R1 / (V_REF / v - 1.0);
} 

#endif
/*********************** END OF DEBUG-ONLY SECTION ****************/

unsigned int findDifference(unsigned int a, unsigned int b) {
  // compare 'a' and 'b' and return the difference
  
  if (a == b) return 0;        // return zerro in case a = b
  if (a > b) return a - b;     // self-exlplained code :)
  return b - a;
}

unsigned char displayMode = 0,    // data display selector
              tickCounter = TICK_TOCK_COUNT, // countdown stage counter
              skipMarker = 0;        // skip counter

unsigned int  sensorData,            // soldering iron's temperature probe data
              targetTemperature,     // the temperature the soldering iron must be heated up to
              wiperPosition;         // ADC value from pot's middle contact

/*
**
**      Main program loop
**
*/


void loop() {

  unsigned int displayValue,                    // data to be send to display
               currentTemperature;              // soldering iron temperature

#ifdef USE_DEBUG_CODE               
  float        voltage;                         // the var for voltage measurement
#endif  


  if (CHECK_EVENT(EVENT_TICK_TOCK_REQ)) {       // check the countdown flag is risen
    tickCounter++;                              // increase stage counter
    CLEAR_EVENT(EVENT_TICK_TOCK_REQ);           // take down the flag
    if (tickCounter < 5) {                      // check it is a first half of countdown
      playTone(8000, 5);                        // play short high tone sound
    } else {                                    // increase loudness
      if (tickCounter != TICK_TOCK_COUNT) {     // check if it isn't last tick
        displayMode = 3;                        // set show tick display mode
        OCR0B = DEFAULT_BRIGHTNESS;             // increase brightness
        playTone(1000, 100);                    // make load beep
      } else {                                  // if it is last tick               
        playTone(1000, 800);                    // play the final beep
      }
    }
  }

  // ======================= STANDBY mode routine ==========================================
  if (CHECK_EVENT(EVENT_STANDBY_MODE)) {  // check the standby flag is risen
    TURN_HEATER_OFF;                      // turn heater off
    TURN_LED_OFF;                         // turn LED off
    displayBuffer[0] = ~SIGN_BLANK;       // blank display
    displayBuffer[1] = ~SIGN_BLANK;
    displayBuffer[2] = ~SIGN_BLANK;

    if (CHECK_EVENT(EVENT_BUTTON_LONG)) {
      playTone(1000, 800);                // play long beep
      setSoftTimer(2, 800);               // set soft timer to wait for signaling
    }

    tickCounter = 0;                      // reset tickCounter

    // wait for the button is released and time is out
    while ((PINB & (1<<PINB0)) || getSoftTimer(2)); 
    TCCR0B &= ~0b111;                     // No clock source (Timer/Counter stopped)
    cbi(TCCR1A, COM1B0);                  // disable speaker output
    toneDuration = 0;                     // reset tone duration counter
    PCMSK0 |= bit (PCINT0);               // set pin 8 as interupt source
    PCIFR  |= bit (PCIF0);                // clear any outstanding interrupts
    PCICR  |= bit (PCIE0);                // enable pin change interrupts for D8 to D13    
    set_sleep_mode (SLEEP_MODE_PWR_DOWN); // set powerdown sleep mode
    sleep_enable();                       // allow enter into sleep mode

    unsigned long int t = 0;              // local keypress duration counter
        
    while(1) {                            // go to endless standby loop
      if ((PINB & (1<<PINB0)) == 0) {     // check for button pressed
        if (++t == 0x00300000) {          // count keyperss duration and check it is long enough
          PCMSK0 &= ~(1<<PCINT0);         // disable pin 8 interrupt
          PCICR  &= ~(1<<PCIE0);          // disable pin change interrupts for D8 to D13 
          break;                          // leave loop
        }
      } else {                            // if no kepress detected
        t = 0;                            // reset keypress duration counter
        sleep_cpu ();                     // go Sleep and wait for the interrupt   
      }
    }
    TCCR0B |= (1<<CS01) | (1<<CS00);      // enable TIMER0 clocking
    resetTimeout(LOW_TEMP_MARGIN);        // reset timeout counters
    displayMode = 0;                      // set display mode
    targetTemperature = 0;                // reset target temperature
    playTone(1000, 600);                  // play greeting
  }   
  // ======================= End of STANDBY mode routine =======================================
  
  sensorData = getOversampled(7);         // get data from termal probe

  if (++skipMarker == 3) {                // every 3rd loop
    skipMarker = 0;                       // reset loop counter
      // reflect potentiometer's wiper position to temperature scale
    wiperPosition = map(getOversampled(6), 0, 4095, LOW_TEMP_MARGIN, HIGH_TEMP_MARGIN);
      // check if pot's data is different enough from target temperature
    if (findDifference(targetTemperature, wiperPosition) > 5) {
      OCR0B = DEFAULT_BRIGHTNESS;         // increase display brightness
      displayMode = 0;                    // set display mode
      tickCounter = 0;                    // reset countdown var
      targetTemperature = wiperPosition;  // set new target temperature
      setSoftTimer(2, 1500);              // set period for displaying target temperature instead of
                                          // measured one
      CLEAR_EVENT(EVENT_LOW_POWER_MODE);  // leave low power mode
      SET_EVENT(EVENT_TEMP_CHANGE_REQ);   // set temperature changing flag
    }
  }
  
  if (CHECK_EVENT(EVENT_BUTTON_PRESSED)) {// check keypress flag is set
    displayMode = 0;                      // force display's main mode
    CLEAR_EVENT(EVENT_BUTTON_PRESSED);    // resed keypress flag
    OCR0B = DEFAULT_BRIGHTNESS;           // set display brighter
    tickCounter = 0;                      // reset tickCounter
    resetTimeout(sensorData);             // re-calc timeout period
    playTone(8000, 20);                   // make short audible 'click'
  }
  
    // represent current soldering iron temperature using the calibration data
  currentTemperature = map(sensorData,
                           ADC_CALIBRATION_DATA_LOW,
                           ADC_CALIBRATION_DATA_HIGH,
                           CALIBRATION_TEMP_LOW,
                           CALIBRATION_TEMP_HIGH) / 10;

  switch (displayMode) {
    case 0:
      if (!CHECK_EVENT(EVENT_TEMP_CHANGE_REQ)) {                          // if no changing temperature flag is set
        if (findDifference(sensorData, targetTemperature) < 10) {         // check the temperature is in the allowed boundaries
          displayValue = map(targetTemperature, 
          	             LOW_TEMP_MARGIN, 
                             HIGH_TEMP_MARGIN, 
                             LOW_TEMP_DEGREE / 10,
                             HIGH_TEMP_DEGREE / 10);                      // use target temperature for displaying
        } else {                                                          // in the case of temperature drift is high enough
          if (CHECK_EVENT(EVENT_LOW_POWER_MODE)) {                        // if low power mode is active
            if (findDifference(sensorData, LOW_TEMP_MARGIN) < 7  ) {
              displayValue = LOW_TEMP_DEGREE / 10;                        // display fixed low margin degree value
            } else {
              displayValue = currentTemperature;                          // show real measured temperature
            }
          } else {                                                        // in main mode
            displayValue = currentTemperature;                            // show real measured temperature
          }
        }
      } else {                                                            // in heating up or cooling down stage
        if (!getSoftTimer(2)) {                                           // if target temperature is not changed recently
          displayValue = currentTemperature;                              // display real measured temperature
        } else {                                                          // target temperature just changed 
          displayValue = map(wiperPosition, 
          	             LOW_TEMP_MARGIN, 
                             HIGH_TEMP_MARGIN, 
                             LOW_TEMP_DEGREE / 10,
                             HIGH_TEMP_DEGREE / 10);      // show target temperature
        }
      }
      break;
/******************************************************************
***
***
***  DEBUG ONLY SECTION
***
***      
*******************************************************************/
#ifdef  USE_DEBUG_CODE
    case 1:
      displayValue = (getVoltage(3) - 1.0) * 10000;         
      break;
    case 2:
      displayValue = (getSensorResistance()) * 10;
      break;
#endif
/********************* END OF DEBUG CODE **************************/
    case 3:
      displayValue = TICK_TOCK_COUNT - tickCounter; // show countdown values
      break;
    default:
      break;
  }

  fillDisplayBuffer(displayValue, ~SIGN_BLANK);    // send data to the display

  if (CHECK_EVENT(EVENT_LOW_POWER_MODE)) {         // if low power mode active
    if (CHECK_EVENT(EVENT_ATTN_REQ)) {             // check if it is first occurrence
      CLEAR_EVENT(EVENT_ATTN_REQ);                 // down flag
      tickCounter = 0;                             // reset tick counter
      OCR0B = MIN_BRIGHTNESS;                      // lower display brightness
      displayMode = 0;                             // set main display mode
    }
    wiperPosition = LOW_TEMP_MARGIN;    // force targed temperature to 185C degree
  }

  /*****************************************************************
  **
  **  HEATER CONTROL SECTION
  **
  *****************************************************************/

  if (sensorData < wiperPosition) {                // check if current temperature is lower than target one                     
    TURN_HEATER_ON;                                // force heating up
    TURN_LED_ON;                                   // toggle LED on
  } else{                                          // the current temperature is equal to target one or above
    TURN_HEATER_OFF;                               // disable heating up
    TURN_LED_OFF;                                  // toggle LED off
  }
  /*****************************************************************/


    // check if it is temperature changing mode
  if (CHECK_EVENT(EVENT_TEMP_CHANGE_REQ) != 0) {
      // check if temperature target has reached
    if (findDifference(sensorData, wiperPosition) < 5) {
      CLEAR_EVENT(EVENT_TEMP_CHANGE_REQ);
      resetTimeout(sensorData);  // recalculate timeout
      playTone(4000, 50);        // play 'temperature matched' sound mark
    }
  }
  
}

Допускаю, что коментарии в исходнике содержат ошибки и опечатки.

Spyer
Offline
Зарегистрирован: 07.04.2014

Добрый день формучане!

Собираю для себя паяльную станцию, приобрел паяльник, фен. Для того чтобы сначала разобратся как это все работает делаю на макетке, но при по при сборке схемы по получения температуры с пальника через ОУ у меня на АЦП ардуины выходит "0". Собирал разные схемы уселения, и все равно ни чего не получается.

Собирал по схемам:

http://habrahabr.ru/post/248959/

http://arrduinolab.blogspot.ru/2015/02/arduino.html

http://d-serviss.lv/index.php?mod=pages&pageName=solderingstation

Подскажите в чем может быть проблема?

 

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

короче смысл в том что когда делаешь много ненужных изгибов ты делаешь индуктивность, да который еще обладает емкостью. возникают обратные/отраженные токи и ты ухудшаешь плату. без необходимости не стоит так делать. на низкой частоте не кретично, но если частота уже мегагерцы дело другое. взаимное влияние проводников, наводки

Spyer
Offline
Зарегистрирован: 07.04.2014

Еще раз посмотрел на макетку которую делаю, вроде соответтсвует.

На выходе от термопары мой мультиметр показывает напряжение  0.2 (при деление 200 мВ) когда зажимаю терморапу руками, а на выходе из ОУ напряжение такое же.

a5021
Offline
Зарегистрирован: 07.07.2013

jeka_tm пишет:

на низкой частоте не кретично, но если частота уже мегагерцы дело другое. взаимное влияние проводников, наводки

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

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

Убедитесь, что сам ОУ у вас работает. Соберите схему усилителя отдельно от всего. Подключите термопару на вход. Измерьте напряжение на выходе. При исправном ОУ и правильно собранной схеме, нуля там быть не может в принципе.

Стоит еще заметить, что использовать LM358 при пятивольтовом питании в цепях АЦП -- это вообще не очень хорошая идея. Полистайте топики в "Аппаратном обеспечении". Там этот вопрос неоднократно поднимался.

Spyer
Offline
Зарегистрирован: 07.04.2014

a5021 пишет:

jeka_tm пишет:

на низкой частоте не кретично, но если частота уже мегагерцы дело другое. взаимное влияние проводников, наводки

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

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

Убедитесь, что сам ОУ у вас работает. Соберите схему усилителя отдельно от всего. Подключите термопару на вход. Измерьте напряжение на выходе. При исправном ОУ и правильно собранной схеме, нуля там быть не может в принципе.

Стоит еще заметить, что использовать LM358 при пятивольтовом питании в цепях АЦП -- это вообще не очень хорошая идея. Полистайте топики в "Аппаратном обеспечении". Там этот вопрос неоднократно поднимался.

И так собираю схему только получение температуры, а подскажите если знаете схемы как можно проверить ОУ

a5021
Offline
Зарегистрирован: 07.07.2013

Я всегда стараюсь помогать в решении каких-то "электронных" вопросов, если это в пределах моей компетенции. Только ваш вопрос будет тут совсем уж офтопиком. Не к месту здесь рассматривать работу электронных компонентов, которые в обсуждаемой конструкции и не используются даже. Абсолютно уверен, что если вы поднимете волнующую вас тему в "Аппаратных вопросах", то найдется не один желающий выссказать свое мнение на сей счет.

kang2k
Offline
Зарегистрирован: 15.05.2015

2 a5021 Я прошу прощения, Вы не могли бы выложить исходники печатки (вроде они в Eagle ?! )

Заранее спасибо

a5021
Offline
Зарегистрирован: 07.07.2013

Только не в игле, а в протеусе.

kang2k
Offline
Зарегистрирован: 15.05.2015

a5021 пишет:

Только не в игле, а в протеусе.

Протеус, даже лучше... Не могу нормально распечатать с картинки. 4 раза печатал, плохо переводится на плату...

a5021
Offline
Зарегистрирован: 07.07.2013

Проект полностью.

Если кто-то задумает ставить плату в корпус и сооружать лицевую панель, то нужно учитывать следущее: самой возвышающейся часть на плате является ардуино. Если предполагается его долгая эксплуатация именно в данном устройстве, то есть смысл не ставить ни разъем ни кроватку под него и не припаивать ему ноги, а как можно плотнее запаивать прямо на плату. Светодиодный дисплей же, напротив, стоит поднять или поставить на разъем так, чтобы он стал самой возвышающейся деталью и оказался, как можно ближе к стеклу лицевой панели. Еще придется задуматься, как удлинить рабочие части переменного резистора и кнопки.