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

alex1985

Участник
  • Постов

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

  • Посещение

Весь контент alex1985


  1. Александр, спасибо за информацию! Буду изучать.
  2. Нашел статью про запись в БД: https://it4it.club/topic/72-uchimsya-peresylat-dannye-s-mqtt-brokera-v-bazu-dannyh-mysql/ может кому пригодится.
  3. 1. Планируется сбор статистики с разграничением уровня доступа, скажем заказчик может просматривать всю статистику только по конкретному закупленному станку, рабочему доступна статистика только за смену. 2. Девайсы разные, но набор основных параметров совпадает > 50% 3. Планируется в основном собирать статистику, но возможно и изменение сервисных параметров, также по запросу, инициируемого сервером, производить обновление прошивки (размер ~100КБ). 4. Отложенные транзакции планируются. Но я вижу механизм схожий с обновлением прошивки, т.е. при появлении новой версии ПО на сервере в соответствующем поле БД выставляется бит наличия прошивки (или несколько байт) и устройство при включении опрашивает это поле. При наличии нужной записи происходит загрузки файла прошивки или выполнение каких-то сервисных команд. 5. Думаю, подлинность девайсов логично определять серверу. В БД предполагается наличие таблицы устройств с уникальными ID и заводскому номеру оборудования, после включения девайс посылает на сервер строку с ID и если ID совпадает с имеющимся в базе - то статистика с девайса заносится в базу, иначе - игнорируется. По поводу защищенного канала - не подскажу, т.к. не разбираюсь в этом. 6. В первом приближении хочу организовать что-то типа журнала событий, т.е. время включения устройства, время работы, ошибки и т.д. но в идеале хочется снимать данные с интервалом в 1 сек., кол-во регистров ~ 10, размерность 1-2 байта. Понимаю, что для опроса данных с такой частотой потребуется сотни мегабайт данных, поэтому пока этот вариант рассматриваю как запасной. Данные планируется хранить вечно. 7. Авторизация и аутентификация клиентов нужна. Доступ в первом приближении планируется сделать по http через сайт, где пользователь вводит логин/пароль и попадает на страницу статистики. А в идеале - и через приложение IOS/Andriod , которое будет доставать данные с сервера и отображать их в нужном виде (табличном или графическом). 8. Графики/таблицы конечно хотелось бы иметь, поэтому я смотрю в сторону промышленных решений, т.к. не хочется самому изобретать приложения для IOS/андроид и т.п. 9. По трафику пока не думал даже. Как вариант, можно считать и отправлять трафик прямо с девайсов и при его низком значении выставлять какое-то поле в БД, сигнализирующее пользователю о его расходе. Интересный вариант! Но меня интересует механизм обмена с БД. Идеальным вариантом было бы решение типа "аренда сервера с конструктором БД и mqtt-брокером", интуитивно-понятное, не требующее долгого погружения в программирование БД, в котором за пол-часа можно было бы накидать структуру БД и огранизовать обмен через mqtt. Не знаю, может чушь пишу конечно, но информации пока мало нахожу.. Изучаю в данный момент mqtt и IoTmanager.
  4. Спасибо! Дельное замечание в нынешней экономической ситуации. Интересует решение на базе IoT-платформы, не американской) Самому изобретать велосипед с "балансировщиками нагрузки" и системой безопасности или поднимать сервер на базе домашнего/рабочего ПК не хочется. Но я не категоричен и готов рассмотреть все варианты решения задачи.
  5. Кол-во устройств планируется до 5000. Поясните что такое брокер в этой цепочке и какой функционал он выполняет? Нашел информацию по платформам IoT, самая крупная - Amazon Web Services. Я в правильном направлении смотрю?
  6. Наверное вопрос не по адресу - с аппаратной частью проблем нет - сделать не сложно, больше интересует работа с базой данных. Как я предполагаю - нужно поднимать сервер и по TCP/IP общаться с базой. Есть у кого опыт подобных работ? Подскажите, куда копать? С университета помнится только sql и то смутно..
  7. Я для того на форум и обратился, чтобы узнать как)
  8. Добрый день, коллеги! Имеется около 2000 изделий на базе микроконтроллера stm32 (назовем их условно черный ящик) и есть задача контроля за этими изделиями через удаленный сервер (сбор статистики, возможность отправки версии прошивки). В каждое из них планируется разместить GPRS-модуль (например SIM300). При включении изделия оно высылает на сервер необходимую информацию, т.е. выступает в роли "мастера", опрашивает наличие файла прошивки и при необходимости производит обновление. Вопрос: как концептуально реализовать эту задачу? Если есть SCADA-системы с подобным функционалом? Есть ли готовые серверные площадки с модемами для решения подобных задач?
  9. Доброго всем времени суток! Делал проект на Cyclone III в Quartus 9.1, затем потребовалось перенести его на Cyclone IV EP4CE6E22I7, сейчас работаю в Quartus 15.0.0. pll добавлял из IP catalog, все настройки ставил по дефолту: один входной клок: 8МГц и два выходных: 200МГц и 32МГц. На вкладке "Operation mode" выбрал "Normal mode". И вроде все нормально, камни очень похожие, но при компиляции появляется варнинг такого содержания: RTL симуляция выглядит так: Сигнал, поступающий на вход (inclk0 8МГц) объявлен как Global Clock и определен на ногу 23. Тактирование идет с микроконтроллера. В констрейнах объявляю клоки следующим образом: create_clock -name clk -period 8MHz [get_ports {clk}] create_generated_clock -name clk_200MHz -source [get_ports {clk}] -multiply_by 25 [get_nets {pll_ena_inst1|pll1|altpll_component|auto_generated|wire_pll1_clk[0]}] create_generated_clock -name clk_adc -source [get_ports {clk}] -multiply_by 4 [get_nets {pll_ena_inst1|pll1|altpll_component|auto_generated|wire_pll1_clk[1]}] Прошу совета - насколько критичен этот варнинг? Заранее спасибо!
  10. Прошу прощения :laughing: Но за советы все равно спасибо!
  11. Иосиф Григорьевич, спасибо! Все ясно и понятно! Тему можно считать закрытой.
  12. Спасибо всем, кто принимал участие в обсуждении! Все получилось, остался один вопрос: при компиляции проекта выдается ограничение по частоте в 200Мгц: Где именно ограничивается минимальный период и можно ли это поправить?
  13. Спасибо за подробный и развернутый ответ! :biggrin: Компилятор ARM v5
  14. Спасибо! А можно уложить эти данные по определенному адресу? Или придется пробегать весь hex в поисках этих строк?
  15. Доброго времени суток! Камень: stm32f407. Нужно сохранить информацию о версии прошивки в самом файле прошивки (hex), желательно по указанному адресу, чтобы ее потом можно было извлечь. Возможно ли это? Информация о версии определяется в тексте программы (на данный момент просто дефайном). Заранее спасибо!
  16. _Anatoliy, спасибо большое! :beer: Посмотрю обязательно!
  17. Вобщем посмотрел Time-report простейшей цепи и сделал вывод: setup и hold отстают друг от друга на один такт. В моем случае - та же простейшая цепь с одним клоком, просто данные захватываются с задержкой в 6 тактов. Поставил hold-time на 1 меньше setup и варнинги пропали. Осталось легкое недопонимание относительно hold( set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|I_limits_reg[*]*} -hold -end 6 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|I_limits_reg[*]*} -setup -end 7
  18. Задам вопрос по другому. Есть 1 общий клок и цепочка D-триггеров: В момент прихода импульса на первый триггер (1) в регистры заносятся некоторые данные, например err_reg[]. Далее с ними проводятся манипуляции (сложение/умножение/сравнение) и к моменту поступления импульса на шестой триггер (6) берется результат (F_limits_reg[]). Периодичность поступления импульсов на цепочку триггеров намного больше 6. Как правильно описать данный констрейн с помощью set_multicycle_path? Делаю так: set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[*]*} -setup -end 6 На картинке снизу изображения временного отчета по setup(слева) и hold(справа). По setup все более-менее понятно: мы указываем когда защелкиваются данные, соответственно сами данные должны прибыть ДО Latch-фронта. А вот с hold не знаю что делать, смысл его для меня пока загадка. Из каких соображений определяется констрейн для hold?
  19. Спасибо за оперативные ответы! Извиняюсь, что пишу так поздно. Проблема была в невыставленном set_multicycle_path. Я почему то полагал, что TimeQuest чуть умнее и сам додумается, т.к. вычисления разнесены по цепочке D-триггеров, но как выяснилось - нужно все прописывать самому. Пришлось добавить целую портянку кода: set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM3} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM3} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM5} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM5} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[24]_OTERM217} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[24]_OTERM217} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]_OTERM235} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]_OTERM235} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM153_OTERM223_OTERM251} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM153_OTERM223_OTERM251} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM155_OTERM221_OTERM239_OTERM299} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM155_OTERM221_OTERM239_OTERM299} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]_OTERM281} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]_OTERM281} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]_OTERM287} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]_OTERM287} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]_OTERM291} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]_OTERM291} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[*]_OTERM295} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[*]_OTERM295} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|I_limits_reg[0]_OTERM13_OTERM215_OTERM233_OTERM275} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|I_limits_reg[0]_OTERM13_OTERM215_OTERM233_OTERM275} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM149_OTERM227_OTERM247_OTERM307} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM149_OTERM227_OTERM247_OTERM307} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM149_OTERM227_OTERM245_OTERM303} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_limits_reg[0]_OTERM7_OTERM149_OTERM227_OTERM245_OTERM303} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|F_reg[12]_OTERM325} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|F_reg[12]_OTERM325} -setup -end 4 set_multicycle_path -from {pid:pid1|err_reg[*]} -to {pid:pid1|I_limits_reg[0]_OTERM13_OTERM215_OTERM233_OTERM273} -setup -end 4 set_multicycle_path -from {pid:pid1|Ki_reg[*]} -to {pid:pid1|I_limits_reg[0]_OTERM13_OTERM215_OTERM233_OTERM273} -setup -end 4 Ситуация выправилась, но осталась куча слаков по Hold, вот один из них: Если я правильно понимаю, то Hold time (th) - это время, которое сигнал должен удерживаться после фронта clk приёмника. Как понимать эту диаграмму? Данные (Data Arrival) пришли раньше фронта Latch clock, что не так?
  20. Доброго дня всем! Есть модуль ПИ-регулятора, проект собирается на cyclone III, таймквест ругается, выдает слаки. Код: module pid ( input clk, input use_pid, //Если 1 - включается ПИД-регулятор, иначе выдаем pwm_cur = pwm_fixed input [24:0] pwm_fixed, //Фиксированное значение ШИМ (используется при use_pid=0) input start_pulse, //Импульс начала вычислений input [11:0] ADC_REF, //АЦП уставки, max: 4096 (12 bit) input [11:0] ADC_FAKT, //АЦП фактическое, max: 4096 (12 bit) input [15:0] Ki, //Интегральный коэффициент input [15:0] Kp, //Пропорциональный коэффициент input [24:0] pwm_min, //Минимальная граница ШИМ input [24:0] pwm_max, //Макчимальная граница ШИМ output reg [24:0] pwm_cur, //Выходное значение ШИМ output reg is_pwm_max, //Если 1 - то ШИМ максимальный output end_pulse //Импульс окончания вычислений ); reg signed [25:0] I_reg; reg signed [26:0] F_reg; reg signed [24:0] I_prev_reg; reg [24:0] pwm_fixed_reg; reg [1:0] F_limits_reg; reg [1:0] I_limits_reg; reg [11:0] adc_ref_reg; reg [11:0] adc_fakt_reg; reg signed [12:0] err_reg; reg [9:0] Kp_reg; reg [9:0] Ki_reg; initial begin I_prev_reg = 25'd1000; is_pwm_max = 0; pwm_cur = 0; end wire [1:0] w_F_limits; wire [1:0] w_I_limits; wire signed [25:0] w_I; wire signed [23:0] w_P; wire signed [26:0] w_F; wire signed [12:0] w_err; wire w_start_pulse2; wire w_start_pulse3; wire w_start_pulse4; wire w_start_pulse5; wire w_start_pulse6; //--------------------------------- // PID-calculating //--------------------------------- assign w_err =$signed({1'b0, ADC_REF}) - $signed({1'b0, ADC_FAKT}); //max: 13 bit assign w_I = use_pid? ($signed({1'b0, Ki_reg}) * err_reg + I_prev_reg) : ($signed({1'b0, pwm_fixed_reg})); //max: (10+1) * 13 + 25 = 26 bit assign w_P = $signed({1'b0, Kp_reg}) * err_reg; //max: (10+1) * 13 = 24 bit assign w_F = use_pid? (w_I + w_P) : ($signed({1'b0, pwm_fixed_reg})); //max: 26 + 24 = 27 bit; assign w_F_limits[0] = (w_F < $signed({1'b0, pwm_min}))? 1'b1 : 1'b0; assign w_F_limits[1] = (w_F > $signed({1'b0, pwm_max}))? 1'b1 : 1'b0; assign w_I_limits[0] = (w_I < $signed({1'b0, pwm_min}))? 1'b1 : 1'b0; assign w_I_limits[1] = (w_I > $signed({1'b0, pwm_max}))? 1'b1 : 1'b0; //============================================ delay delay1(.in(start_pulse), .clk(clk), .out(w_start_pulse2)); delay delay2(.in(w_start_pulse2), .clk(clk), .out(w_start_pulse3)); delay delay3(.in(w_start_pulse3), .clk(clk), .out(w_start_pulse4)); delay delay4(.in(w_start_pulse4), .clk(clk), .out(w_start_pulse5)); delay delay5(.in(w_start_pulse5), .clk(clk), .out(w_start_pulse6)); delay delay6(.in(w_start_pulse6), .clk(clk), .out(end_pulse)); //============================================ always @ (posedge clk) begin //======================================== // Начало вычислений, захватываем входные данные //======================================== if (start_pulse) begin Ki_reg = Ki[9:0]; Kp_reg = Kp[9:0]; err_reg <= w_err; pwm_fixed_reg <= pwm_fixed; end //======================================== // Даем 3 такта на вычисления, помещаем результат в регистры //======================================== else if (w_start_pulse4) begin I_reg <= w_I; F_reg <= w_F; I_limits_reg <= w_I_limits; F_limits_reg <= w_F_limits; end //======================================== // Выдаем результат, учитывая ограничения //======================================== else if (w_start_pulse5) begin //Ограничиваем выходное воздействие case (F_limits_reg) 2'b01: begin pwm_cur <= pwm_min; is_pwm_max <= 0; end 2'b10: begin pwm_cur <= pwm_max; is_pwm_max <= 1; end default: begin pwm_cur <= F_reg[24:0]; is_pwm_max <= 0; end endcase //Ограничиваем интегральную составляющую case (I_limits_reg) 2'b01: I_prev_reg <= pwm_min; 2'b10: I_prev_reg <= pwm_max; default: I_prev_reg <= I_reg[24:0]; endcase end end //============================================ endmodule Модуль delay: module delay #(parameter WIDTH = 1) ( input [WIDTH-1:0] in, input clk, output reg [WIDTH-1:0] out ); always @(posedge clk) out <= in; endmodule Идея такова: в момент прихода стартового импульса (start_pulse) происходит захват входных значений в регистры, цепочка из элементов delay производит задержку входного сигнала на 6 тактов для того, чтобы вся эта "колбаса" успела посчитаться к моменту выдачи импульса завершения (end_pulse). Таймквест выдает ошибки: Но регистр err_reg захватывается на 3 такта раньше чем производится вычисление F_reg, неужели 3 такта недостаточно для умножения? Файл констрейнов: derive_clock_uncertainty create_clock -name clk -period 36.1MHz [get_ports {clk}] create_generated_clock -name clk_216MHz -source [get_ports {clk}] -multiply_by 6 [get_nets {pll_ena_inst1|pll1|altpll_component|auto_generated|wire_pll1_clk[0]}] create_generated_clock -name clk_adc -source [get_ports {clk}] -divide_by 17 -multiply_by 15 [get_nets {pll_ena_inst1|pll1|altpll_component|auto_generated|wire_pll1_clk[1]}] set_false_path -from pll_ena_inst1|pll1|altpll_component|auto_generated|pll1|clk[1] -to adc_inst:adc_inst1|sync:sync_adc|sync[0] Какие констрейны прописать для устранения ошибок? Заранее спасибо!
  21. Спасибо за замечание! Но значение I_prev_reg, а значит и интегральная составляющая (w_I) у меня ограничивается максимальным и минимальным значениями (out_max и out_min), которые имеют разрядность 16 бит, так что криминала быть не должно. Не совсем понял фразу "щелкает каждый такт", но мысль уловил. Переписал немного добавив регистр (flag): reg flag; always @ (posedge clk) begin //-------------------------------- // Gets I and F values //-------------------------------- if (ena_pulse) begin I_reg <= w_I; F_reg <= w_F; I_limits_reg <= w_I_limits; F_limits_reg <= w_F_limits; flag <= 1'b1; end //-------------------------------- // Integral and out limitation //-------------------------------- else if (flag) begin case (F_limits_reg) 2'b01: out <= out_min; 2'b10: out <= out_max; default: out <= F_reg; endcase case (I_limits_reg) 2'b01: I_prev_reg <= out_min; 2'b10: I_prev_reg <= out_max; default: I_prev_reg <= I_reg; endcase flag <= 1'b0; end end В чем вообще разница между стэйт-машиной и регистром в данном случае? Что предпочтительнее использовать? Результат симуляции в обоих случаях одинаковый.
  22. Добрый день всем! Пишу ПИ-регулятор, требуется профессиональная критика) Камень - cyclone III, использовано 4 аппаратных умножителя. Код: module pid ( input clk, input ena, input signed [15:0] in_ustavka, input signed [15:0] in_fakt, input signed [15:0] Ki, input signed [15:0] Kp, input signed [15:0] out_min, input signed [15:0] out_max, output reg signed [31:0] out ); reg signed [31:0] I_reg; reg signed [31:0] F_reg; reg signed [31:0] I_prev_reg; reg [1:0] F_limits_reg; reg [1:0] I_limits_reg; reg [1:0] ena_reg; reg state; initial begin ena_reg = 2'b00; I_prev_reg = 31'd1000; out = 0; state = 1'b0; end wire ena_risingEdge; wire [1:0] w_F_limits; wire [1:0] w_I_limits; wire signed [31:0] w_F; wire signed [31:0] w_I; wire signed [31:0] w_P; wire signed [15:0] w_err; //--------------------------------- // Front detector //--------------------------------- always @(posedge clk) begin ena_reg <= {ena_reg[0], ena}; end assign ena_risingEdge = (ena_reg == 2'b01); //--------------------------------- // PID-calculating //--------------------------------- assign w_err = in_ustavka - in_fakt; assign w_I = Ki*w_err + I_prev_reg; assign w_P = Kp*w_err; assign w_F = w_I + w_P; assign w_F_limits[0] = (w_F < out_min)? 1'b1 : 1'b0; assign w_F_limits[1] = (w_F > out_max)? 1'b1 : 1'b0; assign w_I_limits[0] = (w_I < out_min)? 1'b1 : 1'b0; assign w_I_limits[1] = (w_I > out_max)? 1'b1 : 1'b0; always @ (posedge clk) begin case (state) //-------------------------------- // Gets I and F values //-------------------------------- 1'b0: if (ena_risingEdge) begin I_reg <= w_I; F_reg <= w_F; I_limits_reg <= w_I_limits; F_limits_reg <= w_F_limits; state <= 1'b1; end else state <= 1'b0; //-------------------------------- // Integral and out limitation //-------------------------------- 1'b1: begin case (F_limits_reg) 2'b01: out <= out_min; 2'b10: out <= out_max; default: out <= F_reg; endcase case (I_limits_reg) 2'b01: I_prev_reg <= out_min; 2'b10: I_prev_reg <= out_max; default: I_prev_reg <= I_reg; endcase state <= 1'b0; end //-------------------------------- default: state <= 1'b0; endcase //-------------------------------- end Моделсим:
  23. Спасибо, ознакомлюсь! В тестбенче, в зависимости от дефайна, включаются или не включаются в проект некоторые блоки, в частности pll, но файл констрейна один, поэтому при комментировании дефайна и компиляции проекта в квартусе выскакивают несколько десятков варнингов касательно настроек pll, которых при компиляции проекта фактически нет. В связи с этим вопрос: можно ли использовать дефайны в макросе? Или можно ли в зависимости от дефайна подключать соответствующий файл констрейна?
×
×
  • Создать...