Changeset 17623 for trunk/FACT++


Ignore:
Timestamp:
03/18/14 15:49:33 (11 years ago)
Author:
dneise
Message:
adapted for new firmware version

no ASCII parsing needed, so this was removed. 
FSC sends now fixed length messages, so messages are processed as soon as a certain number of bytes is received.
No command needs to be sent to start the reporting.
While processing the messages, two checksums are computed and compaired against the received data.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/fscctrl.cc

    r17395 r17623  
    2828class ConnectionFSC : public Connection
    2929{
    30     boost::asio::streambuf fBuffer;
     30    boost::array<unsigned char, 4096> fArray;
     31    vector<unsigned char> input_buffer;
     32    boost::array<unsigned char, sizeof(FSC::BinaryOutput_t)> one_message;
    3133
    3234    bool fIsVerbose;
     
    4446    }
    4547
    46     virtual void UpdateHum(float, const vector<float>&)
    47     {
    48     }
    49 
    50     virtual void UpdateVolt(float, const vector<float>&)
    51     {
    52     }
    53 
    54     virtual void UpdateCur(float, const vector<float>&)
     48    virtual void UpdateHum(float, const vector<float>&) 
     49    {
     50    }
     51
     52    virtual void UpdateVolt(float, const vector<float>&) 
     53    {
     54    }
     55
     56    virtual void UpdateCur(float, const vector<float>&) 
    5557    {
    5658    }
     
    6971*/
    7072
    71     void Dump(const string &str)
    72     {
    73         if (!fDumpStream.is_open())
    74         {
    75             fDumpStream.open("socket_dump-fsc.txt", ios::app);
    76             if (!fDumpStream)
     73    void Dump(const string &str) 
     74    {
     75        if (!fDumpStream.is_open())
     76        {
     77            fDumpStream.open("socket_dump-fsc.txt", ios::app);
     78            if (!fDumpStream) 
    7779            {
    7880                //ostringstream str;
     
    9193    // From: http://de.wikipedia.org/wiki/Pt100
    9294    //
    93     double GetTempPT1000(double R) const
     95    double GetTempPT1000(double R) const 
    9496    {
    9597        // This is precise within the range 5degC and 25degC
     
    105107    }
    106108
    107 
    108     void HandleReceivedData(const bs::error_code& err, size_t bytes_received, int /*type*/)
    109     {
    110         // Do not schedule a new read if the connection failed.
    111         if (bytes_received==0 || err)
    112         {
    113             if (err==ba::error::eof)
    114                 Warn("Connection closed by remote host (FSC).");
    115 
    116             // 107: Transport endpoint is not connected (bs::error_code(107, bs::system_category))
    117             // 125: Operation canceled
    118             if (err && err!=ba::error::eof &&                     // Connection closed by remote host
    119                 err!=ba::error::basic_errors::not_connected &&    // Connection closed by remote host
    120                 err!=ba::error::basic_errors::operation_aborted)  // Connection closed by us
    121             {
    122                 ostringstream str;
    123                 str << "Reading from " << URL() << ": " << err.message() << " (" << err << ")";// << endl;
    124                 Error(str);
    125             }
    126             PostClose(err!=ba::error::basic_errors::operation_aborted);
    127             return;
    128         }
    129 
    130         if (fIsVerbose)
    131            Out() << kBold << "Received (" << bytes_received << " bytes):" << endl;
    132 
    133         /*
    134          "status: 00000538 \n"
    135          "time_s: 764.755 \n"
    136          "VOLTAGES \n"
    137          " \n"
    138          "enable:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111  00001111 \n"
    139          "  done:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111  00001111 \n"
    140          "values:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 \n"
    141          "RESISTANCES \n"
    142          " \n"
    143          "enable:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 \n"
    144          "  done:11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 \n"
    145          "values: \n"
    146          "1000.16 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
    147          "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
    148          "1197.07 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
    149          " 558.59  677.92  817.26  989.39 1200.35 1503.06 1799.90 2204.18 \n"
    150          "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
    151          "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
    152          "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
    153          "3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 3199.99 \n"
    154          "end.\n";
    155          */
    156 /*
    157         const unsigned int TIME_OFF = 3;
    158         const unsigned int VOLT_OFF = 30;
    159         const unsigned int CURR_OFF = 70;
    160         const unsigned int HUMI_OFF = 110;
    161         const unsigned int TEMP_OFF = 134;
    162         */
    163 
    164         if (fDump)
    165         {
    166             ostringstream msg;
    167             msg << "--- " << Time().GetAsStr() << " --- received " << bytes_received << " bytes.";
    168             Dump(msg.str());
    169         }
    170 
    171 
    172         istream is(&fBuffer);
    173 
    174         int state = 0;
    175         bool values = false;
    176 
    177         vector<int>   volt;
    178         vector<float> resist;
    179 //        int status=-1;
    180         float time=0;
    181 
    182         string buffer;
    183         while (getline(is, buffer, '\n'))
    184         {
    185             if (fIsVerbose)
    186                 Out() << buffer << endl;
    187             if (fDump)
    188                 Dump(buffer);
    189 
    190             buffer = Tools::Trim(buffer);
    191 
    192             if (buffer.empty())
    193                 continue;
    194 
    195             if (buffer.substr(0, 4)=="end.")
    196                 break;
    197 
    198             if (buffer.substr(0, 8)=="status: ")
    199             {
    200 //                status = stoi(buffer.substr(8));
    201                 continue;
    202             }
    203 
    204             if (buffer.substr(0, 8)=="time_s: ")
    205             {
    206                 time = stof(buffer.substr(8));
    207                 continue;
    208             }
    209 
    210             if (buffer.substr(0, 8)=="VOLTAGES")
    211             {
    212                 state = 1;
    213                 continue;
    214             }
    215 
    216             if (buffer.substr(0, 11)=="RESISTANCES")
    217             {
    218                 state = 2;
    219                 continue;
    220             }
    221 
    222             if (state==1 && buffer.substr(0, 7)=="values:")
    223             {
    224                 istringstream in(buffer.substr(7));
    225                 while (1)
    226                 {
    227                     int v;
    228                     in >> v;
    229                     if (!in)
    230                         break;
    231 
    232                     volt.push_back(v);
    233                 }
    234                 continue;
    235             }
    236 
    237             if (state==2 && buffer.substr(0, 7)=="values:")
    238             {
    239                 values = true;
    240                 continue;
    241             }
    242 
    243             if (state==2 && !values)
    244                 continue;
    245 
    246             istringstream in(buffer);
    247             while (1)
    248             {
    249                 float f;
    250                 in >> f;
    251                 if (!in)
    252                     break;
    253 
    254                 resist.push_back(f);
    255             }
    256         }
    257 
    258         if (volt.size()!=84 || resist.size()!=64)
    259         {
     109    uint16_t fletcher16( uint8_t const *data, size_t bytes )
     110    {
     111        uint16_t sum1 = 0xff, sum2 = 0xff;
     112
     113        while (bytes)
     114        {
     115            size_t tlen = bytes > 20 ? 20 : bytes;
     116            bytes -= tlen;
     117            do {
     118                    sum2 += sum1 += *data++;
     119            } while (--tlen);
     120            sum1 = (sum1 & 0xff) + (sum1 >> 8);
     121            sum2 = (sum2 & 0xff) + (sum2 >> 8);
     122        }
     123        /* Second reduction step to reduce sums to 8 bits */
     124        sum1 = (sum1 & 0xff) + (sum1 >> 8);
     125        sum2 = (sum2 & 0xff) + (sum2 >> 8);
     126        return sum2 << 8 | sum1;
     127    }
     128   
     129    /* ProcessMessage is only called from HandleRead, when enough bytes were received from the FSC
     130     * The bytes of one message were already stored in *one_message*.
     131     * We convert it to an instance of FSC::BinaryOutput_t
     132     * then we check the two checksums
     133     * and then update the DimServices or not depending on the checksums
     134     */
     135    void ProcessMessage() {
     136
     137        FSC::BinaryOutput_t* bin_out;
     138        bin_out = (FSC::BinaryOutput_t*)one_message.data();
     139       
     140        if (fIsVerbose) {
     141           Out() << "Received one_message of FSC::BinaryOutput_t ... will now process it" << endl;
     142        }
     143       
     144       
     145        uint16_t volt_checksum = fletcher16( (uint8_t const *)&one_message[offsetof(FSC::BinaryOutput_t,adc_values)],
     146                                                sizeof(bin_out->adc_values) );
     147        if (volt_checksum != bin_out->adc_values_checksum ){
    260148            ostringstream out;
    261 
    262             out << "Corrupted data received (" << volt.size() << " voltages and ";
     149            out << "volt checksums are different. We calculated " << volt_checksum << " transmitted was: ";
     150            out << bin_out->adc_values_checksum << ".";
     151            Warn(out);
     152            StartRead();
     153            return;
     154        }
     155       
     156        uint16_t resist_checksum = fletcher16( (uint8_t const *)&one_message[offsetof(FSC::BinaryOutput_t,ad7719_values)],
     157                                                sizeof(bin_out->ad7719_values) );
     158        if (resist_checksum != bin_out->ad7719_values_checksum ){
     159            ostringstream out;
     160            out << "resist checksums are different. We calculated " << resist_checksum << " transmitted was: ";
     161            out << bin_out->ad7719_values_checksum << ".";
     162            Warn(out);
     163            StartRead();
     164            return;
     165        }
     166
     167        vector<int> volt (bin_out->adc_values,
     168                            bin_out->adc_values + sizeof(bin_out->adc_values) / sizeof(uint16_t)
     169                          );
     170                         
     171        vector<float> resist(bin_out->ad7719_values,
     172                            bin_out->ad7719_values + sizeof(bin_out->ad7719_values) / sizeof(uint32_t)
     173                          );
     174        float time= float(bin_out->time_sec) + float(bin_out->time_ms)/1000.;
     175
     176        if (volt.size()!=84 || resist.size()!=64) {
     177            ostringstream out;
     178
     179            out << "Something went wrong in vector constructors " << volt.size() << " voltages and ";
    263180            out << resist.size() << " resistances received; 84 and 64 expected)";
    264181            Warn(out);
     
    266183            return;
    267184        }
     185       
     186        // We want to convert the pure ADC values from the FSC board to mV and kOhm respectively
     187        // So we do:
     188        for (unsigned int i=0; i<volt.size(); i++){
     189            volt[i] /= 10;
     190        }
     191        for (unsigned int i=0; i<resist.size(); i++){
     192            resist[i] *= (6.25 * 1024) / (1 << 25);
     193        }
     194       
    268195
    269196        int mapv[] =
     
    560487        UpdateCur( time, currents);
    561488        UpdateHum( time, humidities);
     489       
     490    }
     491
     492    void StartRead() {
     493        // DN: 20140318
     494        async_read_some(ba::buffer(fArray),
     495                            boost::bind(&ConnectionFSC::HandleRead, this,     
     496                            dummy::error,
     497                            dummy::bytes_transferred)
     498                        );
     499       
     500        // FIXME: Add timeout here
     501    }
     502   
     503    void HandleRead(const boost::system::error_code& err, size_t bytes_received) {
     504        // Do not schedule a new read if the connection failed.
     505        if (bytes_received==0 || err)
     506        {
     507            if (err==ba::error::eof)
     508            {
     509                return;
     510            }
     511
     512            // 107: Transport endpoint is not connected (bs::error_code(107, bs::system_category))
     513            // 125: Operation canceled
     514            if (err && err!=ba::error::eof &&                     // Connection closed by remote host
     515                err!=ba::error::basic_errors::not_connected &&    // Connection closed by remote host
     516                err!=ba::error::basic_errors::operation_aborted)  // Connection closed by us
     517            {
     518                ostringstream str;
     519                str << "Reading from " << URL() << ": " << err.message() << " (" << err << ")";// << endl;
     520                Error(str);
     521            }
     522            PostClose(err!=ba::error::basic_errors::operation_aborted);
     523            return;
     524        }
     525       
     526        input_buffer.insert(input_buffer.end(), fArray.data(), fArray.data()+bytes_received);
     527        if (input_buffer.size() >= sizeof(FSC::BinaryOutput_t)){
     528            for (unsigned int i=0; i<sizeof(FSC::BinaryOutput_t); i++){
     529                one_message[i] = input_buffer[i];
     530            }
     531            input_buffer.erase(input_buffer.begin(),input_buffer.begin()+sizeof(FSC::BinaryOutput_t));
     532            ProcessMessage();
     533        }
    562534
    563535        StartRead();
    564536    }
    565537
    566     void StartRead()
    567     {
    568         ba::async_read_until(*this, fBuffer, "end.\n",
    569                              boost::bind(&ConnectionFSC::HandleReceivedData, this,
    570                                          dummy::error, dummy::bytes_transferred, 0));
    571 
    572         // FIXME: Add timeout here
    573     }
    574 
    575     // This is called when a connection was established
    576     void ConnectionEstablished()
    577     {
    578         PostMessage("m", 1);
    579 
    580         fBuffer.prepare(10000);
     538    void ConnectionEstablished() {
    581539        StartRead();
    582540    }
Note: See TracChangeset for help on using the changeset viewer.