Здравствуйте люди добрые! К вас я с такой проблемой. Имеется у меня проект на юнити. И имеется Arduino. С компа я передаю на Arduino число (а точнее 6 чисел). Которое представляет собой угол, в который надо установить сервомотор. Так вот, все вроде бы не плохо работает. Но после того как число превышает 127 (я использую тип char, число передается одним байтом.) Серво встает в 0 градусов. Я решил что это из за того что число 128 Arduino воспринимает как -128. (то есть signed char, 127 это 0111 1111, а 128: 1000 0000. Первый бит отвечает за знак числа) пробовал следующим образом: Servo.write((unsigned int)Serial.read()). не помогает. Пробовал сравнивать полученное число с нулем. и если оно меньше нуля, то прибавлять к нему 255: Код (Text): int GetAngel(){ unsigned int angel = Serial.read(); if(angel < 0) angel += 255; return angel; } не помогло. Я С++ толком не знаю. Может кто подскажет?
Метод read в классе Serial определен так: Код (Text): int read(void); Метод write() в классе Servo так: Код (Text): // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds void write(int value); Комментарий означает следующее: если угол меньше 200 градусов, он трактуется как угол. Иначе - как ширина импульса в микросекундах Однако в вашем коде есть пара проблем: Результат Serial.read() приводится к unsigned int Соответственно условие (angel < 0) всегда ложно Рекомендую вам понять, что приходит от передающей стороны. Например так: Код (Text): int GetAngel(){ int angel = Serial.read(); Serial.println(angel, DEC); if(angel < 0) angel += 255; return angel; }
О как. Всегда думал что servo.write(). Принимает угол. Syntax servo.write(angle) Parameters servo: a variable of type Servo angle: the value to write to the servo, from 0 to 180 Код (Text): void Servo::write(int value) { if(value < MIN_PULSE_WIDTH) { // treat values less than 544 as angles in degrees (valid values in microseconds are handled as microseconds) if(value < 0) value = 0; if(value > 180) value = 180; value = map(value, 0, 180, SERVO_MIN(), SERVO_MAX()); } this->writeMicroseconds(value); } То есть если значение больше чем 544, то значение трактуется как ширина импульса в микросекундах. Если меньше, то как угол. По идее, все должно быть правильно. Кстати да. Код (Text): int GetAngel(){ unsigned int angel = Serial.read(); if(angel < 0) angel += 255; return angel; } unsigned int по началу не было. Я добавил его потом, от отчаяния. С чтением данных от Arduino могут возникнуть проблемы. Если посылать с терминала. То как послать нужную цифру, Alt+цифра? Вроде бы так. Число 127 интерпретируется как 63, 128 интерпретируется как 192. 129 как 193.
Давайте определимся с терминами. 127 - число 1, 2 и 7 - цифры. Если введете в консоли терминала число 127 и нажмете Enter, то будут отправлены как минимум 3 байта: - со значением 49 (цифра 1) - со значением 50 (цифра 2) - со значением 55 (цифра 7) Чтобы передать однобайтовое число в Ардуино и принять его там как однобайтовое без знака, вам нужно послать символ с кодом, равным этому числу. Например, отправленный в сторону Ардуино символ с кодом 176 прилетит в Ардуино и функция Serial.read() вернет вам 176 Чтобы передать число в human-readable формате, вам нужно на стороне Ардуино написать парсер. Отправляете строку "176", на стороне Ардуино парсите полученную строку байт функцией scanf
Подойдет, но некоторые символы (например, с кодом 0) отображаться не будут. Для отображаемых символов точно работает.
Фух, косяк я обнаружил. Был он не в Arduino, а в Unity. А точнее в моем коде. Делал я следующим образом: Код (Text): string OutputData = ""; OutputData += (char)LegAngels.BaseLeft1; OutputData += (char)LegAngels.ShoulderLeft1; OutputData += (char)LegAngels.KneeLeft1; OutputData += (char)LegAngels.BaseRight1; OutputData += (char)LegAngels.ShoulderRight1; OutputData += (char)LegAngels.KneeRight1; sp.Write(OutputData); Потом поправил на это: Код (Text): byte[] OutputData = new byte[18]; OutputData[0] = (byte)LegAngels.BaseRight2; OutputData[1] = (byte)LegAngels.ShoulderRight2; OutputData[2] = (byte)LegAngels.KneeRight2; OutputData[3] = (byte)LegAngels.BaseRight3; OutputData[4] = (byte)LegAngels.ShoulderRight3; OutputData[5] = (byte)LegAngels.KneeRight3; sp.Write(OutputData, 0, 6); И все заработало. Ништяк) Спасибо за помощь!
Никогда не видел так много Ангелов в таком маленьком кусочке кода... робот, видимо, будет с крыльями.