TAEJU HONG / Mbed 2 deprecated Ydlidar_gitlab_version

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
htzer
Date:
Thu Mar 03 06:55:48 2022 +0000
Commit message:
YdlidarX4_gitlab

Changed in this revision

BufferedSerial/Buffer/MyBuffer.cpp Show annotated file Show diff for this revision Revisions of this file
BufferedSerial/Buffer/MyBuffer.h Show annotated file Show diff for this revision Revisions of this file
BufferedSerial/BufferedSerial.cpp Show annotated file Show diff for this revision Revisions of this file
BufferedSerial/BufferedSerial.h Show annotated file Show diff for this revision Revisions of this file
YDLidarX4/YDLidarX4.cpp Show annotated file Show diff for this revision Revisions of this file
YDLidarX4/YDLidarX4.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/Buffer/MyBuffer.cpp	Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,76 @@
+
+/**
+ * @file    Buffer.cpp
+ * @brief   Software Buffer - Templated Ring Buffer for most data types
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+#include "MyBuffer.h"
+
+template <class T>
+MyBuffer<T>::MyBuffer(uint32_t size)
+{
+    _buf = new T [size];
+    _size = size;
+    clear();
+    
+    return;
+}
+
+template <class T>
+MyBuffer<T>::~MyBuffer()
+{
+    delete [] _buf;
+    
+    return;
+}
+
+template <class T>
+uint32_t MyBuffer<T>::getSize() 
+{ 
+    return this->_size; 
+}
+
+template <class T>
+void MyBuffer<T>::clear(void)
+{
+    _wloc = 0;
+    _rloc = 0;
+    memset(_buf, 0, _size);
+    
+    return;
+}
+
+template <class T>
+uint32_t MyBuffer<T>::peek(char c)
+{
+    return 1;
+}
+
+// make the linker aware of some possible types
+template class MyBuffer<uint8_t>;
+template class MyBuffer<int8_t>;
+template class MyBuffer<uint16_t>;
+template class MyBuffer<int16_t>;
+template class MyBuffer<uint32_t>;
+template class MyBuffer<int32_t>;
+template class MyBuffer<uint64_t>;
+template class MyBuffer<int64_t>;
+template class MyBuffer<char>;
+template class MyBuffer<wchar_t>;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/Buffer/MyBuffer.h	Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,163 @@
+
+/**
+ * @file    Buffer.h
+ * @brief   Software Buffer - Templated Ring Buffer for most data types
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+#ifndef MYBUFFER_H
+#define MYBUFFER_H
+
+#include <stdint.h>
+#include <string.h>
+
+/** A templated software ring buffer
+ *
+ * Example:
+ * @code
+ *  #include "mbed.h"
+ *  #include "MyBuffer.h"
+ *
+ *  MyBuffer <char> buf;
+ *
+ *  int main()
+ *  {
+ *      buf = 'a';
+ *      buf.put('b');
+ *      char *head = buf.head();
+ *      puts(head);
+ *
+ *      char whats_in_there[2] = {0};
+ *      int pos = 0;
+ *
+ *      while(buf.available())
+ *      {   
+ *          whats_in_there[pos++] = buf;
+ *      }
+ *      printf("%c %c\n", whats_in_there[0], whats_in_there[1]);
+ *      buf.clear();
+ *      error("done\n\n\n");
+ *  }
+ * @endcode
+ */
+
+template <typename T>
+class MyBuffer
+{
+private:
+    T   *_buf;
+    volatile uint32_t   _wloc;
+    volatile uint32_t   _rloc;
+    uint32_t            _size;
+
+public:
+    /** Create a Buffer and allocate memory for it
+     *  @param size The size of the buffer
+     */
+    MyBuffer(uint32_t size = 0x100);
+    
+    /** Get the size of the ring buffer
+     * @return the size of the ring buffer
+     */
+     uint32_t getSize();
+    
+    /** Destry a Buffer and release it's allocated memory
+     */
+    ~MyBuffer();
+    
+    /** Add a data element into the buffer
+     *  @param data Something to add to the buffer
+     */
+    void put(T data);
+    
+    /** Remove a data element from the buffer
+     *  @return Pull the oldest element from the buffer
+     */
+    T get(void);
+    
+    /** Get the address to the head of the buffer
+     *  @return The address of element 0 in the buffer
+     */
+    T *head(void);
+    
+    /** Reset the buffer to 0. Useful if using head() to parse packeted data
+     */
+    void clear(void);
+    
+    /** Determine if anything is readable in the buffer
+     *  @return 1 if something can be read, 0 otherwise
+     */
+    uint32_t available(void);
+    
+    /** Overloaded operator for writing to the buffer
+     *  @param data Something to put in the buffer
+     *  @return
+     */
+    MyBuffer &operator= (T data)
+    {
+        put(data);
+        return *this;
+    }
+    
+    /** Overloaded operator for reading from the buffer
+     *  @return Pull the oldest element from the buffer 
+     */  
+    operator int(void)
+    {
+        return get();
+    }
+    
+     uint32_t peek(char c);
+    
+};
+
+template <class T>
+inline void MyBuffer<T>::put(T data)
+{
+    _buf[_wloc++] = data;
+    _wloc %= (_size-1);
+    
+    return;
+}
+
+template <class T>
+inline T MyBuffer<T>::get(void)
+{
+    T data_pos = _buf[_rloc++];
+    _rloc %= (_size-1);
+    
+    return data_pos;
+}
+
+template <class T>
+inline T *MyBuffer<T>::head(void)
+{
+    T *data_pos = &_buf[0];
+    
+    return data_pos;
+}
+
+template <class T>
+inline uint32_t MyBuffer<T>::available(void)
+{
+    return (_wloc == _rloc) ? 0 : 1;
+}
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/BufferedSerial.cpp	Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,158 @@
+/**
+ * @file    BufferedSerial.cpp
+ * @brief   Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author  sam grove
+ * @version 1.0
+ * @see
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "BufferedSerial.h"
+#include <stdarg.h>
+
+BufferedSerial::BufferedSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name)
+    : RawSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size))
+{
+    RawSerial::attach(this, &BufferedSerial::rxIrq, Serial::RxIrq);
+    this->_buf_size = buf_size;
+    this->_tx_multiple = tx_multiple;   
+    return;
+}
+
+BufferedSerial::~BufferedSerial(void)
+{
+    RawSerial::attach(NULL, RawSerial::RxIrq);
+    RawSerial::attach(NULL, RawSerial::TxIrq);
+
+    return;
+}
+
+int BufferedSerial::readable(void)
+{
+    return _rxbuf.available();  // note: look if things are in the buffer
+}
+
+int BufferedSerial::writeable(void)
+{
+    return 1;   // buffer allows overwriting by design, always true
+}
+
+int BufferedSerial::getc(void)
+{
+    return _rxbuf;
+}
+
+int BufferedSerial::putc(int c)
+{
+    _txbuf = (char)c;
+    BufferedSerial::prime();
+
+    return c;
+}
+
+int BufferedSerial::puts(const char *s)
+{
+    if (s != NULL) {
+        const char* ptr = s;
+    
+        while(*(ptr) != 0) {
+            _txbuf = *(ptr++);
+        }
+        _txbuf = '\n';  // done per puts definition
+        BufferedSerial::prime();
+    
+        return (ptr - s) + 1;
+    }
+    return 0;
+}
+
+int BufferedSerial::printf(const char* format, ...)
+{
+    char buffer[this->_buf_size];
+    memset(buffer,0,this->_buf_size);
+    int r = 0;
+
+    va_list arg;
+    va_start(arg, format);
+    r = vsprintf(buffer, format, arg);
+    // this may not hit the heap but should alert the user anyways
+    if(r > this->_buf_size) {
+        error("%s %d buffer overwrite (max_buf_size: %d exceeded: %d)!\r\n", __FILE__, __LINE__,this->_buf_size,r);
+        va_end(arg);
+        return 0;
+    }
+    va_end(arg);
+    r = BufferedSerial::write(buffer, r);
+
+    return r;
+}
+
+ssize_t BufferedSerial::write(const void *s, size_t length)
+{
+    if (s != NULL && length > 0) {
+        const char* ptr = (const char*)s;
+        const char* end = ptr + length;
+    
+        while (ptr != end) {
+            _txbuf = *(ptr++);
+        }
+        BufferedSerial::prime();
+    
+        return ptr - (const char*)s;
+    }
+    return 0;
+}
+
+
+void BufferedSerial::rxIrq(void)
+{
+    // read from the peripheral and make sure something is available
+    if(serial_readable(&_serial)) {
+        _rxbuf = serial_getc(&_serial); // if so load them into a buffer
+    }
+
+    return;
+}
+
+void BufferedSerial::txIrq(void)
+{
+    // see if there is room in the hardware fifo and if something is in the software fifo
+    while(serial_writable(&_serial)) {
+        if(_txbuf.available()) {
+            serial_putc(&_serial, (int)_txbuf.get());
+        } else {
+            // disable the TX interrupt when there is nothing left to send
+            RawSerial::attach(NULL, RawSerial::TxIrq);
+            break;
+        }
+    }
+
+    return;
+}
+
+void BufferedSerial::prime(void)
+{
+    // if already busy then the irq will pick this up
+    if(serial_writable(&_serial)) {
+        RawSerial::attach(NULL, RawSerial::TxIrq);    // make sure not to cause contention in the irq
+        BufferedSerial::txIrq();                // only write to hardware in one place
+        RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq);
+    }
+
+    return;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/BufferedSerial/BufferedSerial.h	Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,140 @@
+
+/**
+ * @file    BufferedSerial.h
+ * @brief   Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
+ * @author  sam grove
+ * @version 1.0
+ * @see     
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef BUFFEREDSERIAL_H
+#define BUFFEREDSERIAL_H
+ 
+#include "mbed.h"
+#include "MyBuffer.h"
+
+/** A serial port (UART) for communication with other serial devices
+ *
+ * Can be used for Full Duplex communication, or Simplex by specifying
+ * one pin as NC (Not Connected)
+ *
+ * Example:
+ * @code
+ *  #include "mbed.h"
+ *  #include "BufferedSerial.h"
+ *
+ *  BufferedSerial pc(USBTX, USBRX);
+ *
+ *  int main()
+ *  { 
+ *      while(1)
+ *      {
+ *          Timer s;
+ *        
+ *          s.start();
+ *          pc.printf("Hello World - buffered\n");
+ *          int buffered_time = s.read_us();
+ *          wait(0.1f); // give time for the buffer to empty
+ *        
+ *          s.reset();
+ *          printf("Hello World - blocking\n");
+ *          int polled_time = s.read_us();
+ *          s.stop();
+ *          wait(0.1f); // give time for the buffer to empty
+ *        
+ *          pc.printf("printf buffered took %d us\n", buffered_time);
+ *          pc.printf("printf blocking took %d us\n", polled_time);
+ *          wait(0.5f);
+ *      }
+ *  }
+ * @endcode
+ */
+
+/**
+ *  @class BufferedSerial
+ *  @brief Software buffers and interrupt driven tx and rx for Serial
+ */  
+class BufferedSerial : public RawSerial 
+{
+private:
+    MyBuffer <char> _rxbuf;
+    MyBuffer <char> _txbuf;
+    uint32_t      _buf_size;
+    uint32_t      _tx_multiple;
+ 
+    void rxIrq(void);
+    void txIrq(void);
+    void prime(void);
+    
+public:
+    /** Create a BufferedSerial port, connected to the specified transmit and receive pins
+     *  @param tx Transmit pin
+     *  @param rx Receive pin
+     *  @param buf_size printf() buffer size
+     *  @param tx_multiple amount of max printf() present in the internal ring buffer at one time
+     *  @param name optional name
+     *  @note Either tx or rx may be specified as NC if unused
+     */
+    BufferedSerial(PinName tx, PinName rx, uint32_t buf_size = 256, uint32_t tx_multiple = 4,const char* name=NULL);
+    
+    /** Destroy a BufferedSerial port
+     */
+    virtual ~BufferedSerial(void);
+    
+    /** Check on how many bytes are in the rx buffer
+     *  @return 1 if something exists, 0 otherwise
+     */
+    virtual int readable(void);
+    
+    /** Check to see if the tx buffer has room
+     *  @return 1 always has room and can overwrite previous content if too small / slow
+     */
+    virtual int writeable(void);
+    
+    /** Get a single byte from the BufferedSerial Port.
+     *  Should check readable() before calling this.
+     *  @return A byte that came in on the Serial Port
+     */
+    virtual int getc(void);
+    
+    /** Write a single byte to the BufferedSerial Port.
+     *  @param c The byte to write to the Serial Port
+     *  @return The byte that was written to the Serial Port Buffer
+     */
+    virtual int putc(int c);
+    
+    /** Write a string to the BufferedSerial Port. Must be NULL terminated
+     *  @param s The string to write to the Serial Port
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual int puts(const char *s);
+    
+    /** Write a formatted string to the BufferedSerial Port.
+     *  @param format The string + format specifiers to write to the Serial Port
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual int printf(const char* format, ...);
+    
+    /** Write data to the Buffered Serial Port
+     *  @param s A pointer to data to send
+     *  @param length The amount of data being pointed to
+     *  @return The number of bytes written to the Serial Port Buffer
+     */
+    virtual ssize_t write(const void *s, std::size_t length);
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/YDLidarX4/YDLidarX4.cpp	Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,123 @@
+#include "YDLidarX4.h"
+#include "mbed.h"
+
+
+YDLidarX4::YDLidarX4(PinName tx, PinName rx, PinName m_en, PinName ctl) : _lidar(tx, rx, 1024), _m_en(m_en), _m_ctl(ctl) {
+    _lidar.baud(LIDAR_BAUD);
+    _m_en = 1;
+    //M_EN가 high level이면 M_SCTR의 input voltage는 0V이며, 모터는 최대속도로 회전
+    _m_ctl.period(0.0001);
+    _m_ctl.write(0.85);
+    // PWM 주기는 10KHz, Duty cycle은 85%로 설정
+    softReset();
+}
+
+void YDLidarX4::softReset() {
+    sendCommand(CMD_RESET);
+    wait(0.1);
+    flush();
+    // 버퍼가 있는 스트림은 flush로 데이터를 목적지에 바로 보낸다.
+}
+
+
+void YDLidarX4::stopplease(){
+    sendCommand(0x65);
+    }
+/*
+
+감지모드 >> 이 명령어만 들어가면 먹통됨
+현재 코드가 막히고 있는 부분.
+
+>>해결
+
+*/
+int YDLidarX4::startSampling() {
+    softReset();
+    // 감지하기 전에 리셋한번 하고 들어간다
+    responseHeader header;
+    sendCommand(CMD_START);
+    getResponseHeader(&header);
+    return header.type == RESPONSE_HEADER_TYPE_START ? 1 : 0;
+}
+
+
+// 정지명령, 명령이 들어가긴 하지만 라이다가 멈추진 않음**샘플링만 멈춘다.
+
+// >> 해결
+void YDLidarX4::stopSampling() {
+    sendCommand(CMD_STOP);
+}
+
+void YDLidarX4::getResponseHeader(responseHeader* header) {
+    uint8_t *headerBuffer = (uint8_t*)(header);
+    uint8_t currentByte;
+    uint8_t receivePosition = 0;
+    while (receivePosition < sizeof(responseHeader)) {
+        if (_lidar.readable()) {
+            currentByte = _lidar.getc();
+            switch (receivePosition) {
+                case 0:
+                    if (currentByte != RESPONSE_HEADER_BYTE_1) {
+                        continue;
+                    }
+                    break;
+                case 1:
+                    if (currentByte != RESPONSE_HEADER_BYTE_2) {
+                        receivePosition = 0;
+                        continue;
+                    }
+                    break;
+            }
+            headerBuffer[receivePosition++] = currentByte;
+        }
+    }
+}
+
+void YDLidarX4::getCloudHeader(cloudHeader* header) {
+    flush();
+    uint8_t *headerBuffer = (uint8_t*)(header);
+    uint8_t currentByte;
+    uint8_t receivePosition = 0;
+    while (receivePosition < sizeof(cloudHeader)) {
+        if (_lidar.readable()) {
+            currentByte = _lidar.getc();
+            switch (receivePosition) {
+                case 0:
+                    if (currentByte != CLOUD_HEADER_BYTE_1) {
+                        receivePosition = 0;
+                        continue;
+                    }
+                    break;
+                case 1:
+                    if (currentByte != CLOUD_HEADER_BYTE_2) {
+                        receivePosition = 0;
+                        continue;
+                    }
+                    break;
+            }
+            headerBuffer[receivePosition++] = currentByte;
+        }
+    }
+}
+
+void YDLidarX4::getCloudSamples(uint16_t* tab, uint8_t size) {
+    uint8_t *tabBuffer = (uint8_t*)(tab);
+    uint8_t receivePosition = 0;
+    while (receivePosition < size * sizeof(uint16_t)) {
+        if (_lidar.readable()) {
+            tabBuffer[receivePosition++] = _lidar.getc();
+        }
+    }
+}
+
+
+void YDLidarX4::sendCommand(uint8_t com) {
+    _lidar.putc(START_BYTE);
+    _lidar.putc(com);
+}
+
+void YDLidarX4::flush() {
+    while(_lidar.readable()) {
+        _lidar.getc();
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/YDLidarX4/YDLidarX4.h	Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,85 @@
+#ifndef YDLIDARX4_H
+#define YDLIDARX4_H
+
+#include "BufferedSerial.h"
+#include "mbed.h"
+
+#define LIDAR_BAUD 128000
+
+#define RESPONSE_HEADER_BYTE_1 0xA5
+#define RESPONSE_HEADER_BYTE_2 0x5A
+#define RESPONSE_HEADER_TYPE_START 0x81
+// Scan Command
+
+#define CLOUD_HEADER_BYTE_1 0xAA
+#define CLOUD_HEADER_BYTE_2 0x55
+// 2B in length, fixed at 0x55AA, low in front, high in back
+
+#define START_BYTE 0xA5
+#define CMD_START 0x60
+#define CMD_STOP 0x65
+#define CMD_RESET 0x80
+#define CMD_HEALTH 0x91
+// System Command
+
+struct responseHeader {
+    //응답 관련 헤더
+    uint8_t startByte1;
+    uint8_t startByte2;
+    //start sign, 16비트인데 2개로 나눠놓은듯 
+    uint32_t length:30;
+    //length 30비트
+    uint32_t mode:2;
+    //mode 2비트
+    uint8_t type;
+    //타입코드, 개발자메뉴얼에 8비트라 명시
+} __attribute__((packed));
+
+
+struct cloudHeader {
+    //패킷
+    uint16_t ph;
+    // 패킷헤더
+    uint8_t ct;
+    // 패키지 타입
+    uint8_t lsn;
+    // 수신 정보량
+    uint16_t fsa;
+    // first
+    uint16_t lsa;
+    // last
+    uint16_t cs;
+    // check sum
+} __attribute__((packed));
+
+
+class YDLidarX4 {
+
+public:
+
+    YDLidarX4(PinName tx, PinName rx, PinName m_en, PinName ctl);
+
+    void stopplease();
+    //좀 멈추게 만들어본거
+    void softReset();
+    int startSampling();
+    void stopSampling();
+    // 단순명령어들, 따로 입력값이 없다.
+    
+    void setRotationSpeed(float speed);
+    void getResponseHeader(responseHeader* header);
+    void getCloudHeader(cloudHeader* header);
+    void getCloudSamples(uint16_t* tab, uint8_t size);
+
+private :
+
+    void sendCommand(uint8_t com);
+    void flush();
+
+    BufferedSerial _lidar;
+    DigitalOut _m_en;
+    PwmOut _m_ctl;
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,217 @@
+#include "mbed.h"
+#include "BufferedSerial.h"
+#include "YDLidarX4.h"
+
+#define PC_TX USBTX
+#define PC_RX USBRX
+#define PC_BAUD 115200
+
+#define LIDAR_TX PA_9
+#define LIDAR_RX PA_10
+#define LIDAR_M_EN PB_5
+#define LIDAR_M_PWN PB_4
+#define LIDAR_DEV_EN PA_11
+
+#define ALPHA 0.70
+#define BETA 0.85
+//각도/거리보정 계수
+
+BufferedSerial pc(PC_TX, PC_RX, 512);
+YDLidarX4 lidar(LIDAR_TX, LIDAR_RX, LIDAR_M_EN, LIDAR_M_PWN);
+
+uint16_t samples[128];
+uint16_t trend[360];
+uint16_t datas[360];
+//samples와 trend는 각도보정에 쓰이는 거리값, datas는 sample과 trend에 의해 보정된 거리값
+
+bool isSampling = false;
+/*샘플링되었는가?*/
+
+void processInput() {
+    // Si il y a un message sur le port série
+    // 직렬포트에 메세지가 있는 경우
+    // pc로부터 명령어 받았을때 상황
+    if (pc.readable()) {
+        switch(pc.getc()) {
+            //메세지의 종류에 따른 분류
+            //여기까지 작동 확인
+            case 'G': { // Derniers points relevés
+            //최종점수? 아무튼 pc로부터 받은 값이 'G'일때
+                uint32_t sum = 0;
+                uint8_t sum_counter = 0;
+                uint8_t counter = 0;
+                uint8_t degree = 0;
+                //값들 초기화
+                
+                // On envoit sur le port série la moyenne tous les 10 degrés
+                // 10도마다 직렬포트로 평균치를 보낸다.
+                for (uint16_t index = 0; index < 360; index++) {
+                    // 이 if문은 datas 배열의 index에 해당하는 값을 sum 변수에 더한다.
+                    if (datas[359 - index] != 0) {
+                        //datas라는 배열의 우측 데이터부터 0이 아니라면
+                        sum += datas[359 - index];
+                        //sum이라는 변수는 datas 배열의 index에 해당하는 데이터를 더한다.
+                        sum_counter += 1;
+                        //sum이 몇번 더해졌는지 판별하기 위한 index?
+                    }
+                    if (++counter == 1) {
+                        //***************************************************************************평균치 개수 여기서 조절
+                        pc.printf("%d:", sum / sum_counter);
+                        counter = 0;
+                        sum = 0;
+                        sum_counter = 0;
+                        // counter가 10이면 sum을 10으로 나눈 평균치를 출력하고 모든 변수값 초기화.
+                        // 0~9 평균 출력 및 초기화, 10~11 평균 출력 및 초기화,....
+                        // counter == x 값 변경
+                    }
+                }
+                pc.printf("\n");
+                break;
+            };
+            case 'I': { // Information d'identification
+            // 'I'일 경우 식별정보 pc로 출력. 아마 기기정보인듯
+            // 근데 아무 명령어가 없다?
+                pc.printf("CarteLidar\n");
+                break;
+            };
+            case 'R': { // soft reset du LIDAR
+            // 'R'일 경우 Lidar의 소프트 리셋
+                lidar.softReset();
+                pc.printf("softReset\n");
+                break;
+            };
+            case 'E': { // Démarrer le ranging
+            /*
+            
+            ***************************************************************************'E' 입력시 감지 시작
+            isSampling을 True로 만들어주는게 끝이긴 하다
+            
+            */
+            pc.printf("entering E ok\n");
+                if (lidar.startSampling()) {
+                    isSampling = true;
+                    //샘플링 시작 선언
+                    pc.printf("1\n");
+                } else {
+                    pc.printf("0\n");
+                }
+                break;
+            };
+            case 'D': { // Arrêter le ranging
+            //'D'입력시 감지 중지
+                lidar.stopSampling();
+                isSampling = false;
+                pc.printf("sampling stop\n");
+                break;
+                
+            case 'O':{
+                lidar.stopplease();
+                pc.printf("stop ok\n");
+                break;
+                }
+            };
+            case 'S': { // Savoir si le lidar est entrain de fonctionner ou non
+            //'S'입력시 LIdar가 작동중인지 여부 확인.
+            //isSampling 변수를 통해 확인한다.
+                pc.printf(isSampling ? "State Sampling\n" : "State Stop\n");
+            }
+        }
+    }
+}
+
+void format_samples(uint8_t size) {
+    // Formate les distances obtenues suivant les indications du datasheet
+    //데이터시트 지시사항에 따라 얻은 거리를 측정한다
+    for (uint8_t index = 0; index < size; index++) {
+        samples[index] = samples[index] / 4.0;
+    }
+}
+
+double get_angle_correct(double distance) {
+    // Calcule la correction de l'angle suivant les indications du datasheet
+    //데이터시트 지시사항에 따라 얻은 각도보정
+    return distance == 0 ? 0 : atan(21.8 * (155.3 - distance) / (155.3 * distance)) * 57.2957795147;
+}
+
+uint16_t get_angle_formated(int16_t angle) {
+    // Permet d'obtenir un angle module 360
+    // 각도가 0도 미만 또는 360도 이상일때 보정
+    return angle < 0 ? angle + 360 : angle > 360 ? angle - 360 : angle;
+}
+
+int main() {
+    // Initialisation des communications UART
+    //UART 통신 초기화
+    pc.baud(PC_BAUD);
+    
+    int angle;
+    int s;
+    int index;
+    
+
+
+    // Boucle infinie
+    // 반복문
+    
+    while (true) {
+        // Si le ranging est actif, on lit le prochain paquet
+        // 감지가 활성화된 경우 다음 패킷을 읽는다
+        if (isSampling) {
+            // 이 반복문은 isSampling이 활성화된 경우, 즉 감지 명령어 'E'가 들어온 경우에만 실행된다
+            cloudHeader header;
+            /*
+    
+            pc.printf("cloudHeader\n");
+            
+            */
+            // Récupération du paquet de points actuel
+            // 현재 포인트 패킷 복구
+            lidar.getCloudHeader(&header);
+            /*
+            
+            pc.printf("getCloudHeader\n");
+        
+            */
+            lidar.getCloudSamples(samples, header.lsn);
+            /*
+            
+            pc.printf("getCloudSample\n");
+            
+            */
+            // Si il y a au moins un point échantilloné
+            // 하나 이상의 샘플링 지점이 있는 경우
+            if (header.lsn > 1) {
+                // Formatage préliminaire des points
+                // 점의 예비 포맷
+                format_samples(header.lsn);
+                // Calcul des angles initiaux et finaux du paquet
+                //패킷의 초기 및 최종 각도 계산
+                double fsa = ((double)(header.fsa >> 1) / 64.0) + get_angle_correct(samples[0]);
+                double lsa = ((double)(header.lsa >> 1) / 64.0) + get_angle_correct(samples[header.lsn - 1]);
+                double dif = fsa < lsa ? (lsa - fsa) / ((double)header.lsn - 1.0) : (360.0 + lsa - fsa) / ((double)header.lsn - 1.0);
+                // Iteration sur chaque point du paquet
+                for (index = 0; index < header.lsn; index++) {
+                    // Si la distance mesurée est positive
+                    // 측정된 거리가 양수인 경우
+                    if (samples[index] != 0) {
+                        // Détermination de l'angle pour le point courant
+                        //현재 지점에 대한 각도 결정
+                        angle = get_angle_formated(((dif * (double)(index)) + fsa + get_angle_correct(samples[index])));
+                        // Lissage à double exponentielle de la mesure
+                        // 이중 지수 측정 평활화
+                        s = ALPHA * (double)samples[index] + (1.0 - ALPHA) * ((double)datas[angle] + (double)trend[angle]);
+                        trend[angle] = BETA * ((double)s - (double)datas[angle]) + (1.0 - BETA) * (double)trend[angle];
+                        // Stockage du résultat
+                        // 결과 저장
+                        datas[angle] = s;
+                    }
+                }
+            }
+        }
+        // On exécute les commandes reçues
+        // 수신된 명령을 실행
+        // comportMaster에서 내가 보낸 명령어는 while문 맨 끝에서 받게된다.
+        // while문의 코드는 감지명령이 있을때만 실행되는데 감지명령만 들어가면 먹통되는걸 보면 while문을 빠져나오지 못하는걸로 예상
+        processInput();
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Thu Mar 03 06:55:48 2022 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file