avatar_sergey.67

Программирование кареточных моторов BBS01, BBS02.

Автор sergey.67, 11 Май 2014 в 00:03

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

ra6fnq

Евгений
http://fotki.yandex.ru/users/ra6fnq/
https://yadi.sk/d/8wi9CuXnvvFRh - инструкции на Bafangs

sergey.67

Вот нашел на просторах интернета может быть кому нибудь понадобится.
http://www.emax-ebikes.com.au/uploads/3/7/4/4/37442009/programming_bafang_bbs.pdf

dengor

В общем то документ не внушающий доверия в части описания параметров.
Расставить все точки нади

killer258

Цитата: acyd от 11 Июнь 2014 в 04:10

Еще в ПО бафанга жуткие ограничения, т.е токи и напряжения изменяются в малом диапазоне, обычно в сторону уменьшения от номинала, чтобы не убить.
ссылка на архив, в открывшемся окне выбрать "файл->скачать"
https://drive.google.com/file/d/0Bw59cTuRZg0PbzgyYXBFSG9jTVE/edit?usp=sharing

А вот эти жуткие ограничения - имеется в виду , что они находятся только в интерфейсе ввода  самого программатора или же проблема в том, что  сам контроллер мотора тупо отказывается принимать настройки за пределами малого диапазона?
Потому что если там первое, то я мог бы немножечко поправить программатор, ибо исходник проекта в скачанном архиве есть, а на Delphi я немного пишу. Проблема только в том, что люди, написавшие исходник этого ПО, предполагали  наличие установленного в Delphi компонента Comm1 , на который ссылается программа, а его у меня нет (по умолчаниию ни в Delphi6, ни в Delphi7 он изначально не установлен ). Это компонент, обеспечивающий связь по RS-232, поэтому без него никак не обойтись. Пробовал поискать в интернете, там довольно много предлагается подобных компонентов, таких как
Comm32 , Bcomport, Async32 , ComDrv32 и куча других платных и бесплатных, только нужного для данного проекта Comm1 почему-то нигде не попадается.  Может, случайно есть у кого? Дайте Comm1, если  есть  у кого-нибудь, не могу найти никак. Кто-нибудь ведь уже работал с исходником наверняка.
Бафанги: МК 250w (передн), МК 350w(задн), МИДы BBS-02 500W, и BBS-02 750W ,моноколесо KS14b, бензо: Д8Э, KD-F80

acyd

прога не дает установить и контроллер не принимает значения.
уже приводил пример: у меня контроллер с экраном c950, прошит 500w 18а, а программа дает прошить максимум 20, прошиваешь при газе выдает ошибку e21, но при этом реально работает только на 7.5а.
нужно разлочить только ток.

ra6fnq

Экран не причём, программа определяет идентификатор контроллера и соответственно ему, ограничивает ток. В мой 25 амперный шьётся и реально отдаётся 25, в Ольгин - 20 А, оба 48 вольтовые.
Евгений
http://fotki.yandex.ru/users/ra6fnq/
https://yadi.sk/d/8wi9CuXnvvFRh - инструкции на Bafangs

killer258

#78
Цитата: ra6fnq от 06 Янв. 2015 в 16:49
Экран не причём, программа определяет идентификатор контроллера и соответственно ему, ограничивает ток. В мой 25 амперный шьётся и реально отдаётся 25, в Ольгин - 20 А, оба 48 вольтовые.

Если так, то это хорошо.  в модуле Unit1.pas исходника есть процедура TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);  в которой судя по её содержимому(жаль конечно,что комментариев там нет, но и без них понятно многое) видно, что принимаются данные с компорта, они пишутся в буффер и потом из него извлекается , переводится в строчный тип и выводится в правый верхний угол  в те самые сообщения 'Manufacturer:хххх  , 'Model:ххх ,'Harware Ver:ххх,  потом она определяет, какое напряжение написать из списка и так далее. Так вот, я думаю,чтобы не искать все места в программе, где упоминается ограничение тока,можно прямо в этой процедуре и произвести подмену принятой строки на подправленную, а дальше уже сама программа будет считать, что имеет дело с 25-амперным мотором нужной модели нужной версии Harware Ver и далее сама всё пропишет в контроллер как для 25 ампер.   Только для перекомпиляции проекта всё равно будет нужно  искать уже упомянутый выше компонент Comm1, без него компилятор выдаст ошибку "Field Form1 Comm1 does not have a corresponding component/ Remove the declaration?"
Бафанги: МК 250w (передн), МК 350w(задн), МИДы BBS-02 500W, и BBS-02 750W ,моноколесо KS14b, бензо: Д8Э, KD-F80

peat

Дайте мне позырить исходники. Я на дельфях уже 10 лет сижу и с компортом на ты.


Можно сделать инче - у каждого визуального компонента дельфи есть свой идентификатор или класс зная который можно пихнуть в него , тоесть в компонент на форме программы лбое значение или поменятьстроку или еще что сделать.
Но я бы изучил проток обмена и написал бы свой софт. Или адаптировал сомм1 под какойнить Bport .
Там все процедуры и функции одинаковы ибо все эти Cport Bort  итд юзают API винды. ПОсле 2 чашек кофе  можно вообще без компонентов обойтись.


killer258

Цитата: peat от 08 Янв. 2015 в 20:43
Дайте мне позырить исходники. Я на дельфях уже 10 лет сижу и с компортом на ты.

вот по этой ссылке  https://drive.google.com/file/d/0Bw59cTuRZg0PbzgyYXBFSG9jTVE/edit?usp=sharing
откроется  страничка, в верхней части увидите вертикальную стрелку вниз, упирающуюся в вгоризонтальную черту, наведёте  мышку на неё, появится "скачать", щёлкните,  и вам загрузится.

Цитировать
Но я бы изучил проток обмена и написал бы свой софт.

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

ЦитироватьИли адаптировал сомм1 под какойнить Bport .
Тоже  была такая  мысль. Не захотелось что-то переправлять везде  идентификаторы.

Цитировать
Там все процедуры и функции одинаковы ибо все эти Cport Bort  итд юзают API винды.
То-то я смотрю, все эти Comm32, BComport,CPortLib  и прочие очень уж похожи все друг на друга, одни  и теже свойства , методы  и события практически у всех, что у одного, что у другого.
Бафанги: МК 250w (передн), МК 350w(задн), МИДы BBS-02 500W, и BBS-02 750W ,моноколесо KS14b, бензо: Д8Э, KD-F80

peat

А точно контроллер переваривает , если впихнуть в него излишек с софтины ? Просто если editbox не дает ввести большой ток , это не значит что контроллер его переварит , если ввести силой так сказать. ТОчнее схавает значение , а в регистр запишется обрезанное число например.


peat

#82
Так как у меня нет этого мотора и проверить неначем , займусь только теорией.
Итак есть функция записи в компорт. И что мы тут видим ?  А видим все как на ладоне. Я думал там будет стек USB или какието чумные заходы мыслей..однако все до безобразия просто  и писал прогу  школьник или девушка с красивым маникюром. Особо видно вот по таким связкам :

    st:=55;
    bytSendData[25] := st;

:laugh:
Обычно после хотя бы месяца  кодинга пишут просто одной строкой -  bytSendData[25] := 55;

Итак поехали.

Спойлер
function Searchdev(L: Integer): Integer;
var
  strTemp : String;
  s7 : String ;
  s8 : String  ;
  bytSendData: array[0..255] of byte;
  senddata,sendstr:string;
  redata:array of variant;
  intVarify : Integer ;
  i : Integer ;
  s : Integer;
  st,sleng : Integer;
  restr,d:string;
begin


  bytSendData[0] := $16;

  bytSendData[1] := $52;

  bytSendData[2] := L;

  bytSendData[3] := strtoint(Form1.ComboBox3.text);

  bytSendData[4] := strtoint(Form1.Edit1.text);
  bytSendData[5] := strtoint(Form1.Edit2.text);
  bytSendData[6] := strtoint(Form1.Edit3.text);
  bytSendData[7] := strtoint(Form1.Edit4.text);
  bytSendData[8] := strtoint(Form1.Edit5.text);
  bytSendData[9] := strtoint(Form1.Edit6.text);
  bytSendData[10] := strtoint(Form1.Edit7.text);
  bytSendData[11] := strtoint(Form1.Edit8.text);
  bytSendData[12] := strtoint(Form1.Edit9.text);
  bytSendData[13] := strtoint(Form1.Edit10.text);
  bytSendData[14] := strtoint(Form1.Edit11.text);
  bytSendData[15] := strtoint(Form1.Edit12.text);
  bytSendData[16] := strtoint(Form1.Edit13.text);
  bytSendData[17] := strtoint(Form1.Edit14.text);
  bytSendData[18] := strtoint(Form1.Edit15.text);
  bytSendData[19] := strtoint(Form1.Edit16.text);
  bytSendData[20] := strtoint(Form1.Edit17.text);
  bytSendData[21] := strtoint(Form1.Edit18.text);
  bytSendData[22] := strtoint(Form1.Edit19.text);
  bytSendData[23] := strtoint(Form1.Edit20.text);
  bytSendData[24] := strtoint(Form1.Edit21.text);
  s:=Form1.ComboBox4.ItemIndex;
  if (s=12) then
  begin
    st:=55;
    bytSendData[25] := st;
  end
  else
  begin
    st:=strtoint(Form1.ComboBox4.text)*2;
    bytSendData[25] := st;
  end;

  if Form1.ComboBox5.ItemIndex =2 then
    st:=3*64
  else
    st:=Form1.ComboBox5.ItemIndex*64;
  st:=st+strtoint(Form1.Edit22.text);
  bytSendData[26] := st;
  st:=0;
  for i := 0 to L+1  do
  begin
    st:=st+bytSendData[i+1];
  end;

  s:=st  Mod 256;
  bytSendData[27] := s;



Sleep(50);
  if not Form1.Comm1.writecommdata(@bytSendData,28) then
  begin
    showmessage('Error sending!');

  end
  else
  begin

  end;

  Result := 0;

end;


Все очень просто и понятно.
Основой является массив байт - bytSendData: array[0..255] of byte;
В него по очереди пихаются сначала видимо идентификаторы.  $16 b $52 - видимо это заголовок пакета (типа принадлежность пакета к этому девайзу,
Теперь про переменную L. В Unit1 когда жмем на батон3 (write to controller) вызывается функция BitBtn3Click  и в ней   вычисляется L.
Судя по всему L- это Legal ибо принимает состояние либо 0 либо 1. причем например от условия

if (strtoint(edit22.Text)>36) or (strtoint(edit22.Text)<1) then
    begin
      Application.MessageBox('The SpdMeter Signal is out of range,Please input again.','prompt message',mb_ICONINFORMATION+mb_Ok);
      L:=1;

Тоесть , если SpdMeterSignal > 36 то L=1

Короче идет массивная проверка всех введенных значений с вызовом диалогового окна в случае если значения выйдут за пределы. Эту хню можно смело тереть.

Итак заголовок пакета имеет такой вид -

bytSendData[0] := $16;
bytSendData[1] := $52;
bytSendData[2] := L;
bytSendData[3] := strtoint(Form1.ComboBox3.text);



Дальше тупо записываются в массив bytSendData значения которыые веели в окошках.

Спойлер
bytSendData[4] := strtoint(Form1.Edit1.text);
  bytSendData[5] := strtoint(Form1.Edit2.text);
  bytSendData[6] := strtoint(Form1.Edit3.text);
  bytSendData[7] := strtoint(Form1.Edit4.text);
  bytSendData[8] := strtoint(Form1.Edit5.text);
  bytSendData[9] := strtoint(Form1.Edit6.text);
  bytSendData[10] := strtoint(Form1.Edit7.text);
  bytSendData[11] := strtoint(Form1.Edit8.text);
  bytSendData[12] := strtoint(Form1.Edit9.text);
  bytSendData[13] := strtoint(Form1.Edit10.text);
  bytSendData[14] := strtoint(Form1.Edit11.text);
  bytSendData[15] := strtoint(Form1.Edit12.text);
  bytSendData[16] := strtoint(Form1.Edit13.text);
  bytSendData[17] := strtoint(Form1.Edit14.text);
  bytSendData[18] := strtoint(Form1.Edit15.text);
  bytSendData[19] := strtoint(Form1.Edit16.text);
  bytSendData[20] := strtoint(Form1.Edit17.text);
  bytSendData[21] := strtoint(Form1.Edit18.text);
  bytSendData[22] := strtoint(Form1.Edit19.text);
  bytSendData[23] := strtoint(Form1.Edit20.text);
  bytSendData[24] := strtoint(Form1.Edit21.text);


Дальше интереснее.
Начиная с 25-го байта в массиве , видим условие:

s:=Form1.ComboBox4.ItemIndex;
  if (s=12) then
  begin
    st:=55;
    bytSendData[25] := st;
  end
  else
  begin
    st:=strtoint(Form1.ComboBox4.text)*2;
    bytSendData[25] := st;
  end;


КОроче 25  26  27 ячейки это диаметр колеса , модель спидометра и что то связано с сигналом с датчика. Можно рямо взять этот кусок кода.

И вот тут уже  if not Form1[b-b].Comm1.writecommdata(@bytSendData,28)[/b-b] then... происходит сама запись.


КОроче говоря , перевести на Bport а лучше на CportLib  тут вообще не проблема.
Например передача пакета в Cport звучит так -
Comport1.Write(bytSendData,28) где bytSendData - наш заполненный массив , 28 - количество байт для передачи. Это количество определяет длину пакета и олжно быть неизменным.

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

При чтении с контроллера происходит вызов функции
  st:=$52;
  Readdev(st);  с параметром $52.

В этой функции заполняются всего 2 байта нашего массива

bytSendData[0] := $11;
  bytSendData[1] := st;

(помним что ST=$52

И передаются эти 2 байта в компорт.
Comm1.writecommdata(@bytSendData,2)

Дальше ждем 28 байт ответа от контроллера которые мы помещаем в наш массив.

Тут все настолько просто что я уже устал писать.

Подытожу.
Запрос на дамп из контроллера  выглядет так -
B1=$11
B2=$52
Выливаем 2 байта в компорт.

Ждем ответ.

В ответе приходит пакет из 28 байт.
Запихиваем этт пакет в наш массив. На Cport выглядет так - ComPort1.read(наш массив,28);
Дальше из этого массива распихиваем значения по ячейкам.

Модифицируем , сливаем обратно.

Там еще будут вопросы по настройке компорта. Но это в гугл.

На счет компонента Tcomm - это из дельфи6.  Можно скачать 6-ю дельфю там он должен быть. Вилимо эту бафанговскую тулзу делали в 6-й дельфи.
Я бы скачал попробовал. Ради разлока.

..ушел спать.











killer258

Цитата: peat от 09 Янв. 2015 в 02:49
писал прогу  школьник или девушка с красивым маникюром. Особо видно вот по таким связкам :

    st:=55;
    bytSendData[25] := st;

:laugh:
Обычно после хотя бы месяца  кодинга пишут просто одной строкой -  bytSendData[25] := 55;

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

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

Цитировать
Итак поехали.


Например передача пакета в Cport звучит так -
Comport1.Write(bytSendData,28) где bytSendData - наш заполненный массив , 28 - количество байт для передачи. Это количество определяет длину пакета и олжно быть неизменным.

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

При чтении с контроллера происходит вызов функции
  st:=$52;
  Readdev(st);  с параметром $52.

В этой функции заполняются всего 2 байта нашего массива

bytSendData[0] := $11;
  bytSendData[1] := st;

(помним что ST=$52

И передаются эти 2 байта в компорт.
Comm1.writecommdata(@bytSendData,2)

Дальше ждем 28 байт ответа от контроллера которые мы помещаем в наш массив.

Тут все настолько просто что я уже устал писать.

Подытожу.
Запрос на дамп из контроллера  выглядет так -
B1=$11
B2=$52
Выливаем 2 байта в компорт.

Ждем ответ.

В ответе приходит пакет из 28 байт.
Запихиваем этт пакет в наш массив. На Cport выглядет так - ComPort1.read(наш массив,28);

C учётом того, что уже было  выяснено ранее, это относится к запросу главной вкладки (Basic)
там как раз $11  $52, потом идёт 25 байтов для окошек этой вкладки и последний , 28-й байт, видимо, контрольная сумма.
Для двух оставшихся вкладок (Assist и Throttle) идут отдельные запросы, и второй  байт уже  будет $53 и $54 cоответственно.
И там байтов  в пакете приходит поменьше, по числу окошек в этих вкладках.
$52, $53,$54- это значит, смотря к какой  вкладке относится,  а  в целом видимо, второй  байт пакета -это код операции, указание "что делать"



Цитировать
Модифицируем , сливаем обратно.
Здесь видимо, всё будет аналогично чтению, только или хеадер будет другой, или код операции другой вероятно, потребуется. Возможно, запись тоже происходит в три захода, для каждой из владок, и коды операций окажутся $55,$56 и $57 соответственно.. Можно  будет "подсмотреть" портмонитором во время сеанса связи этого ПО с мотором .

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

И ещё, как было выяснено ранее,  байт после  кода операции является чем-то вроде статуса операции. Придётся выяснить, как он формируется и что он значит .
Бафанги: МК 250w (передн), МК 350w(задн), МИДы BBS-02 500W, и BBS-02 750W ,моноколесо KS14b, бензо: Д8Э, KD-F80

peat

Я не увидел вычисление контрольной суммы вобще.. Там в коде даже нет определения 28-го байта. Судя по всему его значение NIL.
Это относится к первой закладке.

Да..там 3 закладки и разные заголовки и длины пакетов. Но это ничуть не усложняет задачу.

Был бы мотора и желание я  бы справился с новой прогой  минут за 30 с отладкой.  Тут даже думать не надо. Протокол на ладоне.

На счет переварит или нет - это уже на свой с трах и риск. Но я уверен что загрузчик контроллера не пострадает если в ячейки занести Overlaped  параметры.
Это не бит ориентированный протокол , где на каждый параметр отведено стррогое число бит . И например число 15 кодируется как 1111 , а число 16 уже требует 5 бит. 10000. В этом случае пакет удлинится и вероятно что сдвинет код в контроллере что может затронуть загрузчик. Но повторюсь - тут байт ориентированный протокол. И под данные отведено свое место и что то записать не туда невозможно.




killer258

Цитата: peat от 09 Янв. 2015 в 16:42
Я не увидел вычисление контрольной суммы вобще.. Там в коде даже нет определения 28-го байта. Судя по всему его значение NIL.
Это относится к первой закладке.

Да..там 3 закладки и разные заголовки и длины пакетов. Но это ничуть не усложняет задачу.


В общем-то, да, хоть один пакет, хоть три, разницы нет. Возможно, что они вообще независимы и можно скорее всего  даже вдуть в мотор только лишь один  пакет только той вкладки, на которой  находится параметр, не выставляемый оригинальным бафанговским софтом в нужных пределах.   Это вкладка Basic, второй и третий байты после кода операции$52 . LowBat Protect(41 вольт)  и Limited Current(25A). Остальные-то параметры можно устанавливать  и естественным  путём, без этого взлома.
По-моему, эти пакеты можно вдуть в мотор  даже с какой-нибудь терминалки, отключив добавление в конце строки  символов CR LF
Процедуры  контрольной суммы в исходнике я тоже не видел, хотя странно, обычно в подобных обменах она используется.
Возможно, её проверка в моторе отключена
Бафанги: МК 250w (передн), МК 350w(задн), МИДы BBS-02 500W, и BBS-02 750W ,моноколесо KS14b, бензо: Д8Э, KD-F80

killer258

Как говорил один из участников форума, 500 вт и 750 вт моторы вроде бы одинаковы по размерам, и внешне ничем не отличаются, кроме шильдика,поэтому подозреваю,  что достаточно будет  лишь вдуть  туда Current Limit=25A для превращения моего 500 вт мотора в 750-ваттный.
Бафанги: МК 250w (передн), МК 350w(задн), МИДы BBS-02 500W, и BBS-02 750W ,моноколесо KS14b, бензо: Д8Э, KD-F80

acyd

говорил же выше, мой 500вт, id и буковки в программе абсолютно такие же как у 750вт 20а, прошивка той же версии,  больше 18а(19 и 20) дает прописать, но выдает ошибку при попытке газануть даже на холостом и едет только на 7а,
транзисторы кратковременно могут переварить 30а, сразу не сгорят.

killer258

Значит, остаётся только искать  шунт в контроллере мотора и лудить его. Покупать по новым ценам 750 вт мотор уже будет довольно напряжно.
Бафанги: МК 250w (передн), МК 350w(задн), МИДы BBS-02 500W, и BBS-02 750W ,моноколесо KS14b, бензо: Д8Э, KD-F80

ra6fnq

Можно купить контроллер: http://em3ev.com/store/index.php?route=product/product&path=46&product_id=188
80$ меньше 440 - 500$,  особенно если вскладчину, чтоб раскидать транспортные расходы на всеж
Евгений
http://fotki.yandex.ru/users/ra6fnq/
https://yadi.sk/d/8wi9CuXnvvFRh - инструкции на Bafangs