Перейти к содержанию

Ушик

Members
  • Постов

    88
  • Зарегистрирован

  • Посещение

Весь контент Ушик

  1. Спасибо, доходчиво и понятно разъяснили. Я думал, что пользовательская программа и бутлоадер - они живут в разных, не связанных между собой областях памяти. Пусть и в пределах одного поля памяти, не важно. Типа как в атмеловских чипах - выделил кусок памяти под загрузчик и забыл про нее. Ну а раз так нельзя и надо исходники бутлоадера пришивать к своим исходникам, то все плохо. Хотя остается вопрос: в сети гуляет куча всяких бутлоадеров для пиков, и большая часть именно в виде скомпилированных кексов, без исходников. А с этими тогда как быть? Блин, блин, вот же блин! Придется собирать программатор.
  2. Да, еще запоздалое прозрение. Может быть какой-либо софт умеет использовать эту микрочиповскую шайбу как программатор? А то ICD2 что-то ни в одной программе не попадается.
  3. Поставил я этот IPE, но не нашел в ней поддержки своего ICD2. Наверное, плохо искал. Для чего мне нужен бутлоадер. В моем видении мира он (бутлоадер) превращает коммуникационный порт ПК в программатор. Т.е. я пишу новую программу, получаю кекс. Затем подключаю своё устройство к ПК, запускаю программу поддержки этого бутлоадера и вливаю новую прошивку с процессор. Устройство приобретает новые функции, еще более улучшенные. Все счастливы. Отыскав готовый бутлоадер (и даже не один) я радовался, что половина дела сделана. Как же я заблуждался! Для меня бутлоадер - это та же ардуина, подключил и работай. Поясните, пожалуйста, что Вы имеете в виду? Насколько я представляю, общий функционал в целом остается прежним. Меня (сейчас) интересуют 1-2 канала ШИМ, 1 таймер, I2C, GPIO. Возможно, в конечной программе нужно будет указывать какие-то моменты, но это я дальше буду уже постигать. С Пиками я работал последний раз лет 7 назад, так что могу искренне верить в любую чушь Про платный компилятор - да, Вы и тут правы, такую информацию я тоже находил. Естественно, не в официальных источниках Вот мой ознакомительно-лайтовый компилятор и не компилирует, таблетку хочет. ---------------------------------------------------------------------------------------------------------------------------------------- Надеюсь, я верно понял Вашу мысль. Если нет - пожалуйста, распишите как для идиота, пошагово, я точно не обижусь Спасибо
  4. Схема не запускается, потому что не хватает напряжения для открывания полевых транзисторов. Посмотрите даташит, там все картинки начинаются от 4 вольт. К сожалению, не могу подсказать подходящих транзисторов, но может быть есть смысл глянуть на биполярные? Раз Вам киловатты дуг и милиардов скорости не нужно И по диодам. Шотки, безусловно, можно поставить, только имейте в виду, что у них пробивное напряжение не очень высокое, по данным ЕМНИП где-то в районе 60 вольт. Хотя при таких соотношениях обмоток там навряд ли будет больше 20 вольт в прыжке
  5. Увы, не получилось так сделать: то ли без перекомпиляции система не подхватывает файл с диска (что вряд ли), то ли я в лыжах на асфальте обутый. В логах нет строчки, сообщающей о прошивке устройства, только стирание и верификация. Так что хороший метод, возможно, где-то еще пригодится, но не в данном конкретном случае. Я тут другое нашел: "If you are trying to compile the MicroChip bootloader, you'll need the full version of the C programmer (not the LITE or Student versions) or the compiled code won't fit into the bootspace (0x800 for MCHPUSB bootloader and 0x1000 for the HID bootloader)". А я уже столько бубнов порвал, что сам не знаю, что там сейчас стоит. Очень даже возможно, что вообще ознакомительная версия компилятора. Попробую в этом направлении порыться. Крик души: как же не хочется трогать эту шаткую конструкцию! Если оно работает - не лезь!
  6. Хм, вроде бы об одном говорим, а как-то не понимаю я Вас. Мои действия пошагово: 1. Установил дрова на железо, поставил софт, поженил отладчик и процессор - они друг друга видят, лампочки на отладчике мигают в такт моим размахиваниям мышкой. 2. В пакете MPLAB IDE 8.92 открыл проект USB HID bootloader, но скомпилировать его не получается - на этапе линкования вылазит ошибка, которую я не победил. Которую все-таки придется победить, ибо иного выхода у меня, похоже, нет. 2.1. Получить файл bootloader.hex честным путем я не смог, зато в инете нашел готовый. 3. Пятый день ищу в MPLAB IDE способ влить в процессор прошивку БЕЗ компиляции. Так же вполне устроит вариант найти ее в другой программе, которая умеет работать с ICD2. Кратко: мне нужно прошить готовым кексом без компиляции. Это возможно? Если да, то как? Спасибо Тут описан вариант с компиляцией исходников, но компиляция-то как раз и не проходит. Иначе я бы не приставал тут к умным дядькам П.С. Вот сообщение об ошибке, которое заставляет меня окончательно поседеть в столь юном возрасте: На этапе компиляции: C:\Projects\PIC18\Boot_2\usbdrv.c:104:Warning [2056] expression is always true И линкования: MPLINK 5.00, LINKER Device Database Version 1.17 Copyright (c) 1998-2013 Microchip Technology Inc. Error - section '_cinit_scn' can not fit the section. Section '_cinit_scn' length=0x0000009e Errors : 1
  7. Все так, но Вы немного неверно поняли мой вопрос. Есть готовый, утащенный из Сети файл прошивки. Есть готовый, рабочий и даже видящий процессор отладчик. Но я не владею секретом соединить эти две компоненты Я отчаянно надеюсь, что есть хитрый финт, с помощью которого можно превратить отладчик в программатор Пусть крайне непродуктивный и неудобный, но чтобы можно было однократно прошить готовое готовым, а дальше уже пользоваться этим самым бутлоадером.
  8. Здравствуйте, уважаемые. Собственно, вопрос уже озвучен выше. Волею судьбы заимел натуральный микрочиповский дебагер и горсточку микропроцессоров, тоже микрочиповских. А так же имею необходимость собрать одно небольшое приспособление, для которого как нельзя лучше подходит этот контроллер. Хотя бы уже тем, что он есть К сожалению, на этом "уже есть" и заканчивается. Для удобства хочу влить в микроконтроллер какой-нибудь USB bootloader и не париться, да вот как-то не получается. Сколько ни рылся, в MPLAB не нашел ни опции "сделать хорошо", ни "запрограммировать без компиляции проекта". А проект бутлоадера как раз и не собирается. Собирать же программер для разовой акции тоже как-то не хочется. Так что прошу подсказки, может быть кто-то знает решение. Спасибо.
  9. Раньше в школе не учили читать, писать и расставлять запятые, так что да, идите в ногу со временем и ничего не бойтесь
  10. Теме ап Заменил диод на HER108 - не греется. Правда, забыл глянуть, что там на стоке творится А вот почему при соединении земель становится "вообще все плохо" так и осталось загадкой. Знаю, выходнй ток там ничтожный, и делители в цепях ОУ его сжирают неплохо, но не настолько же там слаботочный выход: 1700+ вольт при емкости 0,5uF накачивает за пару секунд! Это при разъединенных землях, а при соединении оных - на выходе что-то там трепыхается вяло и все. Причем, провод ВН, заходящий на вход ОУ отпаян. Питальник показывает 17 Ватт (11,3Вх1,5А) в обоих случаях.
  11. Когда-то, лет 15 назад, занимался ремонтом компьютерных блоков питания. Но это было уже весьма давно, не совсем в тему да и вообще.... Пожалуй да, останусь при имеющейся схеме и постараюсь ее довести до более-менее вменяемого состояния. Возможно, потом еще апну эту тему, когда будет о чем говорить Спасибо за внимание
  12. На счет частотных характеристик диода не будем спорить, если подходит - то оно и к лучшему Просто в описании так написанно категорично, а я такой доверчивыыыый.... Конечно, формально это не даташит и все такое, ну и оставим диод в покое Намного больше меня волнует, как организовать обратную связь. При беглом осмотрении своих скудных запасов нашел ШИМ контроллер UC3842 и оптореле PVT412L, вот думаю, получится ли на них что сварганить. К сожалению, те схемы, что успел найти - они на выходе имеют фиксированные напряжения. Ставить переменный резистор в цепь ВН как-то ссыкотно (ага, я не только доверчивый, но и... излишне осторожный ) . В общем, ковыряюсь помаленьку.
  13. Спасибо за отклики По поводу 1N4004. Спасибо, Вы совершенно правы, опять я меняю местами лево и право, плюс и минус, добро и зло - продолжать можно долго Паял его полоской в сторону шины питания, а анодом, соответственно, к транзистору. Так что, вроде бы, не перевернул. Но! Посмотрел его даташит и ужаснулся: оказывется, 4004 заточен под 60 герц! А я его пытаюсь накормить десятками килогерц. Да через него энергия тупо как сквозь емкость прокачивается, конечно же он отпаяется Пороюсь в своей тайной комнате, авось найду что подобающее. На счет применения специализированных мелкосхем полностью с Вами согласен. Правда, это ставит меня в несколько неловкое положение: с одной стороны объективная необходимость в их применении, с другой - не менее удручающая необходимость их покупки. Точнее, не сама покупка угнетает, а почтовые поборы: за каждую пересылку по 300 рубликов отваливать приходится. Так что я еще буду долго думать Хотя что тут думать, все равно надо с макетки на печатку переезжать, а то там за проводами уже соплей не видно - как раз есть повод сделать правильно. Кстати, если уж использовать что-то типа TL494, то наверное лучше посмотреть на TL594: те же электроны, вид сбоку, но зато уже заточена под полевые тарнзисторы (если мне память не врет). Еще есть мысли поставить несколько ключей в параллель, для умощнения. Все-таки автомобильный аккумулятор штука злая, сожрет девайс и не поперхнется Но это потом уже, если понадобится.
  14. Да, с STM32 в действительности все не так, как на самом деле. Недавно возникла нужда прошить проц, я долго чесал дыню и думал, чем бы его того. А потом нагуглил такую утилитку, как STM32CubeProgrammer. Скачал с сайта STM и все прошло вполне успешно - бинарник залился, заработал и даже почти удовлетворил мои хотелки Попробуйте, вдруг и Вам поможет. А что касается Ваших слов, что никаких видимых признаков работы проекта, посмотрите, у Вас ининциализация процессора корректно проходит? STM32 - они в этом плане ох как нервно делаются, легче с фьюзами в AVR разобраться, чем с тактированием STM
  15. Еще порция информации. Разделил высоковольтную и низковольтную цепи совсем, т.е. разорвал связь по земле. Нашел еще один лабораторный блок питания, выставил 12 вольт, убрал резистор в цепи стока. Нагрузил выход емкостью 100uF 400V- заряжается до максимума за считанные секунды, один раз даже успел обосраться, увидев на мультиметре 450 вольт - имеется опыт ловли взрывающихся электролитов Ток при этом питальник отдает около 3А. При таком токе греться ничего не греется (кроме резистора в стоковой цепи, который я убрал), но кормить-то предполагается от условно мобильного источника, а сетевой БП на него ну совсем не похож А еще у меня опять отпаялся снабберный диод. Сто раз уже проверил - все верно собрано, а диод все равно как буд-то перевернут. Первый диод сгорел в пепел, поставил 1N4004, два последовательно - все равно отпаиваются. Анодный вывод (с полоской) к +12В, катод - к стоку транзистора. Я уже ХЗ что с этим девайсом делать. Соединю земли - не качает напряжение, 100 вольт надувает целую минуту; Разделю ВВ и НВ - мгновенно конденсатор накачивается сверх всякой меры. Я что, открыл новый вид электроядерной энергии?
  16. Здравствуйте, уважаемые. Прошу помощи, как всегда Суть в следующем. Собрал преобразователь для электротермической пушки, плазмогана, бдыщ-машинки - названий много, мне нравится первое Смысл этого изобретения - накачать конденсатор и бабахнуть в нагрузку. Для дела, конечно же, а не просто так Все бы хорошо, да вот только настроить этот преобразователь я, оказывается, не умею. Поэтому я тут. Преобразователь построен по стандартной схеме на таймере 555, драйвер (на комплементарной паре транзисторов), MOSFET - все канонично. Трансформатор намотан на броневом сердечнике НМ2000, 20 витков в первичной обмотке и примерно 450 во вторичной. Зазор примерно 0,3мм. Габариты сердечника таковы, что можно киловатт прокачать - что нашел, то и вкорячил. Сейчас трансформатор подключен через сопротивление 2 Ом, ибо транзисторы тают на глазах Высоковольтная часть - три последовательно запаяных диода HER407 и конденсатор примерно 0,1uF. Питание всей конструкции осуществляется от лабораторного источника 12 вольт 1 Ампер. Штатным питанием хочется сделать автомобильный аккумулятор, но его я пока подключал всего 1 раз и узнал, что нужен источник вечных транзисторов Собственно, отсюда и сопротивление в цепи трансформатора временно образовалось. Схема классическая на NE555, никакой отсебятины. Если вдруг прямые ссылки тут не приветствуются, то под спойлером ссылка на первоисточник: Вдобавок к вышеприведенной схеме добавил диод между входным питанием и питанием таймера в надежде, что будет меньше просаживаться питание на таймере. И конденсатор по питанию 100uF. 100uF мало, добавлю еще. Собран только преобразователь, контроля за напряжением на входе и выходе нет. А теперь непонятки, которые надеюсь с вашей помощью разрешить. 1. Контроль за выходным напряжением вести все-таки необходимо, поэтому собрал на LM358 компаратор. Схему этого узла показать не могу, она секретная Но если очень надо будет, то нарисую, со мной легко договориться Для работы этого узла нужно соединить земли ВН и НВ, но если это сделать - то преобразователь начинает жрать слишком много тока, входное напряжение падает до 8-9В и все начинает греться. Если не соединять - то вроде бы все работает, но в нагрузку накачивает напряжение без ограничений, а это не комильфо. 2. Сильно греется резистор в цепи трансформатора (до выделения волшебного дыма), а так же транзистор (транзистор не очень сильно, рука терпит). 3. В идеале хотел бы довольно широко регулировать величину выходного напряжения - сколько удастся выжать из этой конструкции и вытерпят выходные элементы. Из приборов имею пару мультиметров и небольшой осциллограф, которым так и не научился пользоваться Если сможете помочь - буду очень признателен Спасибо за внимание.
  17. Это потрясающе А какова (примерно) масса деревянных коромысел? Сколько граммов тащит этот агрегат? И еще, если позволите: что за Дедовская пыхтелка? Можно ли где-то ознакомиться с этим интересным девайсом? Спасибо.
  18. После многих бессонных дней оно таки заработало. Температура с Вашей, Yuriy.pv, подсказкой давно уже пофикшена, а вот двигатель лентопротяжки - буквально пол часа как заработал нормально. Условно нормально, т.к. 30 минут надругательств - это не тест. Что сделано: 1. Перетащил на библиотеку GyverStepper. В целом это без разницы, просто я пошел не самым логичным путем 2. Забросил проект на пару дней. 3. Перетащил с места на место строчки кода в процедуре loop (). 4. Причесал код, убрал закомментированные куски. 5. Выбросил все старые файлы из папки с проектом и перекомпилил заново в стопицотый раз. Что именно дало толчок к работе - не знаю. Но случилось чудо и картинка поплыла, как Солнце среди звезд, как жирный конь в компоте, как главком на красной площади, как деньги из бюджета - продолжать можно долго Еще раз спасибо за внимание, за помощь и поддержку. Вот текущий код: /* * Станок по протяжке ленты из ПЭТ бутылок в пруток. * Версия 0.1 от 03.08.2021 */ #include "Wire.h" #include "LiquidCrystal_I2C.h" #include "GyverButton.h" #include <GyverStepper.h> #define PID_INTEGER #include "GyverPID.h" #include <EEPROM.h> //----------------------------------------------------------------------------------------------------------------------- #define ver "0.1" #define btn_dec_pin 11 #define btn_ok_pin 10 #define btn_inc_pin 9 #define btn_inc_step 20 #define btn_dec_step 20 // PWM пины: 3, 5, 6, 9, 10, 11 #define heater_pin 5 // Контакт D5 #define tsens_pin 21 // Контакт A7 #define fan_pin 6 // Контакт D6 #define thermistor_r 100000 // Номинальное сопротивление термистора при 25 градусах 100К #define t_nominal 25 // Температура, при которой меряется номинальное сопротивление термистора #define thermo_b 3950 // Какой-то бетта коэффициент термистора (обычно 3000-4000). ХЗ что это #define thermo_r 11880 // Постоянный резистор второго плеча термистора, 11.88К #define num_pas 10 // Количество измерений температуры для усреднения #define temp_addr 0 // Адрес в EEPROM для хранения температуры нагревателя #define speed_addr 2 // Адрес в EEPROM для хранения скорости протяжки // ПИД регулятор #define dt 500 // Частота регулировки ПИД 0.5 секунды #define PID_kp 5.2 #define PID_ki 0.5 #define PID_kd 0.5 // Мотор протяжки #define motor_max_speed 1000 // Максимальное число шагов в секунду #define motor_steps 200 // Количество шагов мотора на оборот (для Nema17 200) #define motor_acceleration 300 #define motor_step_pin 15 // Контакт А1 #define motor_dir_pin 14 // Контакт А0 #define motor_en_pin 16 // Контакт А2 //======================================================================================================================= LiquidCrystal_I2C lcd(0x27, 16, 2); GButton btn_dec(btn_dec_pin); GButton btn_inc(btn_inc_pin); GButton btn_ok(btn_ok_pin); GyverPID regulator(0.1, 0.05, 0.01, 100); // коэф. П, коэф. И, коэф. Д, период дискретизации dt (мс) GStepper<STEPPER2WIRE> motor(motor_steps, motor_step_pin, motor_dir_pin, motor_en_pin); // драйвер step-dir + пин enable //======================================================================================================================= String menu_item [] = {"Temp ","Speed ","Motor ", "Heat ", "Fan ", "Save ", "Load "}; int menu_pos = 0; int heater_current_temp = 0; int heater_new_temp = 0; int motor_speed = 0; float error, error0, pid, pwr, integ; uint16_t Kp, Ki, Kd; bool heater_logo = false; static bool motor_enable = false; //----------------------------------------------------------------------------------------------------------------------- void Logo (void); void Btn_dec (int); void Btn_inc (int); void Btn_OK (); void Show (); void Save (); void Load (); int GetTemp (); void PID_heater (); void Motor_step (); void Ticks (); //======================================================================================================================= void Logo (void) { String logo_str = "Extruder ver.0.1"; int pos = 0; for (pos==0; pos<logo_str.length (); pos++) { lcd.setCursor (pos,0); lcd.print (logo_str[pos]); delay (100); } delay (1000); lcd.clear (); } //----------------------------------------------------------------------------------------------------------------------- void Btn_dec (int clicks){ // 0 1 2 3 4 5 6 //"Temp ","Speed ","Motor ", "Heat ", "Fan ", "Save ", "Load " // Одиночные нажатия if (clicks==1) { switch (menu_pos) { case 0: if (heater_new_temp>0) {heater_new_temp--;}; break; case 1: {motor_speed=motor_speed-5; motor.setSpeed(motor_speed);}; break; case 2: motor_enable = false; break; case 3: break; case 4: break; case 5: Save (); break; case 6: Load (); break; } }; // Долгое удержание if (clicks==2) { switch (menu_pos) { case 0: if (heater_new_temp>btn_dec_step) {heater_new_temp=heater_new_temp-btn_dec_step;}; break; case 1: {motor_speed=motor_speed-20; motor.setSpeed(motor_speed);}; break; } }; } //----------------------------------------------------------------------------------------------------------------------- void Btn_inc (int clicks){ // 0 1 2 3 4 5 6 //"Temp ","Speed ","Motor ", "Heat ", "Fan ", "Save ", "Load " // Одиночные нажатия if (clicks==1) { switch (menu_pos) { case 0: heater_new_temp++; break; case 1: if (motor_speed<motor_max_speed) {motor_speed=motor_speed+5; motor.setSpeed(motor_speed);}; break; case 2: motor_enable = true; break; case 3: break; case 4: break; case 5: Save (); break; case 6: Load (); break; } }; // Долгое удержание if (clicks==2) { switch (menu_pos) { case 0: heater_new_temp=heater_new_temp+btn_inc_step; break; case 1: {motor_speed=motor_speed+20; motor.setSpeed(motor_speed);}; break; }; }; } //----------------------------------------------------------------------------------------------------------------------- void Btn_OK (){ // 0 1 2 3 4 5 6 //"Temp ","Speed ","Motor ", "Heat ", "Fan ", "Save ", "Load " switch (menu_pos) { case 0: regulator.setpoint = heater_new_temp; break; case 1: break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: break; } menu_pos++; if (menu_pos==7) {menu_pos=0;}; } //----------------------------------------------------------------------------------------------------------------------- void Show (void) { lcd.setCursor (0,0); lcd.print (menu_item[menu_pos]); lcd.setCursor (6,0); lcd.print ("T="); lcd.print (heater_new_temp); lcd.print("/"); lcd.print(heater_current_temp); lcd.print(" "); lcd.setCursor (6,1); lcd.print ("S="); lcd.print (motor_speed); lcd.print(" "); lcd.setCursor (14,1); if (heater_logo==true) {lcd.print('h');} else {lcd.print(' ');}; lcd.setCursor (13,1); if (motor_enable==true) {lcd.print('m');} else {lcd.print(' ');}; } //----------------------------------------------------------------------------------------------------------------------- void Save (void) { eeprom_update_word (temp_addr, heater_new_temp); eeprom_update_word (speed_addr, motor_speed); menu_pos = 0; } //----------------------------------------------------------------------------------------------------------------------- void Load (void) { heater_new_temp = eeprom_read_word (temp_addr); motor_speed = eeprom_read_word (speed_addr); menu_pos = 0; //Проверка на -1 (после обновления прошивки из ЕЕПРОМ читается -1) if (motor_speed==-1) motor_speed = 0; if (heater_new_temp==-1) heater_new_temp = 0; } //----------------------------------------------------------------------------------------------------------------------- int GetTemp(void) { //Функция измерения температуры int16_t At = 0; for (uint8_t i = 0; i < 10; i++) At += analogRead(tsens_pin); //Усредняем At /= 10; //10 последовательных измерений float Rt = 1023.0 / At - 1; Rt = thermo_r / Rt; float T; T = Rt / thermistor_r; T = log (T); T /= thermo_b; T += 1 / (t_nominal + 273.15); T = 1 / T; T -= 273.15; int xx; xx = T; return xx; } //----------------------------------------------------------------------------------------------------------------------- void PID_heater (void) { regulator.input = heater_current_temp; // сообщаем регулятору текущую температуру pwr = regulator.getResultTimer(); analogWrite(heater_pin, pwr); // отправляем на мосфет if (pwr>0) {heater_logo = true;} else {heater_logo = false;}; } //----------------------------------------------------------------------------------------------------------------------- void Ticks (void) { btn_dec.tick(); btn_inc.tick(); btn_ok.tick(); if (motor_enable==true) {motor.tick();}; } //----------------------------------------------------------------------------------------------------------------------- void PreSave (void) { motor_speed = 500; heater_new_temp = 50; Save (); lcd.clear (); lcd.print ("EEPROM saved"); lcd.setCursor (0,1); lcd.print ("T=50, S=500"); delay (1000); } //----------------------------------------------------------------------------------------------------------------------- void PreLoad (void) { Load (); lcd.clear (); lcd.print ("EEPROM loaded"); lcd.setCursor (0,1); lcd.print ("T="); lcd.print (heater_new_temp); lcd.print ("S=500"); lcd.print (motor_speed); delay (1000); } //----------------------------------------------------------------------------------------------------------------------- //======================================================================================================================= void setup() { // Инициализация портов { pinMode (heater_pin, OUTPUT); pinMode (fan_pin, OUTPUT); digitalWrite (heater_pin, LOW); digitalWrite (fan_pin, LOW); } // Инициализация дисплея { lcd.init(); lcd.backlight(); lcd.clear (); } Load (); // Инициализация ПИД регулятора { regulator.setDirection(NORMAL); // направление регулирования (NORMAL/REVERSE). ПО УМОЛЧАНИЮ СТОИТ NORMAL regulator.setLimits(0, 255); // пределы (ставим для 8 битного ШИМ). ПО УМОЛЧАНИЮ СТОЯТ 0 И 255 regulator.setpoint = heater_new_temp; // сообщаем регулятору температуру, которую он должен поддерживать regulator.Kp = PID_kp; regulator.Ki +=PID_ki; regulator.Kd = PID_kd; } // Инициализация двигателя протяжки { motor.invertEn(false); motor.setRunMode(KEEP_SPEED); motor.setMaxSpeed(motor_max_speed); motor.setAcceleration(motor_acceleration); motor.setSpeed(motor_speed); } // Прочее { Logo (); // Загрузка сохраненных в ЕЕПРОМ значений, если это необходимо if (digitalRead (btn_dec_pin)==0&&digitalRead (btn_inc_pin)==0) {PreSave (); Logo();}; if (digitalRead (btn_ok_pin)==0&&digitalRead (btn_inc_pin)==0) {PreLoad (); Logo();}; } } //======================================================================================================================= void loop() { heater_current_temp = GetTemp (); PID_heater (); Ticks (); Show (); if (btn_dec.isClick()) {Btn_dec(1);}; if (btn_inc.isClick()) {Btn_inc(1);}; if (btn_ok.isClick()) {Btn_OK();}; if (btn_dec.isHolded()) {Btn_dec(2);}; if (btn_inc.isHolded()) {Btn_inc(2);}; } Странно, предыдущий ответ пропал, а потом снова появился - это ваще законно? Простите, у нас тут локальная котоклизьма была, света больше суток не видели - даже пиво пили темное! Пишу иногда, по настроению. Точнее, пописываю Так, фанфики на все, что глаза видят Вы правы, станочек задумывался как вытягиватель ПЭТ-филамента для принтера, но пока делал - пришло много новых хотелок. Уж как там с филаментом пойдет я не знаю, все-таки вонюч он сверхмерно. Это я уже из экспериментов с предыдущей итерацией станка уяснил, а то в инете на сей счет мнения диаметрально разнятся. Еще хочу корзины научиться плести из этого прутка, сплести полноценный грузовой прицеп для велика, подвязки для помидоров в теплицу, розги для соседских детей, леску для триммера, гамак... Боюсь, моя печень не одобрит такой размах хотелок
  19. Юрий, Вы таки тоже правы Дунька - это как магия: она не зло и не добро, она просто есть. Вопрос в том, как ее применять Для меня платформа ардуино - это кучка железа, имеющий какое-то подобие устаканенного набора функций (зачастую несовместимого само с с собой), кучка программных поддержек (работающих только в демках), крайне убогую оболочку (порой легче в блокноте работать) и т.д. и т.п. Хаять можно долго и со вкусом - это существенно повышает моё ЧСВ Однако есть же и плюсы: оно уже есть, можно спросить совета у уже нахававшихся, можно скачай и прошей без особых трепыханий и будет тебе метеостанция... Все это сливается в понятие "порог вхождения". Впрочем. Вы и сами все это прекрасно понимаете, не будем тут холиваром развлекаться Я не хочу разбираться в начинке библиотек, не хочу оптимизировать и выцарапывать ресурсы (знаете сказку об одном байте?) и все такое. Буду по существу лучше Почему на дуньке делаю? Потому, что я не настолько крут, чтобы написать поддержку экрана, подключенного по I2C Драйвер мотора уж подцепил бы, там действительно все неприлично просто. Да и с кнопками тоже доводилось дело иметь. На резонный вопрос "ну и?" превентивно отвечу: "ну, эта..." Так-то, если уж касаться этой темы о предпочтениях в программировании, то мне больше всех нравится FlowCode - визуальная среда, строишь алгоритм программы из школьных блок-схем, а на выходе кекс, асм и си. Все бы хорошо, да вот закрытая она, эта ФК, поддержки нормального железа нет, только свои модули продвигают, а под самодельщину поддержку писать - опять же, я не хочу этим заниматься. Впрочем, я увлекся, узвините. Функция Ticks() вызывается в бесконечном цикле loop() - это аналог идеологически истинного while (1) do {}; В результате программа крутится внутри этого лупа, выскакивая ненадолго на всякие там прерывания (если они есть) и прочие функции (в том числе и наш Ticks()). Все как всегда, те же фаберже, вид сбоку. Была мысль злобно плюнуть в код и настрочить, как Вы говорите, самому это управление драйвером. И даже не вижу сложностей особоых, по крайней мере сейчас не вижу . Возможно, этим все и закончится
  20. Спасибо, что проявляете интерес к моему скромному проекту С подозрениями все хорошо - их есть у меня Но увы, кроме подозрений еще нужны веские доказательства, псакинг тут не прокатит. Вот думаю, может еще параною подключить, для надежности? При RAM=61% и FLASH=93% без паранои никак Сегодня еще не занимался проектом, не успел. Постараюсь пару часиков поковыряться. Хочу другие библиотеки еще попробовать - порой такой финт прокатывает на ардуине. Хоть и не всегда, конечно. Самое удивительное, что копипаст кода в пустой скетч двигателем крутит (и кнопками кнопит), а в нужном проекте - нет. Есть мысль переписать все нафиг с чистого листа, но сомнения гложут. А что, прошу прощения, не так с функцией Ticks()? void Ticks (void) { btn_dec.tick(); btn_inc.tick(); btn_ok.tick(); if (motor_enable==true) {motor.runSpeed();}; } Для опроса кнопок там вызываются, собственно, опросы кнопок и затем, если мотору можно крутиться (значение параметра задается вручную) - делаем один шажок. Это если я правильно понял описание функций библиотеки. Вроде бы никакого криминала в ней нет, да и на изменение скорости она не влияет. Честно говоря, не вижу, на что в ней можно грозно посмотреть. Эта переменная (motor_enable) так же используется в функции Show() - выводит символ m, если мотору можно крутиьтся. Так вот там она вполне корректно отрабатывается, так что и переменная тоже меняется. Я так думаю. Сейчас, после переезда на гайверовскую библиотеку (нравятся они мне, как-то удобненько работают, а про внутренний мир этих библиотек я не в курсе ) управления мотором функция приобрела немного иной вид: void Ticks (void) { btn_dec.tick(); btn_inc.tick(); btn_ok.tick(); if (motor_enable==true) {motor.tick();}; } В общем, пойду ковыряться, авось это поможет Потом расскажу, что получится.
  21. Действительно, с температурой теперь все в норме, нагрев управляется вовремя, произвольно и как и задумано Теперь с двигателем воюю. Проверил сто раз весь код, переполз на библиотеку GyverStepper, вытаскивал в отдельный скетч относящиеся к делу куски - там работает. И запускается, и скорость меняется, и тормозится... А в вышеприведенном скетче - авотхрен, фигвам! Точнее, вообще не запускается, хотя кусочки код копипастю из работающего окна в неработающее. Есть подозрение, что ресурсов мало осталось ( 94%/62% RAM/FLASH), но как-то так себе предположение. В общем, ищу пока решение
  22. Эээ... Ну да, действительно Вот ведь, Семен Семеныч Наверное, с двигателем тоже самое происходит Спасибо, слона-то я и не заметил
  23. Здравствуйте, уважаемые. Прошу помощи в написании прошивки станочка для протяжки ПЭТ бутылок в пруток. Точнее, не всей прошивки,а кусочка кода. Написал я кое-как программу, уж как сумел, и она даже почти работает. Вот это "почти" и не дает закрыть проект Предполагаемый алгоритм работы таков: 1. Система запускается, все хорошо. 2. Из EEPROM читаются 2 переменных, температура нагревателя и скорость мотора. 3. Нагреватель (при необходимости) начинает греться. Температура нагрева контролируется ч помощью ПИД регулятора (засада №1). 4. Когда температура устаканится, либо, по мнению пользователя, уже и так сойдет - ручками запускаем мотор, протягивающий ленту через нагреватель. Скорость вращения мотора задается средствами библиотеки AccelStepper (засада №2). Двигатель протяжки можно остановить в любой момент через менюшку. 5. В любой момент можно поменять скорость движка и температуру нагревателя. Остальные задумки уже не влазят в процессор , да и не особо нужны. Но пункт 5 немножко как раз и не работает. Система при старте считывает ранее заданные значения температуры и скорости, применяет их, а на дальнейшие мои попытки изменить их гордо корчит рожу. И, соотетственно, не меняет. Вот и хочу попросить совета, что я делаю не так. Самое противное, что примеры к библиотекам работают исправно, а в составе моего проекта - авотхрен. Проект строится на Atmega168P (Nano v2), мотор Nema17 с драйвером A4988. Из управления - 3 дискретных кнопки и экранчик 2*16 строчек. Прошу помощи Вот скетч (надеюсь, получится правильно вставить ) , схему подключений тоже нарисую, если нужно будет. Хотя там все задействованные лапы в дефайнах видны . #include "Wire.h" #include "LiquidCrystal_I2C.h" #include "GyverButton.h" #include <GyverTimers.h> #include <EEPROM.h> #define PID_INTEGER #include "GyverPID.h" //#include <GyverStepper.h> #include <AccelStepper.h> //----------------------------------------------------------------------------------------------------------------------- #define btn_dec_pin 11 #define btn_ok_pin 10 #define btn_inc_pin 9 #define btn_inc_step 20 #define btn_dec_step 20 // PWM пины: 3, 5, 6, 9, 10, 11 #define heater_pin 5 // Контакт D5 #define tsens_pin 21 // Контакт A7 #define fan_pin 6 // Контакт D6 #define thermistor_r 100000 // Номинальное сопротивление термистора при 25 градусах 100К #define t_nominal 25 // Температура, при которой меряется номинальное сопротивление термистора #define thermo_b 3950 // Какой-то бетта коэффициент термистора (обычно 3000-4000). ХЗ что это #define thermo_r 11880 // Постоянный резистор второго плеча термистора, 11.88К #define num_pas 10 // Количество измерений температуры для усреднения #define temp_addr 0 // Адрес в EEPROM для хранения температуры нагревателя #define speed_addr 2 // Адрес в EEPROM для хранения скорости протяжки // ПИД регулятор #define dt 500 // Частота регулировки ПИД 0.5 секунды #define PID_kp 5.2 #define PID_ki 0.5 #define PID_kd 0.5 // Мотор протяжки #define motor_steps 200 // Количество шагов мотора на оборот (для Nema17 200) #define motor_step_pin 15 // Контакт А1 #define motor_dir_pin 14 // Контакт А0 #define motor_en_pin 16 // Контакт А2 #define motor_max_speed 1000 // Максимальное число шагов в секунду //======================================================================================================================= LiquidCrystal_I2C lcd(0x27, 16, 2); GButton btn_dec(btn_dec_pin); GButton btn_inc(btn_inc_pin); GButton btn_ok(btn_ok_pin); //GyverPID regulator(1, 0, 0, 500); // коэф. П, коэф. И, коэф. Д, период дискретизации dt (мс) GyverPID regulator(0.1, 0.05, 0.01, 100); // коэф. П, коэф. И, коэф. Д, период дискретизации dt (мс) //GyverPID regulator(0.1, 0.05, 0.01); // коэф. П, коэф. И, коэф. Д // Определение тип интерфейса двигателя #define motorInterfaceType 1 AccelStepper motor(motorInterfaceType, motor_step_pin, motor_dir_pin); //======================================================================================================================= String menu_item [] = {"Temp ","Speed ","Motor ", "Heat ", "Fan ", "Save ", "Load "}; int menu_pos = 0; int heater_current_temp = 0; int heater_new_temp = 0; int motor_speed = 0; float error, error0, pid, pwr, integ; uint16_t Kp, Ki, Kd; bool heater_logo = false; static bool motor_enable = false; //----------------------------------------------------------------------------------------------------------------------- void Logo (void); void Btn_dec (int); void Btn_inc (int); void Btn_OK (); void Show (); void Save (); void Load (); int GetTemp (); void PID_heater (); void Motor_step (); void Ticks (); //======================================================================================================================= //----------------------------------------------------------------------------------------------------------------------- // Прерывание А таймера 1 ISR(TIMER1_A) { // прерывание таймера btn_dec.tick(); btn_inc.tick(); btn_ok.tick(); } //----------------------------------------------------------------------------------------------------------------------- void Logo (void) { String logo_str = "Extruder ver.0.0"; int pos = 0; for (pos==0; pos<logo_str.length (); pos++) { lcd.setCursor (pos,0); lcd.print (logo_str[pos]); delay (100); } delay (1000); lcd.clear (); } //----------------------------------------------------------------------------------------------------------------------- void Btn_dec (int clicks) { // 0 1 2 3 4 5 6 //"Temp ","Speed ","Motor ", "Heat ", "Fan ", "Save ", "Load " // Одиночные нажатия if (clicks==1) { switch (menu_pos) { case 0: if (heater_new_temp>0) {heater_new_temp--;}; break; case 1: {motor_speed=motor_speed-1;}; break; case 2: motor_enable = false; digitalWrite (motor_en_pin, HIGH); break; case 3: break; case 4: break; case 5: Save (); break; case 6: Load (); break; } }; // Долгое удержание if (clicks==2) { switch (menu_pos) { case 0: if (heater_new_temp>btn_dec_step) {heater_new_temp=heater_new_temp-btn_dec_step;}; break; case 1: {motor_speed=motor_speed-btn_dec_step;}; break; } }; } //----------------------------------------------------------------------------------------------------------------------- void Btn_inc (int clicks) { // 0 1 2 3 4 5 6 //"Temp ","Speed ","Motor ", "Heat ", "Fan ", "Save ", "Load " // Одиночные нажатия if (clicks==1) { switch (menu_pos) { case 0: heater_new_temp++; break; case 1: if (motor_speed<motor_max_speed) {motor_speed=motor_speed+1;}; break; case 2: motor_enable = true; digitalWrite (motor_en_pin, LOW); break; case 3: break; case 4: break; case 5: Save (); break; case 6: Load (); break; } }; // Долгое удержание if (clicks==2) { switch (menu_pos) { case 0: heater_new_temp=heater_new_temp+btn_inc_step; break; case 1: if (motor_speed<motor_max_speed-btn_inc_step) {motor_speed=motor_speed+btn_inc_step;}; break; }; }; } //----------------------------------------------------------------------------------------------------------------------- void Btn_OK () { // 0 1 2 3 4 5 6 //"Temp ","Speed ","Motor ", "Heat ", "Fan ", "Save ", "Load " switch (menu_pos) { case 0: break; case 1: motor.stop (); delay (20); motor.setSpeed(motor_speed); break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: break; } menu_pos++; if (menu_pos==7) {menu_pos=0;}; } //----------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------- void Show (void) { lcd.setCursor (0,0); lcd.print (menu_item[menu_pos]); lcd.setCursor (6,0); lcd.print ("T="); lcd.print (heater_new_temp); lcd.print("/"); lcd.print(heater_current_temp); lcd.print(" "); lcd.setCursor (6,1); lcd.print ("S="); lcd.print (motor_speed); lcd.print(" "); lcd.setCursor (14,1); if (heater_logo==true) {lcd.print('h');} else {lcd.print(' ');}; lcd.setCursor (13,1); if (motor_enable==true) {lcd.print('m');} else {lcd.print(' ');}; //lcd.setCursor (0,1); lcd.print(regulator.getResultTimer()); lcd.print(" "); } //----------------------------------------------------------------------------------------------------------------------- void Save (void) { eeprom_update_word (temp_addr, heater_new_temp); eeprom_update_word (speed_addr, motor_speed); menu_pos = 0; } //----------------------------------------------------------------------------------------------------------------------- void Load (void) { heater_new_temp = eeprom_read_word (temp_addr); motor_speed = eeprom_read_word (speed_addr); menu_pos = 0; } //----------------------------------------------------------------------------------------------------------------------- int GetTemp(void) //Функция измерения температуры { int16_t At = 0; for (uint8_t i = 0; i < 10; i++) At += analogRead(tsens_pin); //Усредняем At /= 10; //10 последовательных измерений float Rt = 1023.0 / At - 1; Rt = thermo_r / Rt; float T; T = Rt / thermistor_r; T = log (T); T /= thermo_b; T += 1 / (t_nominal + 273.15); T = 1 / T; T -= 273.15; int xx; xx = T; return xx; } //----------------------------------------------------------------------------------------------------------------------- void PID_heater (void) { //heater_current_temp = GetTemp (); regulator.input = heater_current_temp; // сообщаем регулятору текущую температуру pwr = regulator.getResultTimer(); analogWrite(heater_pin, pwr); // отправляем на мосфет if (pwr>0) {heater_logo = true;} else {heater_logo = false;}; } //----------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------- void Ticks (void) { btn_dec.tick(); btn_inc.tick(); btn_ok.tick(); if (motor_enable==true) {motor.runSpeed();}; } //----------------------------------------------------------------------------------------------------------------------- void PreSave (void) { motor_speed = 500; heater_new_temp = 50; Save (); lcd.clear (); lcd.print ("EEPROM saved"); lcd.setCursor (0,1); lcd.print ("T=50, S=500"); delay (1000); } //----------------------------------------------------------------------------------------------------------------------- void PreLoad (void) { Load (); lcd.clear (); lcd.print ("EEPROM loaded"); lcd.setCursor (0,1); lcd.print ("T="); lcd.print (heater_new_temp); lcd.print ("S=500"); lcd.print (motor_speed); delay (1000); } //----------------------------------------------------------------------------------------------------------------------- //======================================================================================================================= void setup() { // Инициализация портов { pinMode (motor_en_pin, OUTPUT); pinMode (motor_dir_pin, OUTPUT); pinMode (motor_step_pin, OUTPUT); pinMode (heater_pin, OUTPUT); pinMode (fan_pin, OUTPUT); digitalWrite (motor_en_pin, HIGH); digitalWrite (motor_dir_pin, HIGH); digitalWrite (motor_step_pin, HIGH); digitalWrite (heater_pin, LOW); digitalWrite (fan_pin, LOW); } // Инициализация дисплея { lcd.init(); lcd.backlight(); lcd.clear (); } Load (); // Инициализация таймера { //Timer1.setFrequency(1000); // 1KHz //Timer1.enableISR(); // Запускаем прерывание (по умолч. канал А) } // Инициализация ПИД регулятора { regulator.setDirection(NORMAL); // направление регулирования (NORMAL/REVERSE). ПО УМОЛЧАНИЮ СТОИТ NORMAL regulator.setLimits(0, 255); // пределы (ставим для 8 битного ШИМ). ПО УМОЛЧАНИЮ СТОЯТ 0 И 255 regulator.setpoint = heater_new_temp; // сообщаем регулятору температуру, которую он должен поддерживать // в процессе работы можно менять коэффициенты //regulator.Kp = 5.2; //regulator.Ki += 0.5; //regulator.Kd = 0; regulator.Kp = PID_kp; regulator.Ki +=PID_ki; regulator.Kd = PID_kd; } // Инициализация двигателя протяжки { // Устанавливаем максимальную скорость, коэффициент ускорения, начальную скорость motor.setMaxSpeed(motor_max_speed); motor_speed = -1000; motor.setSpeed(motor_speed); } // Прочее { Logo (); // Загрузка сохраненных в ЕЕПРОМ значений, если это необходимо if (digitalRead (btn_dec_pin)==0&&digitalRead (btn_inc_pin)==0) {PreSave (); Logo();}; if (digitalRead (btn_ok_pin)==0&&digitalRead (btn_inc_pin)==0) {PreLoad (); Logo();}; } } //----------------------------------------------------------------------------------------------------------------------- //======================================================================================================================= void loop() { Ticks (); heater_current_temp = GetTemp (); if (btn_dec.isClick()) {Btn_dec(1);}; if (btn_inc.isClick()) {Btn_inc(1);}; if (btn_ok.isClick()) {Btn_OK();}; if (btn_dec.isHolded()) {Btn_dec(2);}; if (btn_inc.isHolded()) {Btn_inc(2);}; Show (); PID_heater (); }
  24. Думаете, ТС уже собрал чего-то там и даже попробовал сунуть это в розетку? Мой последний гаусс, кстати, тоже был состряпан по схема ТСа. И даже умудрился прострелить полиэтиленовый пакет
×
×
  • Создать...