Показано с 1 по 1 из 1
  1. #1
    Модератор
    Регистрация
    06.07.2008
    Возраст
    46
    Сообщений
    414
    Вес репутации
    436

    По умолчанию Управлялка ногами посредством терминалки

    Сделал тут управлялку ногами ардуины постедством терминалки, PHP или чего угодно другого.

    Скорость порта 115200, можете поменять в setup()

    Кроме того, скетч поддерживает работу dallas 18х20, причем если нужно - на нескольких pin'ах, в данном примере - pin10, pin9.
    #define OneWirePinCount 2
    #define OneWirePin0 10
    #define OneWirePin1 9
    byte OneWirePins[OneWirePinCount];https://duino.ru/arduino.html

    Плюс - работу с пинами (тут - 11 штук).

    #define IOPinCount 11
    byte IOPins[IOPinCount] ={3,4,5,6,7,8,11,12,13,A2,A3};

    Ответ на каждую команду завешается нулевым символом.

    команда "at" - ответ ОК.
    команда "info" - выводит какой-то текст.
    команда "list" - выводит список устройств. Выводятся только ранее найденные устройства +пины общего назначения, перечисленные в IOPins. Вывод - <тип устройства>;<номер вывода ардуины>;<идентификатор устройства>;<параметры чтения через запятую>;<параметры записи через запятую>.
    для 18х20 - может грузить температуру (параметр T), записывать в датчики не умеет.
    Для пинов:
    М - pinMode (пин на выход (1) или на вход (0) работает) (запись - задание параметра, чтение - текущее состояние).
    D - digitalWrite (LOW (0)/ HIGH (1)) (запись - задание параметра, чтение - текущее состояние).
    P - digitalRead (LOW (0)/ HIGH (1))
    A - параметр чтения - analogread, на вывод - analogwrite. Работает только для соответствующих ног.

    Учтите, что несмотря на то, что в IOPins указаны ноги A2, используются в реальности номера пинов, как если бы они были цифровыми, для arduino - A0 -> 14 A1 -> 15 и тд.

    команда "scan" - ищет устройства 1wire. Пока устройства 1wire не найдены, им нельзя выдать команды. Максимальное количество устройств 1-wire, с которым может работать - Max1WCount задано 20.

    команда "measure" - отдает команду на измерение температуры на все 1wire пины.
    "read" загружает данные температуры со всех 18x20 устройств. Учтите, что между measure и read должно пройти время не менее 750мс.
    "print" выводит параметры всех устройств. Вид вывода:
    <id>;<список значений через запятую>. Что значения значат можете посмотреть в команде list.
    "set" - позволяет задать параметры пинов

    Отправка команды - перевод строки - 13 или 10-й символ (подходит \n)

    Примеры.
    >>at\n
    <<OK\n\0
    >>scan\n
    <<OK\n\0
    >>measure\n
    <<OK\n\0
    >>list\n
    >>1W;10;28.9C6E4302000046;T;
    1W;10;28.9DAE1B02000097;T;
    1W;10;28.23DC1B0200006D;T;
    1W;10;28.DB6A43020000A9;T;
    Pin;3;P3;M,D,P;M,D,A
    Pin;4;P4;M,D,P;M,D
    Pin;5;P5;M,D,P;M,D,A
    Pin;6;P6;M,D,P;M,D,A
    Pin;7;P7;M,D,P;M,D
    Pin;8;P8;M,D,P;M,D
    Pin;11;P11;M,D,P;M,D,A
    Pin;12;P12;M,D,P;M,D
    Pin;13;P13;M,D,P;M,D
    Pin;16;P16;M,D,P,A;M,D
    Pin;17;P17;M,D,P,A;M,D
    \0
    >>read\n
    <<OK\n\0
    >>print
    >>28.9C6E4302000046;-1.63
    28.9DAE1B02000097;43.69
    28.23DC1B0200006D;38.88
    28.DB6A43020000A9;41.50
    P3;0,0,0
    P4;0,0,0
    P5;0,0,0
    P6;0,0,0
    P7;0,0,0
    P8;0,0,0
    P11;0,0,0
    P12;0,0,0
    P13;1,0,0
    P16;0,0,0,342
    P17;0,0,0,340
    \0

    Смотрим на то, что выдала нам list в отношении P13:
    Pin;13;P13;M,D,P;M,D
    и на то, что выдала print:
    P13;1,0,0
    На чтение - параметры M,D,P (состояние pinmode у нас 1 - OUTPUT, состояние digitalwrite =0, значит LOW, digitalread =0 ).
    на запись можно давать команды с параметрами M,D т.е. только pinmode и digitalwrite, так как данная нога не поддерживает ни analogwrite.

    нога A2 преобразовалась в P16. Именно так ей можно будет дать команду. Для нее считался еще один параметр - analogread = 342 в моем примере. Это видно по тому, как эта нога описана в list
    Pin;16;P16;M,D,P,A;M,D
    на чтение четыре параметра M,D,P,A.

    >>set P13 D 1\n
    <<OK\n\0
    Эта команда выпонила digitalWrite(13,HIGH); В результате у меня на плате зажегся светодиод, связанный с ногой P13. Связано это с тем, что pinMode уже был в OUTPUT (так было написано в выводе print).

    >>set P13 M 0\n
    <<OK\n\0
    Эта команда выполнила pinMode(13,INPUT); Светодиод почти погас.

    В PHP для того, чтобы делить вывод удобно пользоваться explode()

    PHP код:
    function GetAnswer($handle$timetowait)
    {
    //    echo "test";
        
    $currt=time();
        
    $cur="";
        
    $i=0;
        
    $j=0;
        for (
    $data="";($data!="\0")&&(time()-$currt<$timetowait);)
        {
            
    $i++;
            
    $data fread($handle1);
            if (
    $data!="")
                
    $j++;
            if (
    $data!="\0")
                
    $cur.=$data;
        }
    //    echo $cur;
    //    echo $i.";".$j;
        
    return $cur;
    }

    function 
    SendCommand($handle,$str)
    {
        
    fputs($handle,$str);
    //    echo "command:".$str."<br>";
        
    $a=GetAnswer($handle,2);
        
    $data=str_replace("\n","<br>",$a);
    //    echo $data."<br>";
    }

    exec("stty -F /dev/ttyUSB0 cs8 115200 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -c
    rtscts"
    );

    $handle fopen("/dev/ttyUSB0""r+"); //format: dio.serial://[device-name]

    if (!stream_set_blocking($handle,0))
        echo 
    "cant set blocking mode";
    if (
    $handle) {
    echo 
    "Initialize port... done<br>";

    $a=fread($handle,0);
    //echo "before:".$a."<br>";

    SendCommand($handle,"at\n");
    SendCommand($handle,"info\n");
    SendCommand($handle,"scan\n"); // не анализируем вывод - он может быть только ОК.

    fputs($handle,"list\n");
    $a=GetAnswer($handle,2);
    //echo "list:".$a."<br>";
    $Lines=explode("\n",$a); // делим на строки
    for ($i=0;$i<count($Lines);$i++)
    {
    //    echo $Lines[$i]."<br>";
        
    $Params=explode(";",$Lines[$i]); // делим на параметры
        
    if (count($Params)>=4)
        {
            
    $Type=$Params[0]; // тип устройства 1W/pin
            
    $Pin=$Params[1]; // номер пина
            
    $Id=$Params[2]; // id
            
    $ReadParams=$Params[3]; 
            
    $WriteParams=$Params[4];
    ...
         }

    Код скетча.
    PHP код:
    #include <OneWire.h>

    // OneWire DS18S20, DS18B20, DS1822 Temperature Example
    //
    // http://www.pjrc.com/teensy/td_libs_OneWire.html
    //
    // The DallasTemperature library can do all this work for you!
    // http://milesburton.com/Dallas_Temperature_Control_Library

    #define OneWirePinCount 2
    #define OneWirePin0 10
    #define OneWirePin1 9
    byte OneWirePins[OneWirePinCount];
    #define IOPinCount 11
    byte IOPins[IOPinCount] ={3,4,5,6,7,8,11,12,13,A2,A3};

    #ifdef OneWirePin0 
      
    OneWire  ds0(OneWirePin0);
    #endif
    #ifdef OneWirePin1
      
    OneWire  ds1(OneWirePin1);
    #endif
    #ifdef OneWirePin2
      
    OneWire  ds2(OneWirePin2);
    #endif
    #ifdef OneWirePin3
      
    OneWire  ds3(OneWirePin3);
    #endif
    #ifdef OneWirePin4
      
    OneWire  ds4(OneWirePin4);
    #endif

    #define Max1WCount 20

    #define MaxCommandLength 20

    byte Command[MaxCommandLength];
    byte CommandLength=0;

    byte at_Command[] PROGMEM "at";
    byte info_Command[] PROGMEM "info";
    byte List_Command[] PROGMEM "list";
    byte Scan_Command[] PROGMEM "scan";
    byte Measure_Command[] PROGMEM "measure";
    byte Read_Command[] PROGMEM "read";
    byte Print_Command[] PROGMEM "print";
    byte Set_Command[] PROGMEM "set";

    byte addr[Max1WCount][9];
    int16_t Datas[Max1WCount];

    OneWiredss[OneWirePinCount];
    byte IOPin[IOPinCount];

    int8_t OneWireDeviceCount;

    void setup(void) {
    #ifdef OneWirePin0
      
    dss[0]=&ds0;
      
    OneWirePins[0]=OneWirePin0;
    #endif
    #ifdef OneWirePin1
      
    dss[1]=&ds1;
      
    OneWirePins[1]=OneWirePin1;
    #endif
    #ifdef OneWirePin2
      
    dss[2]=&ds2;
      
    OneWirePins[2]=OneWirePin2;
    #endif
    #ifdef OneWirePin3
      
    dss[3]=&ds3;
      
    OneWirePins[3]=OneWirePin3;
    #endif
    #ifdef OneWirePin4
      
    dss[4]=&ds4;
      
    OneWirePins[4]=OneWirePin4;
    #endif

    //  dss[0]=&ds1;
    //  dss[1]=&ds2;
      
    OneWireDeviceCount=0;
      
    Serial.begin(115200);
    }

    void Print1WId(byte *id)
    {
        for(
    uint8_t i 08i++) {
          
    Serial.print(*id >>4HEX);
          
    Serial.print(*id 15HEX);
          if (
    i==0)
            
    Serial.write('.');
          
    id++;
        }
    }

    void Scan(void)
    {
      
    OneWireds;
      
      
    OneWireDeviceCount=0;
      for (
    uint8_t i=0;i<OneWirePinCount;i++)
      {
        
    ds=dss[i];
        
    ds->reset_search();
        for (;
    ds->search(addr[OneWireDeviceCount]);)
        {
          if (
    OneWire::crc8(addr[OneWireDeviceCount], 7) == addr[OneWireDeviceCount][7]) 
          {
            
    addr[OneWireDeviceCount][8]=i;
            
    OneWireDeviceCount++;
          }
        }
      }
    }

    bool IsPinAnalogWrite(uint8_t Pin)
    {
        return 
    digitalPinToTimer(Pin)!=NOT_ON_TIMER;
    }

    bool IsPinAnalogRead(uint8_t pin)
    {
    #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
        
    if (pin >= 54pin -= 54; else pin=255// allow for channel or pin numbers
    #elif defined(__AVR_ATmega32U4__)
        
    if (pin >= 18pin -= 18; else pin=255;// allow for channel or pin numbers
    #else
        
    if (pin >= 14pin -= 14; else pin=255;// allow for channel or pin numbers
    #endif
       
    return pin!=255;
    }

    void List(void)
    {
        for (
    byte i=0;i<OneWireDeviceCount;i++)
        {
          
    Serial.print("1W;");
          
    Serial.print(OneWirePins[addr[i][8]]);
          
    Serial.print(";");
          
    Print1WId(addr[i]);
          
    byte j=addr[i][0];
          if ((
    j==0x10)||(j==0x22)||(j==0x28))
          {
            
    Serial.print(";T;");
          }
          
    Serial.println();
        }
        for (
    byte i=0;i<IOPinCount;i++)
        {
          
    byte pin=IOPins[i];
          
    Serial.print("Pin;");
          
    Serial.print(pin);
          
    Serial.print(";P");
          
    Serial.print(pin);
          
    Serial.print(";M,D,P");
          if (
    IsPinAnalogRead(pin))
            
    Serial.print(",A");
          
    Serial.print(";M,D");
          if (
    IsPinAnalogWrite(pin))
            
    Serial.print(",A");
          
    Serial.println();
        }
    }  

    void StartMeasureTemp(void)
    {
        for (
    uint8_t j=0;j<OneWirePinCount;j++)
        {
          
    OneWireds;
          
    ds=dss[j];
          
    ds->reset();
          
    ds->skip();
          
    ds->write(0x44,1);         // start conversion, with parasite power on at the end
        
    }
    /*    for (int8_t j=0;j<Count;j++)
        {
          OneWire* ds;
          ds=dss[addr[j][8]];
          ds->reset();
          ds->select(addr[j]);
          ds->write(0x44,1);         // start conversion, with parasite power on at the end
        }*/
    }

    int8_t type_s(uint8_t index)
    {
      switch (
    addr[index][0]) {
        case 
    0x10:
          return 
    1;
        case 
    0x28:
          return 
    0;
        case 
    0x22:
          return 
    0;
        default:
          return -
    1;
      }

    }

    void ReadTemps(void)
    {
      
    byte data[12];
      for (
    int j=0;j<OneWireDeviceCount;j++)
      {
        
    OneWireds;
        
    ds=dss[addr[j][8]];
        
    ds->reset();
        
    ds->select(addr[j]);    
        
    ds->write(0xBE);         // Read Scratchpad
      
        
    for (uint8_t i 09i++) {           // we need 9 bytes
          
    data[i] = ds->read();
        }

        
    // convert the data to actual temperature
      
        
    unsigned int raw = (data[1] << 8) | data[0];
        if (
    type_s(j)) {
          
    raw raw << 3// 9 bit resolution default
          
    if (data[7] == 0x10) {
            
    // count remain gives full 12 bit resolution
            
    raw = (raw 0xFFF0) + 12 data[6];
          }
        } else {
          
    byte cfg = (data[4] & 0x60);
          if (
    cfg == 0x00raw raw << 3;  // 9 bit resolution, 93.75 ms
          
    else if (cfg == 0x20raw raw << 2// 10 bit res, 187.5 ms
          
    else if (cfg == 0x40raw raw << 1// 11 bit res, 375 ms
          // default is 12 bit resolution, 750 ms conversion time
        
    }
        
    Datas[j] = raw;
      
    //  fahrenheit = celsius * 1.8 + 32.0;
      
    }
    }

    void PrintTemps(void)
    {
      for (
    int j=0;j<OneWireDeviceCount;j++)
      {
        
    float celsius=(float)Datas[j]/16.0;
        
    Print1WId(addr[j]);
        
    Serial.print(";");
        
    Serial.println(celsius);
      }
    }

    bool GetPinState(byte pin)
    {
        
    uint8_t bit digitalPinToBitMask(pin);
        
    uint8_t port digitalPinToPort(pin);
        
    volatile uint8_t *out;

        if (
    port == NOT_A_PIN) return false;

        
    // If the pin that support PWM output, we need to turn it off
        // before doing a digital write.
        
    out portOutputRegister(port);

            return *
    out bit;
    }

    bool GetPinMode(byte pin)
    {
        
    uint8_t bit digitalPinToBitMask(pin);
        
    uint8_t port digitalPinToPort(pin);
        
    volatile uint8_t *reg;

        if (
    port == NOT_A_PIN) return false;

        
    reg portModeRegister(port);

            return *
    reg bit;
            
    //    if (mode == INPUT) { 
    //        *reg &= ~bit;
    //    } else {
    //        *reg |= bit;
    //    }
    }

    void PrintPins()
    {
        for (
    byte i=0;i<IOPinCount;i++)
        {
          
    byte pin=IOPins[i];
          
    Serial.print("P");
          
    Serial.print(pin);
          
    Serial.print(";");
          if (
    GetPinMode(pin))
    //      if (true)
            
    Serial.print("1,");
          else
            
    Serial.print("0,");
          if (
    GetPinState(pin))
      
    //    if (false)
            
    Serial.print("1,");
          else
            
    Serial.print("0,");
    //      if (true)
          
    if (digitalRead(pin)==HIGH)
            
    Serial.print("1");
          else
            
    Serial.print("0");
          if (
    IsPinAnalogRead(pin))
          {
            
    Serial.print(",");
            
    Serial.print(analogRead(pin));
          }
          
    Serial.println();
        }
    }

    bool FindNextString(byte &firstbyte &length)
    {
      for (;(
    first<CommandLength)&&(Command[first]==' ');first++);
      if (
    first>=CommandLength)
        return 
    false;
      else
      {
        for(
    length=1;(first+length<CommandLength)&&(Command[first+length]!=' ');length++);
        return 
    true;
      }
    }

    bool TestSubstr(byte first,byte length,bytestr)
    {
     
    byte i;
     for (
    i=0;(i<length)&&(pgm_read_byte(&str[i])==Command[first+i]);i++);
     if (
    i<length)
      return 
    false;
     else
      return (
    pgm_read_byte(&str[length])==0);
    }

    byte CharToInt(byte ch)
    {
      if ((
    ch>='0')&&(ch<='9'))
        return 
    ch-'0';
      else
        return 
    255;
    }

    void ProceedCommand(void)
    {
      
    byte first;
      
    uint8_t length;
      
    first=0;
      
    byte Error=0;
      if (
    FindNextString(first,length))
    //  for (first=0;FindNextString(first,length);first=first+length+1)
      
    {
    //      Serial.write("Command:");
    //      for (byte i=0;i<length;i++)
    //        Serial.write(Command[first+i]);
    //      Serial.write("\n");
    //      Serial.write(0x10);
          
    if (TestSubstr(first,length,at_Command))
          {
            
    Serial.write("OK\n");
          }
          else
          if (
    TestSubstr(first,length,info_Command))
          {
            
    Serial.write("ver 0.1\n");
            
    Serial.write("OneWire;");
            for (
    byte i=0;i<OneWirePinCount;i++)
            {
              if (
    i>0)
                
    Serial.write(";");
              
    Serial.print(OneWirePins[i]);
            }
            
    Serial.write("\nIOPins;");
            for (
    byte i=0;i<IOPinCount;i++)
            {
              if (
    i>0)
                
    Serial.write(";");
              
    Serial.print(IOPins[i]);
            }
            
    Serial.write("\n");
          }
          else
          if (
    TestSubstr(first,length,Scan_Command))
          {
            
    Scan();        
            
    Serial.write("OK\n");
          }
          else
          if (
    TestSubstr(first,length,List_Command))
          {
    //         Serial.write("Nothing to do\n");
            
    List();        
          }
          else
          if (
    TestSubstr(first,length,Measure_Command))
          {
            
    StartMeasureTemp();
    //        delay(750);
            
    Serial.write("OK\n");
          }
          else
          if (
    TestSubstr(first,length,Print_Command))
          {
    //        Serial.write("OK\n");
            
    PrintTemps();
            
    PrintPins();
          }
          else
          if (
    TestSubstr(first,length,Read_Command))
          {
            
    Serial.write("OK\n");
            
    ReadTemps();
          }
          else
          if (
    TestSubstr(first,length,Set_Command))
          {
            
    first+=length+1;
            if (
    FindNextString(first,length))
            {
              if ((
    Command[first]=='P')&&((length==2)||(length==3)))
              {
                
    byte p2;
                
    byte p1=CharToInt(Command[first+1]);
                if (
    length==2)
                {
                    
    p2=p1;
                    
    p1=0;
                }
                else
                  
    p2=CharToInt(Command[first+2]);
                
    byte pin,comm,value;
                if ((
    p1==255)||(p2==255))
                  
    Error=true;
                else
                  
    pin=p1*10+p2;
                if (!
    Error)
                {
                  
    first+=length+1;
                  if (
    FindNextString(first,length))
                  {
                      if (
    length!=1)
                        
    Error=true;
                      else
                        
    comm=Command[first];
                  }
                  else
                    
    Error=true;
                }
                if (!
    Error)
                {
                  
    first+=length+1;
                  if (
    FindNextString(first,length))
                  {
                      if (
    length>3)
                        
    Error=true;
                      else
                      {
                        
    value=0;
                        for (
    byte i2=0;i2<length;i2++)
                        {
                          
    byte w=CharToInt(Command[first+i2]);
                          if (
    w==255)
                            
    Error=true;
                          else
                            
    value=value*10+w;
                        }
                      }
                  }
                  else
                    
    Error=true;
                }
                if (!
    Error)
                {
                  if (
    comm=='M')
                  {
                    if (
    value==0)
                      
    pinMode(pin,INPUT);
                    else
                    if (
    value==1)
                      
    pinMode(pin,OUTPUT);
                    else
                      
    Error=true;
                  }
                  else
                  if (
    comm=='D')
                  {
                    if (
    value==0)
                      
    digitalWrite(pin,LOW);
                    else
                    if (
    value==1)
                      
    digitalWrite(pin,HIGH);
                    else
                      
    Error=true;
                  }
                  else
                  if (
    comm=='A')
                  {
                    if (
    IsPinAnalogWrite(pin))
                      
    analogWrite(pin,value);
                    else
                      
    Error=true;
                  }
                  else
                    
    Error=true;
                }            
                 
                
                
    Serial.write("OK\n");
              }
              else
                
    Error=true;
            }
            else
              
    Error=true;

    //        Serial.write("OK\n");
    //        ReadTemps();
          
    }
          else
            
    Error=true;
          if (
    Error)
            
    Serial.write("Error/n");
          
    Serial.write((byte)0);     
      }
    }

    void loop(void) {
      
    byte i;
      
    byte present 0;
    //  Serial.write('a');
    //  delay(5000);
        
      
    if (Serial.available())
      {
        
    char ch;
        
    ch=Serial.read();
    //    Serial.write(ch);
        
    if ((ch==10)||(ch==13))
        {
            if (
    CommandLength>0)
              
    ProceedCommand();
            
    CommandLength=0;
        }
        else
        if (
    CommandLength<MaxCommandLength)
        {
          
    Command[CommandLength]=ch;
          
    CommandLength++;
        }
      }
      
    //  byte type_s;

    /*  Scan(); 
      
      if (Count>0)
      {
        StartMeasureTemp();
      }
      
      delay(750);     // maybe 750ms is enough, maybe not

      ReadTemps();
        
      PrintTemps();

      delay(1000);*/
    //  Serial.println(" Celsius, ");
    //  Serial.print(fahrenheit);
    //  Serial.println(" Fahrenheit");

    Последний раз редактировалось Chip; 22.03.2017 в 11:15.

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •