Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MX12.cpp
- Committer:
- denis2nis
- Date:
- 2021-11-03
- Revision:
- 0:7556356a8bcd
- Child:
- 2:02f3323a107d
File content as of revision 0:7556356a8bcd:
#include "MX12.h" MX12::MX12(PinName tx, PinName rx, int baud) : _mx12(tx, rx) { _baud = baud; _mx12.baud(_baud); _mx12.format(8, SerialBase::None, 1); _mx12.attach(callback(this, &MX12::_ReadCallback), SerialBase::RxIrq); _state = State::Available; } void MX12::SetSpeed(unsigned char mot_id, float speed) { char data[2]; // Speed absolute value int goal = (0x3ff * abs(speed)); // Spin direction (CW is negative) if (speed < 0) { goal |= (0x1 << 10); } data[0] = goal & 0xff; data[1] = goal >> 8; // Enter writing state _state = State::Writing; // Send instruction rw(mot_id, 0x20, 2, data); } char MX12::IsAvailable(void) { return _state == State::Available; } void MX12::ReadPosition(unsigned char mot_id) { // Make a request, interrupt takes care of everything else _state = State::ReadingPosition; rw(mot_id, 0x24, 2, NULL); } float MX12::GetPosition(unsigned char mot_id) { return _angle[mot_id]; } MX12::Status MX12::GetStatus(void) { return _status; } // Debug function to print Serial read void MX12::PrintAnswer() { for(char i = 0; i < MX12_ANSWER_MAX_SIZE; i++) { printf("%x ", _res[i]); } printf("\r\n"); } void MX12::rw(unsigned char mot_id, char adress, char len, char *data) { _res_count = 0; memset(_res, 0, MX12_ANSWER_MAX_SIZE); // Forge packet char cmd[16]; cmd[0] = 0xff; cmd[1] = 0xff; cmd[4] = 0x02 + (data != NULL); cmd[2] = mot_id; if(data == NULL) cmd[3] = 4; else cmd[3] = 3 + len; cmd[5] = adress; // Compute checksum if(data == NULL) { cmd[6] = len; cmd[7] = 0xFF - (mot_id + 4 + 2 + adress + len); // [XXX] Force length to one to force send len = 1; } else { char cs = mot_id + len + adress + 6; for(char i = 0; i < len; i++) { cmd[6 + i] = data[i]; cs += data[i]; } cmd[6 + len] = 0xFF - cs; } // Send packet if(mot_id != 0xFE) { for(char i = 0; i < (7 + len); i++) { _mx12.write(&cmd[i], 1); } } } void MX12::_ReadCallback() { char c; // Loop on reading serial if(_mx12.read(&c, 1)) { _res[_res_count] = c; _res_count++; if(_res_count >= MX12_ANSWER_MAX_SIZE) _res_count = 0; // Find answer in buffer char ans_i = 2; for(; (_res[ans_i] != 0xFF) && (ans_i <= MX12_ANSWER_MAX_SIZE - 1); ans_i++); if(ans_i >= MX12_ANSWER_MAX_SIZE) return; ans_i += 2; char mot_id = _res[ans_i++]; char len = _res[ans_i++]; _chksm = _res[ans_i + len - 1]; // [TODO] Verify checksum if(len != 0 && _chksm != 0) { // Interpret answer depending on state switch(_state) { case State::ReadingPosition: _angle[mot_id] = (((uint16_t) _res[ans_i + 1] << 8) | (uint16_t) _res[ans_i]) * 0.088; _state = State::Available; break; case State::Writing: // Return the corresponding status code switch(_res[ans_i]) { case 0: _status = Status::Ok; break; case 1 << 0: _status = Status::InputVoltageError; break; case 1 << 1: _status = Status::AngleLimitError; break; case 1 << 2: _status = Status::OverheatingError; break; case 1 << 3: _status = Status::RangeError; break; case 1 << 4: _status = Status::ChecksumError; break; case 1 << 5: _status = Status::OverloadError; break; case 1 << 6: _status = Status::InstructionError; break; default: _status = Status::Unknown; } _state = State::Available; break; default: _status = Status::Unknown; } } } }