Как сформировать контрольную сумму CRC ?

bit
Offline
Зарегистрирован: 07.05.2012

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

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

 

 как запустить таблицу расчёта контрольной суммы?

 

Пример кода

 

void setup() {  

Serial.begin(9600);  
  
}

void loop() {
  
  
  Serial.print("88");
  Serial.print(",");
  Serial.println(con_sum);
  

 

 

 

static const uint8_t PROGMEM dscrc_table[] = { 
    0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 
  157,195, 33,127,252,162, 64, 30, 95,  1,227,189, 62, 96,130,220, 
   35,125,159,193, 66, 28,254,160,225,191, 93,  3,128,222, 60, 98, 
  190,224,  2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 
   70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89,  7, 
  219,133,103, 57,186,228,  6, 88, 25, 71,165,251,120, 38,196,154, 
  101, 59,217,135,  4, 90,184,230,167,249, 27, 69,198,152,122, 36, 
  248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91,  5,231,185, 
  140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 
   17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 
  175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 
   50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 
  202,148,118, 40,171,245, 23, 73,  8, 86,180,234,105, 55,213,139, 
   87,  9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 
  233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 
  116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; 

uint8_t crc8(const uint8_t *addr, uint8_t len) { 
  uint8_t crc = 0; 
  while (len--) { 
    crc = pgm_read_byte(dscrc_table + (crc ^ *addr++)); 
  } 
  return crc; 
}

 

 

 

bit
Offline
Зарегистрирован: 07.05.2012

В папке OneWire.h  вроде есть пример вот тока не понятно как это запустить

 



#include "OneWire.h"


OneWire::OneWire(uint8_t pin)
{
 pinMode(pin, INPUT);
 bitmask = PIN_TO_BITMASK(pin);
 baseReg = PIN_TO_BASEREG(pin);
#if ONEWIRE_SEARCH
 reset_search();
#endif
}


// Perform the onewire reset function.  We will wait up to 250uS for
// the bus to come high, if it doesn't then it is broken or shorted
// and we return a 0;
//
// Returns 1 if a device asserted a presence pulse, 0 otherwise.
//
uint8_t OneWire::reset(void)
{
 IO_REG_TYPE mask = bitmask;
 volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
 uint8_t r;
 uint8_t retries = 125;

 noInterrupts();
 DIRECT_MODE_INPUT(reg, mask);
 interrupts();
 // wait until the wire is high... just in case
 do {
  if (--retries == 0) return 0;
  delayMicroseconds(2);
 } while ( !DIRECT_READ(reg, mask));

 noInterrupts();
 DIRECT_WRITE_LOW(reg, mask);
 DIRECT_MODE_OUTPUT(reg, mask); // drive output low
 interrupts();
 delayMicroseconds(480);
 noInterrupts();
 DIRECT_MODE_INPUT(reg, mask); // allow it to float
 delayMicroseconds(70);
 r = !DIRECT_READ(reg, mask);
 interrupts();
 delayMicroseconds(410);
 return r;
}

//
// Write a bit. Port and bit is used to cut lookup time and provide
// more certain timing.
//
void OneWire::write_bit(uint8_t v)
{
 IO_REG_TYPE mask=bitmask;
 volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;

 if (v & 1) {
  noInterrupts();
  DIRECT_WRITE_LOW(reg, mask);
  DIRECT_MODE_OUTPUT(reg, mask); // drive output low
  delayMicroseconds(10);
  DIRECT_WRITE_HIGH(reg, mask); // drive output high
  interrupts();
  delayMicroseconds(55);
 } else {
  noInterrupts();
  DIRECT_WRITE_LOW(reg, mask);
  DIRECT_MODE_OUTPUT(reg, mask); // drive output low
  delayMicroseconds(65);
  DIRECT_WRITE_HIGH(reg, mask); // drive output high
  interrupts();
  delayMicroseconds(5);
 }
}

//
// Read a bit. Port and bit is used to cut lookup time and provide
// more certain timing.
//
uint8_t OneWire::read_bit(void)
{
 IO_REG_TYPE mask=bitmask;
 volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
 uint8_t r;

 noInterrupts();
 DIRECT_MODE_OUTPUT(reg, mask);
 DIRECT_WRITE_LOW(reg, mask);
 delayMicroseconds(3);
 DIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise
 delayMicroseconds(10);
 r = DIRECT_READ(reg, mask);
 interrupts();
 delayMicroseconds(53);
 return r;
}

//
// Write a byte. The writing code uses the active drivers to raise the
// pin high, if you need power after the write (e.g. DS18S20 in
// parasite power mode) then set 'power' to 1, otherwise the pin will
// go tri-state at the end of the write to avoid heating in a short or
// other mishap.
//
void OneWire::write(uint8_t v, uint8_t power /* = 0 */) {
    uint8_t bitMask;

    for (bitMask = 0x01; bitMask; bitMask <<= 1) {
 OneWire::write_bit( (bitMask & v)?1:0);
    }
    if ( !power) {
 noInterrupts();
 DIRECT_MODE_INPUT(baseReg, bitmask);
 DIRECT_WRITE_LOW(baseReg, bitmask);
 interrupts();
    }
}

void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) {
  for (uint16_t i = 0 ; i < count ; i++)
    write(buf[i]);
  if (!power) {
    noInterrupts();
    DIRECT_MODE_INPUT(baseReg, bitmask);
    DIRECT_WRITE_LOW(baseReg, bitmask);
    interrupts();
  }
}

//
// Read a byte
//
uint8_t OneWire::read() {
    uint8_t bitMask;
    uint8_t r = 0;

    for (bitMask = 0x01; bitMask; bitMask <<= 1) {
 if ( OneWire::read_bit()) r |= bitMask;
    }
    return r;
}

void OneWire::read_bytes(uint8_t *buf, uint16_t count) {
  for (uint16_t i = 0 ; i < count ; i++)
    buf[i] = read();
}

//
// Do a ROM select
//
void OneWire::select(const uint8_t rom[8])
{
    uint8_t i;

    write(0x55);           // Choose ROM

    for (i = 0; i < 8; i++) write(rom[i]);
}

//
// Do a ROM skip
//
void OneWire::skip()
{
    write(0xCC);           // Skip ROM
}

void OneWire::depower()
{
 noInterrupts();
 DIRECT_MODE_INPUT(baseReg, bitmask);
 interrupts();
}

#if ONEWIRE_SEARCH

//
// You need to use this function to start a search again from the beginning.
// You do not need to do it for the first search, though you could.
//
void OneWire::reset_search()
{
  // reset the search state
  LastDiscrepancy = 0;
  LastDeviceFlag = FALSE;
  LastFamilyDiscrepancy = 0;
  for(int i = 7; ; i--) {
    ROM_NO[i] = 0;
    if ( i == 0) break;
  }
}

// Setup the search to find the device type 'family_code' on the next call
// to search(*newAddr) if it is present.
//
void OneWire::target_search(uint8_t family_code)
{
   // set the search state to find SearchFamily type devices
   ROM_NO[0] = family_code;
   for (uint8_t i = 1; i < 8; i++)
      ROM_NO[i] = 0;
   LastDiscrepancy = 64;
   LastFamilyDiscrepancy = 0;
   LastDeviceFlag = FALSE;
}

//
// Perform a search. If this function returns a '1' then it has
// enumerated the next device and you may retrieve the ROM from the
// OneWire::address variable. If there are no devices, no further
// devices, or something horrible happens in the middle of the
// enumeration then a 0 is returned.  If a new device is found then
// its address is copied to newAddr.  Use OneWire::reset_search() to
// start over.
//
// --- Replaced by the one from the Dallas Semiconductor web site ---
//--------------------------------------------------------------------------
// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
// search state.
// Return TRUE  : device found, ROM number in ROM_NO buffer
//        FALSE : device not found, end of search
//
uint8_t OneWire::search(uint8_t *newAddr)
{
   uint8_t id_bit_number;
   uint8_t last_zero, rom_byte_number, search_result;
   uint8_t id_bit, cmp_id_bit;

   unsigned char rom_byte_mask, search_direction;

   // initialize for search
   id_bit_number = 1;
   last_zero = 0;
   rom_byte_number = 0;
   rom_byte_mask = 1;
   search_result = 0;

   // if the last call was not the last one
   if (!LastDeviceFlag)
   {
      // 1-Wire reset
      if (!reset())
      {
         // reset the search
         LastDiscrepancy = 0;
         LastDeviceFlag = FALSE;
         LastFamilyDiscrepancy = 0;
         return FALSE;
      }

      // issue the search command
      write(0xF0);

      // loop to do the search
      do
      {
         // read a bit and its complement
         id_bit = read_bit();
         cmp_id_bit = read_bit();

         // check for no devices on 1-wire
         if ((id_bit == 1) && (cmp_id_bit == 1))
            break;
         else
         {
            // all devices coupled have 0 or 1
            if (id_bit != cmp_id_bit)
               search_direction = id_bit;  // bit write value for search
            else
            {
               // if this discrepancy if before the Last Discrepancy
               // on a previous next then pick the same as last time
               if (id_bit_number < LastDiscrepancy)
                  search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
               else
                  // if equal to last pick 1, if not then pick 0
                  search_direction = (id_bit_number == LastDiscrepancy);

               // if 0 was picked then record its position in LastZero
               if (search_direction == 0)
               {
                  last_zero = id_bit_number;

                  // check for Last discrepancy in family
                  if (last_zero < 9)
                     LastFamilyDiscrepancy = last_zero;
               }
            }

            // set or clear the bit in the ROM byte rom_byte_number
            // with mask rom_byte_mask
            if (search_direction == 1)
              ROM_NO[rom_byte_number] |= rom_byte_mask;
            else
              ROM_NO[rom_byte_number] &= ~rom_byte_mask;

            // serial number search direction write bit
            write_bit(search_direction);

            // increment the byte counter id_bit_number
            // and shift the mask rom_byte_mask
            id_bit_number++;
            rom_byte_mask <<= 1;

            // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
            if (rom_byte_mask == 0)
            {
                rom_byte_number++;
                rom_byte_mask = 1;
            }
         }
      }
      while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7

      // if the search was successful then
      if (!(id_bit_number < 65))
      {
         // search successful so set LastDiscrepancy,LastDeviceFlag,search_result
         LastDiscrepancy = last_zero;

         // check for last device
         if (LastDiscrepancy == 0)
            LastDeviceFlag = TRUE;

         search_result = TRUE;
      }
   }

   // if no device found then reset counters so next 'search' will be like a first
   if (!search_result || !ROM_NO[0])
   {
      LastDiscrepancy = 0;
      LastDeviceFlag = FALSE;
      LastFamilyDiscrepancy = 0;
      search_result = FALSE;
   }
   for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i];
   return search_result;
  }

#endif

#if ONEWIRE_CRC
// The 1-Wire CRC scheme is described in Maxim Application Note 27:
// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
//

#if ONEWIRE_CRC8_TABLE
// This table comes from Dallas sample code where it is freely reusable,
// though Copyright (C) 2000 Dallas Semiconductor Corporation
static const uint8_t PROGMEM dscrc_table[] = {
      0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
    157,195, 33,127,252,162, 64, 30, 95,  1,227,189, 62, 96,130,220,
     35,125,159,193, 66, 28,254,160,225,191, 93,  3,128,222, 60, 98,
    190,224,  2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
     70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89,  7,
    219,133,103, 57,186,228,  6, 88, 25, 71,165,251,120, 38,196,154,
    101, 59,217,135,  4, 90,184,230,167,249, 27, 69,198,152,122, 36,
    248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91,  5,231,185,
    140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
     17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
    175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
     50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
    202,148,118, 40,171,245, 23, 73,  8, 86,180,234,105, 55,213,139,
     87,  9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
    233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
    116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};

//
// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
// and the registers.  (note: this might better be done without to
// table, it would probably be smaller and certainly fast enough
// compared to all those delayMicrosecond() calls.  But I got
// confused, so I use this table from the examples.)
//
uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
{
 uint8_t crc = 0;

 while (len--) {
  crc = pgm_read_byte(dscrc_table + (crc ^ *addr++));
 }
 return crc;
}
#else
//
// Compute a Dallas Semiconductor 8 bit CRC directly.
// this is much slower, but much smaller, than the lookup table.
//
uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
{
 uint8_t crc = 0;
 
 while (len--) {
  uint8_t inbyte = *addr++;
  for (uint8_t i = 8; i; i--) {
   uint8_t mix = (crc ^ inbyte) & 0x01;
   crc >>= 1;
   if (mix) crc ^= 0x8C;
   inbyte >>= 1;
  }
 }
 return crc;
}
#endif

#if ONEWIRE_CRC16
bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc)
{
    crc = ~crc16(input, len, crc);
    return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1];
}

uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc)
{
    static const uint8_t oddparity[16] =
        { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };

    for (uint16_t i = 0 ; i < len ; i++) {
      // Even though we're just copying a byte from the input,
      // we'll be doing 16-bit computation with it.
      uint16_t cdata = input[i];
      cdata = (cdata ^ crc) & 0xff;
      crc >>= 8;

      if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4])
          crc ^= 0xC001;

      cdata <<= 6;
      crc ^= cdata;
      cdata <<= 1;
      crc ^= cdata;
    }
    return crc;
}
#endif

#endif

 

leshak
Offline
Зарегистрирован: 29.09.2011

Так а в чем вопрос-то? Сами спросили, сами ответили. В вашем же посте функция crc8 для расчета контрольной суммы. Вызываете ее, передаете адресс "кого нужно обсчитать", и сколько байт нужно обработать.

leshak
Offline
Зарегистрирован: 29.09.2011

И во втором посте, тоже две фунции crc8 и crc16-ть.

Вы вообще не с того немного начали. У контрольная сумма это не какое-то "стандарт". Это "класс фунций". Семейство. Которые похоже только "предназначением".Контрольная сумма — Википедия

Поэтому для "некоего устройства", нужен "некий алгоритм расчета контрольной суммы".

Вообщем начинайте поиск с даташита своего "некоего устройства", в котором дожно быть описано как расчитать контрольную сумму. Именно для ЭТОГО устройства.

Либо ищите готовую либу под него.

Либо, если устройство работает по какой-то стандартной шине - в описании шины будет указанно что-же именно понимается под "контрольной суммой" в данном случае.

bit
Offline
Зарегистрирован: 07.05.2012

Привет , я  в ручную рассчитывал контрольную сумму по CRC 100110001 через  калькулятор

 

http://ghsi.de/CRC/index.php?Polynom=100110001&Message=7c+80+e0+c8+ca+00+3f+28

 

 и забивал в строку

 

byte dataToSend1[]={62,1,7,19,83,0,252,20,183};       // 1-83
#define DATA_LENGTH1 sizeof(dataToSend1)/sizeof(byte) 

byte dataToSend2[]={62,1,7,19,84,0,42,21,157};      // 2-84
#define DATA_LENGTH2 sizeof(dataToSend2)/sizeof(byte) 

byte dataToSend3[]={62,1,7,19,95,0,231,23,136};    //  3-95
#define DATA_LENGTH3 sizeof(dataToSend3)/sizeof(byte)

 

62,1,7,19,83,0,252,20   контрольная сумма 183

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

static const uint8_t PROGMEM dscrc_table[] = { 
    0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 
  157,195, 33,127,252,162, 64, 30, 95,  1,227,189, 62, 96,130,220, 
   35,125,159,193, 66, 28,254,160,225,191, 93,  3,128,222, 60, 98, 
  190,224,  2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 
   70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89,  7, 
  219,133,103, 57,186,228,  6, 88, 25, 71,165,251,120, 38,196,154, 
  101, 59,217,135,  4, 90,184,230,167,249, 27, 69,198,152,122, 36, 
  248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91,  5,231,185, 
  140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 
   17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 
  175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 
   50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 
  202,148,118, 40,171,245, 23, 73,  8, 86,180,234,105, 55,213,139, 
   87,  9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 
  233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 
  116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53}; 

uint8_t crc8(const uint8_t *addr, uint8_t len) { 
  uint8_t crc = 0; 
  while (len--) { 
    crc = pgm_read_byte(dscrc_table + (crc ^ *addr++)); 
  } 
  return crc; 
}

 

 

 

bit
Offline
Зарегистрирован: 07.05.2012

Вот наброски кода есть но где то что то тут не правильно

 

#include <stdio.h>



unsigned char our_data[8] = {62,1, 7,19, 122,0, 132,30};

void setup()
 {
  Serial.begin(9600);
 }

void loop()
 {

    unsigned char CRC_table[256] = {
           0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
           157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
           35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
           190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
           70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
           219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
           101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
           248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
           140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
           17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
           175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
           50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
           202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
           87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
           233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
           116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};


//---------------------------------------------------------------------------

  int main(int argc, char* argv[])
 {
     unsigned char our_crc, i;

    our_crc = 0;

    for(i=0; i<8; i++)
        CRC(&our_crc, our_data[i]);

    // MUST be 234 (0xEA)
    printf("Calculated CRC: %d (%Xh)\n");

    return 0;
 }
   Serial.println(CRC);
 }


void CRC (unsigned char *crc, unsigned char data)
{
    *crc = CRC_table[*crc ^ data];
    return;
}

 

leshak
Offline
Зарегистрирован: 29.09.2011

А мы теперь должны угадать в чем именно "неправильно" проявляется? Это такая игра?

А "не то", тут то, что вы берете копируете код, и вставляете его "куда попало", не осмыслено. Не вникая ни "куда вы его вставили" ни что же этот код означает с точки зрения компилятора.

Для начала, отворматируйте свой код. Все что в скобочках квадратных должно иметь смещение. Если не хотите руками нажмите CTRL-T в ArduinoIDE, она автоматом это сделает. После чего ответте на такие вопросы:
1. Сколько функций объявляет ваш код?
2. Где он их объявляет (внутри чего они находятся)
3. Где они вызываются (назовите строки)
4. Что происходит в строке 50?

bit
Offline
Зарегистрирован: 07.05.2012

у меня почему та код выдаёт ошибку

 

 

0021\hardware\arduino\cores\arduino/Print.h:61: note:                 void Print::println(long unsigned int, int) <near match>

sketch_jul10a.cpp: In function 'void CRC(unsigned char*, unsigned char)':

sketch_jul10a:56: error: 'CRC_table' was not declared in this scope

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Лицорука... лешак, я понял, ты тут терпение тренируеш и спокойствие.

leshak
Offline
Зарегистрирован: 29.09.2011

А где ответы на вопросы?

Вот вам еще:

"sketch_jul10a:56: error: 'CRC_table' was not declared in this scope" - как перевести? Где объявлена переменная CRC_table?

bit
Offline
Зарегистрирован: 07.05.2012

Не я просто пытаюсь разобраться

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

leshak пишет:

А где ответы на вопросы?

Есть вариант в Караганде. :)

leshak
Offline
Зарегистрирован: 29.09.2011

Puhlyaviy пишет:
Лицорука... лешак, я понял, ты тут терпение тренируеш и спокойствие.

Дык а фигли? Вон в железных вопросах со мной так же "тренируют терпение". Там уже я туплю.

А вообще, когда я учился, то мой учитель (который себя таковым не считал, просто небыло больше никого кто хоть что-то знал, и инета небыло, даже фидо еще у нас не...) - вообще ничего не объяснял. Все его ответы на мои приставания сводились к "вон в той книге есть то что тебе нужно". В итоге я был ему благодарен именно за такой подход :)

2bit: вам нужно брать справочник по языку и начинать смотреть "объявления переменных", "область видимости переменых", "объявление функций"... вообщем вначале ознакомится с синтаксисом языка (пару простеньких упражнений выполнить), а потом уже пытатся на его базе строить осмысленные предложения, а не "дали набор слов, расставте их там что-бы фраза получилась правильная". И чужой код "что-же тут происходит и зачем" - появится шанс понимать.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Гыыы, у меня щас дочь осваивает курс по програмированию на с++ от гарварда.. дык она програмы сначала в тетради пишет. И как то там видит что у ней работать будет а что нет. Я честно говоря окосел когда первый раз увидел. Кстати очень занимательный курс, для начинающих особенно. Они там так хитро народ вводят в програмирование. Рекомендую.

bit
Offline
Зарегистрирован: 07.05.2012

1 две функции

2  int main(int argc, char* argv[])

 

3 строка 36

4 должна выводится чексум

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Гыыы. Эпично.
Официант, еще кувшин сидора и крылышек. Ну и попкорна если кто желает.

leshak
Offline
Зарегистрирован: 29.09.2011

Puhlyaviy пишет:
Гыыы, у меня щас дочь осваивает курс по програмированию на с++ от гарварда.. дык она програмы сначала в тетради пишет. И как то там видит что у ней работать будет а что нет. Я честно говоря окосел когда первый раз увидел. Кстати очень занимательный курс, для начинающих особенно. Они там так хитро народ вводят в програмирование. Рекомендую.

А меня как раз бесило, когда в школе заставляли "в тетрадочке". Невозможно ничего поправить, даже форматирование. Нет помощи дружественного компилятора который может подсказать куда обратить внимание... :)  (многие почему-то на ошибки компилятора негативно реагируют, а ведь это "первейший друг", самая главная помощь, которая позволяет решить 90% самостоятельно).

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

Собственно с того момента все "практики" я проводил в режиме "учитель". Бродил по классу и помогал "у кого что не выходит/не понятно".

Хе... вот вспомнил былое... :)  Может потому тут на форуме мне и нравится "терпение тренировать"? ;)

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Ну там они кстати забавно. По инструкции подымаеш виртуальную машину с их линухом (почти голый в командной строке). Там уже все библиотеки, все подлючено. И пишеш код в текстовике, компилиш, запускаешь. Смотриш.

leshak
Offline
Зарегистрирован: 29.09.2011

bit пишет:

1 две функции

Неверно. У вас их 4-ре штуки объявлено. Назовите две которые вы нашли.

bit пишет:

2  int main(int argc, char* argv[])

Еще раз. Сделайте отбивку кода. Внутри main() у вас не объявлено ни одной функции (испльзуются - да, а объвление - в другом месте). Кстати, вы догадываетесь что main() - это тоже функция? Уже хотя-бы поэтому ответом на вопрос "внутри чего они находятся?" ответ "внутри main() - ну никак не может быть верным.

bit пишет:

3 строка 36

Неверно. В строке 36-ть у вас объявляется функция main() , а вопрос был "где они вызываются?"  (кстати "они", фунции, а не только про одну вопрос был).

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

bit пишет:

4 должна выводится чексум

Чексум - это уже "то что вы держите в голове". Я для компилятора существуют понятие "переменная" (у которой дожно быть имя) и "функция" и т.п. Так что же именно выводить Serial.println(CRC);  ? Переменную CRC? Результат функции CRC? Генеральную линию партии? ;)

bit
Offline
Зарегистрирован: 07.05.2012

 1  Я только 3 функции вижу
 

07

void setup()

12

void loop()

54

void CRC (unsigned

 

4 Результат функции CRC

 

На остальные вопросы затрудняюсь ответить
 

 

А можно какой нить код простой чтобы с него начать разбираться? 

bit
Offline
Зарегистрирован: 07.05.2012

 

bit
Offline
Зарегистрирован: 07.05.2012
void setup() {
 
  
  Serial.begin(19200);
}

void loop() {
 Serial.write(62);
 
  Serial.write(1);
   Serial.write(7);
    Serial.write(19);
     Serial.write(83);
      Serial.write(0);
       Serial.write(252);
        Serial.write(20);
         Serial.write(183);  //  Контрольная сумма    100110001    P(x) = x8+ x5+ x4+ x0
 delay(1000);
}

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

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

Да что тут писать-то?  Что толку, даже если за денежку напишут, если вы воспользоваться уже готовым не можете?

Если пытаетесь объявление фунции, в функцию пихать? Если структуру базового скетча ардуины не знаете. Пытается main() сюда вмантулить.

Вот что это: int main(int argc, char* argv[])?

Спросили бы "что такое main" выяснили бы что такое параметры  argc и argv[]. Сразу бы узнали что это "параметры переданные программи из командной строки".... А где у нас в ардуине (или любом микроконтроллере) команданая строка... а в п... нигде. Операционки-то у нас нет. Значит это ЯВНО вообще из другой оперы.

Да, в конце-то концов. За МЕСЯЦ можно-то было разобраться, что функция внутри функции не объявляется? За месяц с нуля, вообще не видя компьютер до этого, уже можно было хотя-бы синтаксические несуразности убрать. Взять любой учебник по C/C++ и хотя-бы объявлять функции и вызывать их научится?

И ведь этого "достаточно" для вашей задачи. В #5 у вас уже "все написано". Нужно только "выбросить лишние". И не пытаться запихнуть багажник автомобиля в телевизор. Нужно,все-таки, телевизор в багажник автомобиля.

 

#include <stdio.h>

    unsigned char CRC_table[256] = {
           0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
           157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
           35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
           190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
           70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
           219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
           101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
           248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
           140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
           17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
           175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
           50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
           202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
           87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
           233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
           116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};




unsigned char our_data[8] = {62,1, 7,19, 122,0, 132,30};

void setup()
 {
  Serial.begin(9600);
 }

void loop()
 {


     unsigned char our_crc, i;

    // вычисляем контрольную сумму
    our_crc = 0;
    CRC(&our_crc, our_data[i]);


    // MUST be 234 (0xEA)
    Serial.println("Calculated CRC:");
    Serial.println(our_crc,DEC); // выводим контрольную в десятичном
    Serial.println(our_crc,HEX); // выводим в шестнадцатеричном
    Serial.println(our_crc,BIN); // вывоидм в двоичном
    
    Serial.println();
    Serial.println();
    Serial.println();
    
    delay(1000); // задержка
}


void CRC (unsigned char *crc, unsigned char data)
{
    *crc = CRC_table[*crc ^ data];
    return;
}

Выводит раз в секунду:

Calculated CRC:
161
A1
10100001

Что вообщем-то немного похоже на ваше "Контрольная сумма    100110001"

Ну, а если учесть, что ваше "100110001" - это 9-ть бит. И выкинуть "один лишний", то будет не "похоже", а "совпадает".

При этом.... мозг "что такое CRC" - я вообще не включал. Взял код который тут висит месяц и выкинул из него "синтаксические несуразности". Просто взял и вызвал функцию которая "уже готова".

bit
Offline
Зарегистрирован: 07.05.2012

 

Спасибо большое за помощь.

 

 

bit
Offline
Зарегистрирован: 07.05.2012

Почему-то код работает не правильно, контрольную сумму расчитыватся только по первому числу 62 и контрол суумма должна быть 234 (0xEA)?

И где тут встовляется полином 100110001  P(x)  = x8+ x5+ x4+ x0 или он тут не нуже, расчёт идёт по таблице?

leshak
Offline
Зарегистрирован: 29.09.2011

Ай, дарагой, отстань.... ну нужна тебе эта 234, а???? Это что, начало номера девушк, да?

#include <stdio.h>

    unsigned char CRC_table[256] = {
           0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
           157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
           35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
           190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
           70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
           219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
           101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
           248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
           140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
           17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
           175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
           50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
           202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
           87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
           233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
           116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53};




unsigned char our_data[8] = {62,1, 7,19, 122,0, 132,30};

void setup()
 {
  Serial.begin(9600);
 }

void loop()
 {


     unsigned char our_crc;

    // вычисляем контрольную сумму
    our_crc = 0;
    for(byte i=0;i<8;i++)CRC(&our_crc, our_data[i]);


    // MUST be 234 (0xEA)
    Serial.println("Calculated CRC:");
    Serial.println(our_crc,DEC); // выводим контрольную в десятичном
    Serial.println(our_crc,HEX); // выводим в шестнадцатеричном
    Serial.println(our_crc,BIN); // вывоидм в двоичном
    
    Serial.println();
    Serial.println();
    Serial.println();
    
    delay(1000); // задержка
}


void CRC (unsigned char *crc, unsigned char data)
{
    *crc = CRC_table[*crc ^ data];
    return;
}

Вывод:

Calculated CRC:
234
EA
11101010

 

bit
Offline
Зарегистрирован: 07.05.2012

Спасибо

maxus
Offline
Зарегистрирован: 18.03.2016

ээээ... в догонку

есть устройства (MPX TOYOTA) посылающие сообщения:

0x67, 0xFE, 0xDF, 0x40, 0x00, 0x00, 0x00, 0x00, 0x36, 0x7E

0x55, 0xFE, 0xE6, 0x20, 0x25, 0x40, 0xE3, 0x7E

0x53, 0xFE, 0x24, 0x00, 0x67, 0x7E

0x64, 0xFE, 0xE4, 0x00, 0x00, 0x28, 0x7E

0x44, 0xFE, 0xAB, 0x62, 0x80, 0x30, 0x7E

0xA4, 0x62, 0xA4, 0xFF, 0x00, 0x19, 0x7E

(4bits) приоритет/(4bits) размер / DST-ID (8bits) / MES-ID (8bits) / DATA (8- 88bits) / CRC (8bits) / EOM (8blts) / 

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

Спасибо.

вопрос решен. 

кому интересно решение тут: habrahabr.ru/company/contactless/blog/216023/