Stories of a homemade robot. Part 1

https://habr.com/ru/post/583888/image

The process of integrating these or those robots into the social, urban sphere has always been interesting. A lot of questions arise, both technical, legal and ethical.

What will happen, for example, if your craft weighing under 60 kg breaks, for example, someone’s leg, or if the GPS track breaks down and the robot provokes an accident at a busy pedestrian crossing? Or will he give flowers to the wrong, “unprogrammed” girl, make a mistake with the color of the client’s skin, or deliver to the addressee warm beer and cold shawarma? Having once asked the idea of ​​creating a robot of your dreams, you can get answers to some of these questions, at the same time, once again, try to turn the world around. Actually, under the cut, the process of creating a certain universal robot is described. Specifically, the chassis.

The first robots were more like a “pen test”
There was such a 2-wheeled

And such a modification:

Well, this one:

After studying about fifty design options, both factory and home-made, it was decided to take as a basis a simple and elegant design of the “Crab” type from Thai lawn mowers. The design, mechanics and kinematics were visually determined.
So, to create we need:

  1. A pile of scrap metal:

https://habr.com/ru/post/583888/image

  1. Wheels. It is advisable to choose with a pronounced tread parallel to the wheel axis in order to realize ground lug and tank turning. In this case, wheels from a walk-behind tractor are used.

  2. Driven stars. From motorcycles, mokicks and other bicycles.

  3. Electric motors with a 12 volt MY1016Z2 model gearbox. As it turned out later, the margin of magnetic saturation of the core and the thickness of the insulation of the windings of such a motor make it easy to overload them with a voltage of 24 volts, increasing the current and power.

https://habr.com/ru/post/583888/image

  1. Motorcycle chain. Motorcycle chain number 428 was chosen for better compatibility with most gears.

  2. Remote control.You can use any, Chinese was taken for aircraft modeling, with a range of up to 400m.

https://habr.com/ru/post/583888/image

  1. Microcontroller Atmega 8a.

  2. A couple of Darlington assemblies to control electromagnetic relays, for example ULN2803AFWG.

  3. Electromagnetic relays and beds for them, mainly used in cars.

![image](https://habrastorage.org/webt/ud/i3/8p/udi38psgbjxvm9qomjdj9nfwyww.jpeg“size = 2560×189)

  1. Lead acid battery.

After a couple of months of waving a grinder with a disc, a stroke of electrodes, and a construction of sweat, blood and metal was ready.

Hubs, axles, washers and other spare parts. Not without turning work on turning stops, tension rollers for chains.

https://habr.com/ru/post/583888/image

A piece of metal and a bunch of wires:

https://habr.com/ru/post/583888/image

The electronic filling for the dough of the whole design is extremely simple:
The Atmega is directly screwed onto a transistor assembly that directly drives the relay. The relays, it should be noted, switch the load through self-made chokes to slightly smooth out the armature currents when starting the motors.

The polarity reversal of the power supply to the motors is also carried out by command from Atmeg and through separate relays.

https://habr.com/ru/post/583888/image

Having carried out the procedure of binding the receiver to the remote control, closing the contacts on the receiver with a service jumper, in the slang “Bind” – you can start programming the control of the remote control.

Let’s look at the output signals from the receiver with an oscilloscope:

https://habr.com/ru/post/583888/image

Yeah, depending on the position of the stick, the pulse width changes. You can process this with a microcontroller by reading the signal levels, counting the clock cycles-duration.

A couple of dozen tests for calibration and the code was written.

This is how the source code for receiving signals from the receiver and controlling the robot looks like.

;by IC
;GK1
;PC5-муфта
;pc4-контакт 4- реверс правый борт (ВЫХОДНОЙ СИГНАЛ)
;pc3-контакт 3 -реверс левый борт (ВЫХОДНОЙ СИГНАЛ)
;pc2-контакт 2 -мотор-редуктор правый борт (ВЫХОДНОЙ СИГНАЛ)
;pc1-контакт 1 -мотор-редуктор левый борт (ВЫХОДНОЙ СИГНАЛ)
;pc0-ДВС (ВЫХОДНОЙ СИГНАЛ)G
;pb-ВХОДНОЙ СИГНАЛ ПДУ
;ПДУ - канал 4 - левый стик, лево-право
;ПДУ - канал 3 - левый стик, вверх-вниз
;ПДУ - канал 2 - правый стик, вверх-вниз (вниз-скважность уменьшается, вверх- скважность увеличивается)
;ПДУ - канал 1 - правый стик, лево- право (лево-скважность уменьшается, право- скважность увеличивается)
;d7-d8 -нейтраль
;0116h - высоко
;91 - низко
rjmp RESET ; Reset Handler
rjmp EXT_INT0 ; IRQ0 Handler
rjmp EXT_INT1 ; IRQ1 Handler
;rjmp TIM2_COMP ; Timer2 Compare Handler
;rjmp TIM2_OVF ; Timer2 Overflow Handler
;rjmp TIM1_CAPT ; Timer1 Capture Handler
;rjmp TIM1_COMPA ; Timer1 CompareA Handler
;rjmp TIM1_COMPB ; Timer1 CompareB Handler
;rjmp TIM1_OVF ; Timer1 Overflow Handler
;rjmp TIM0_OVF ; Timer0 Overflow Handler
;rjmp SPI_STC ; SPI Transfer Complete Handler
;rjmp USART_RXC ; USART RX Complete Handler
;rjmp USART_UDRE ; UDR Empty Handler
;rjmp USART_TXC ; USART TX Complete Handler
;rjmp ADC ; ADC Conversion Complete Handler
;rjmp EE_RDY ; EEPROM Ready Handler
;rjmp ANA_COMP ; Analog Comparator Handler
;rjmp TWSI ; Two-wire Serial Interface Handler
;rjmp SPM_RDY ; Store Program Memory Ready Handler
RESET:
cli
ldi r17, 0xff     
out 0x3D, r17                ;инициализация стэка
ldi R16, 0b00111111     ;порт С как выход
out 0x14, r16           ;настройка через регистр DDRC
ldi R16, 0x0            ;порт B как вход
out 0x17, r16           ;настройка через регистр DDRB
ldi R16, 0x0            ;порт D как вход
out 0x11, r16           ;настройка через регистр DDRD
sbi 0x12, 0         ;устанавливаем бит активации Pull-up в PORTD для пина PD0
sbi 0x12, 1         ;устанавливаем бит активации Pull-up в PORTD для пина PD1
sbi 0x12, 2         ;устанавливаем бит активации Pull-up в PORTD для пина PD2
jmp PDU_mode
U_turn_right_PDU:
nop
CALL R1__LEFT_ON
CALL latency_relay_switch
CALL M1__LEFT_ON
CALL M2__RIGHT_ON
nop
jmp chanel3
U_turn_left_PDU:
nop
CALL R2__RIGHT_ON
CALL latency_relay_switch
CALL M1__LEFT_ON
CALL M2__RIGHT_ON
nop
jmp chanel3
PDU_mode:
chanel1:
ldi r21, 0
ldi r22, 0
ldi r23, 1
ldi r24, 0
nop
get_low:
nop
sbic 0x10, 0
jmp get_low            ;дождались нуля на PD0
get_rising:
nop
sbis 0x10, 0
jmp get_rising            ;дождались HIGH сигнала на PD0
get_falling:
nop
add r21, r23               ;основной бит
adc r22, r24               ;дополнительный
sbic 0x10, 0
jmp get_falling            ;Сигнал HIGH закончился
cpi r22, 1
breq U_turn_right_PDU
cpi r21, 0x9f   ;a0
brlo U_turn_left_PDU
chanel2:
ldi r21, 0
ldi r22, 0
ldi r23, 1
ldi r24, 0
nop
get_low2:
nop
sbic 0x10, 1
jmp get_low2            ;дождались нуля на PD0
get_rising2:
nop
sbis 0x10, 1
jmp get_rising2            ;дождались HIGH сигнала на PD0
get_falling2:
nop
add r21, r23               ;основной бит
adc r22, r24               ;дополнительный
sbic 0x10, 1
jmp get_falling2            ;Сигнал HIGH закончился
cpi r22, 1
breq Motion_forward_PDU
cpi r21, 0x9f   ;a0
brlo Motion_backward_PDU
nop
CALL M1__LEFT_OFF
CALL M2__RIGHT_OFF
CALL latency_relay_switch
CALL R1__LEFT_OFF
CALL R2__RIGHT_OFF
nop
chanel3:
ldi r21, 0
ldi r22, 0
ldi r23, 1
ldi r24, 0
get_low3:
sbic 0x10, 2
jmp get_low3            ;дождались нуля на PD0
get_rising3:
sbis 0x10, 2
jmp get_rising3            ;дождались HIGH сигнала на PD0
get_falling3:
add r21, r23               ;основной бит
adc r22, r24               ;дополнительный
sbic 0x10, 2
jmp get_falling3            ;Сигнал HIGH закончился
cpi r22, 1
breq Clutch_ON_PDU
CALL Clutch_OFF
nop
jmp PDU_mode
Clutch_ON_PDU:
CALL Clutch_ON
jmp PDU_mode
Motion_forward_PDU:
CALL R2__RIGHT_ON
CALL latency_relay_switch
CALL R1__LEFT_ON
CALL latency_relay_switch
CALL M1__LEFT_ON
CALL M2__RIGHT_ON
nop
jmp chanel3
Motion_backward_PDU:
CALL M1__LEFT_ON
CALL M2__RIGHT_ON
nop
jmp chanel3
LDI     R16,2       ; Загружаем адрес нулевой ячейки
LDI     R17,0       ; EEPROM 
;LDI    R21, 0x33       ; и хотим записать в нее число cc
RCALL   EEWrite     ; вызываем процедуру записи.
LDI     R16,1       ; Загружаем адрес нулевой ячейки
LDI     R17,0       ; EEPROM 
mov r21, r22
RCALL   EEWrite     ; вызываем процедуру записи.
ldi r25, 1               ;флаг записи епромки
LDI     R16,3       ; Загружаем адрес нулевой ячейки
LDI     R17,0       ; EEPROM 
mov r21, r25
RCALL   EEWrite     ; вызываем процедуру записи.
skip:
nop
jmp idle
EEWrite:    
SBIC    EECR,EEWE       ; Ждем готовности памяти к записи. Крутимся в цикле
RJMP    EEWrite         ; до тех пор пока не очистится флаг EEWE
CLI             ; Затем запрещаем прерывания.
OUT     EEARL,R16       ; Загружаем адрес нужной ячейки
OUT     EEARH,R17       ; старший и младший байт адреса
OUT     EEDR,R21        ; и сами данные, которые нам нужно загрузить
SBI     EECR,EEMWE      ; взводим предохранитель
SBI     EECR,EEWE       ; записываем байт
SEI                 ; разрешаем прерывания
RET                 ; возврат из процедуры
EERead: 
SBIC    EECR,EEWE       ; Ждем пока будет завершена прошлая запись.
RJMP    EERead          ; также крутимся в цикле.
OUT     EEARL, R16      ; загружаем адрес нужной ячейки
OUT     EEARH, R17      ; его старшие и младшие байты
SBI     EECR,EERE       ; Выставляем бит чтения
IN  R25, EEDR       ; Забираем из регистра данных результат
RET
Motion_forward:
CALL latency_relay_switch
CALL R2__RIGHT_ON
CALL latency_relay_switch
CALL R1__LEFT_ON
CALL latency_relay_switch
CALL M1__LEFT_ON
CALL M2__RIGHT_ON
CALL latency
CALL M1__LEFT_OFF
CALL M2__RIGHT_OFF
CALL latency_relay_switch
CALL R1__LEFT_OFF
CALL R2__RIGHT_OFF
Motion_backward:
CALL latency_relay_switch
CALL M1__LEFT_ON
CALL M2__RIGHT_ON
CALL latency
CALL M1__LEFT_OFF
CALL M2__RIGHT_OFF
U_turn_right:
CALL latency_relay_switch
CALL R1__LEFT_ON
CALL latency_relay_switch
CALL M1__LEFT_ON
CALL M2__RIGHT_ON
CALL latency
CALL M1__LEFT_OFF
CALL M2__RIGHT_OFF
CALL latency_relay_switch
CALL R1__LEFT_OFF
;ret
U_turn_left:
CALL latency_relay_switch
CALL R2__RIGHT_ON
CALL latency_relay_switch
CALL M1__LEFT_ON
CALL M2__RIGHT_ON
CALL latency
CALL M1__LEFT_OFF
CALL M2__RIGHT_OFF
CALL latency_relay_switch
CALL R2__RIGHT_OFF
;ret
jmp Motion_forward
TEST1:
CALL ICE_Start
CALL latency
CALL ICE_Stop
CALL latency
CALL M1__LEFT_ON
CALL latency
CALL M1__LEFT_OFF
CALL latency
CALL M2__RIGHT_ON
CALL latency
CALL M2__RIGHT_OFF
CALL latency
CALL R1__LEFT_ON
CALL latency
CALL R1__LEFT_OFF
CALL latency
CALL R2__RIGHT_ON
CALL latency
CALL R2__RIGHT_OFF
CALL latency
CALL Clutch_ON
CALL latency
CALL Clutch_OFF
jmp TEST1
idle:
;sbi 0x15, 5           ;PortC, бит 5
nop
jmp idle
EXT_INT0:
sbi 0x15, 5           ;PortC, бит 5
reti
EXT_INT1:
sbi 0x15, 4           ;PortC, бит 5
reti
;Задержка
latency_relay_switch:                 ;калиброванная задержка для переключения реле
ldi r20, 255
ldi r21, 100
;ldi r22, 1
delay2:
subi r20, 1
sbci r21, 0
;sbci r22, 0
brne delay2
nop
ret
;Задержка
latency:
ldi r20, 255
ldi r21, 255
ldi r22, 12
delay1:
subi r20, 1
sbci r21, 0
sbci r22, 0
brne delay1
nop
ret
ICE_Start:
sbi 0x15, 0           ;PortC, бит 0
RET
ICE_Stop:
cbi 0x15, 0           ;PortC, бит 0
ret
M1__LEFT_ON:
sbi 0x15, 1           ;PortC, бит 1
ret
M1__LEFT_OFF:
cbi 0x15, 1           ;PortC, бит 1
ret
M2__RIGHT_ON:
sbi 0x15, 2           ;PortC, бит 2
ret
M2__RIGHT_OFF:
cbi 0x15, 2           ;PortC, бит 2
ret
R1__LEFT_ON:
sbi 0x15, 3           ;PortC, бит 3
ret
R1__LEFT_OFF:
cbi 0x15, 3           ;PortC, бит 3
ret
R2__RIGHT_ON:
sbi 0x15, 4           ;PortC, бит 4
ret
R2__RIGHT_OFF:
cbi 0x15, 4           ;PortC, бит 4
ret
Clutch_ON:
sbi 0x15, 5           ;PortC, бит 5
ret

Clutch_OFF:
cbi 0x15, 5           ;PortC, бит 5
ret

After the final assembly and after fifty trips, it became clear that the mechanics of the robot are working perfectly. This cart easily copes with most obstacles, significant slopes up to 40 ‰, has a reserve of power, sufficient maneuverability.

As you can see in the video, in some areas of the terrain, the engine torque is clearly not enough.
It doesn’t matter – they can easily withstand a 2-fold overload with an increase in torque and speed. It is enough to install one more battery in the power circuit, but another big problem appears – sticking of the contact part of the relay, due to an increase in current. What actually happened – suddenly The 60,000 gram car, having lost control, rushed in an unacceptable direction.

The solution to the problem by installing contactors with arc suppression is not considered in principle – people’s lives are more expensive, let it be better to burn out the transistor in the motor controller.

Returning to the “base” without losses, it was decided to seriously modify the circuitry and control algorithms for the robot, in favor of humanity. Otherwise, how can he independently deliver shawarma? without attracting the attention of law enforcement officials and not getting into the criminal bulletin of local news.

As you can see, the robot presented in the title of the article and the robot described in the body of the article are slightly different, which only means that not all stories are told.

The robot will be equipped with more or less professional controllers of electric motors with vector control of torque, various software functions such as hard-stop, duplicate signals, installed sensor equipment and lithium batteries, will be replaced with a more interesting microprocessor.

Recording a heat trace and searching for deviations for fixing violations of the security perimeter and local man-made defects.

Connecting the robot to the bill acceptor using the old mdb vending protocol.

About all this and the adventures of a robot among people in the following parts.

PS New laws of robotics are just around the corner.
PSS The working title of the project is “Grass-killer”.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *