Interfacing motors from RPi with PicAxe

I've successfully hooked up the my RPi to my Picaxe for interfacing through this link:
http://www.instructables.com/id/PICAXE-Raspberry-Pi-ADC/

I can successfully return the variables from B1 to my RPi.
However, I'm new to Python and  basically want to get started by writting motor control.

I already know a decent amount of how programming works in general,
enough to where I can understand how the coding on that page works without knowing python.
I was hoping someone could point my in the direction of how to SEND motor instructions to my PicAxe from RPi,
Either articles of how to write though that port to the RPi to CALL functions to be used, or write functions?

If someone could take the time for an example of controlling a motor or servo though this connection method,
it would also be highly appreciated. I don't mind doing work to adapt it or learn it, I'm just at a loss for where to start,
because I don't want to learn ALL of Python from scratch from a book right yet. I just want to learnt to control my motors.

Please note they're not stepper motors and that's all I could find into on, they are the Bi-Di motors from the "getting started".
As always, any help would be appreciated, like where to start for writing high/low to Pic motors, because I don't need WMC.
I just want it on or off, so it has full power when moving... just no means to relay the information.

To simplify, since I’ve been

To simplify, since I’ve been working at and trying to study this for the past 4 hours, where’s what I still need to know:

I know how to program the PicAxe to move motors depending on the output variable sent from the I2C on the RPi.
However, my current problem is: How do I send a variable in python (or another language) from the RPi to the PicAxe?

I simply want to set it so if it sends certain values declared on the Pi to the PicAxe, how can I write the value to the PicAxe?
I have the picaxe motors programmed to go high/low depending on the value of symbol “move”.
How can I program symbol “move” to change from the Pi, or what can I change it to so it can be set?

 

Thanks!

Quick question

Can you command the motors via the PICAXE from the keyboard, if the PICAXE is connected to the computer?

Once you can do that it should be a simple matter of sending the data to the PICAXE via a serial connection from the RPi. I know to make a USB to TTL board talk to a PICAXE chip requires you to invert the TX/RX lines. My last sentence is only to suggest that you might need to invert your signals to get the PICAXE chip to understand what the RPi is telling it.

Thanks for the response,

Thanks for the response, Harvey (If you watched Adult Swim you’d get my reference).

Anyhow I don’t know HOW to control them with keypressing from RPi yet, that’s where I’m stuck.
I’ve spent 90% of the time since my post (total time, the other 10% was phone, eating, etc) looking up Python.

I’ve found write_byte_data, and know to put my PicAxe’s address (0x10) in the first part,
but I don’t understand how to reference/change a symbol/variable in the PicAxe with the other 2 parts…

write_byte_data(0x10,b1,2)
Is what I’m about to try, to see if it makes b1 set to 2 instead of 0, the default programmed in PicAxe.
Or is there a more clear explaination of how to send into to addresses in the PicAxe?

Maybe some help?

http://www.picaxeforum.co.uk/showthread.php?23284-Raspberry-Pi-And-PICAXE-using-i2c

Thanks Jax, but when I read

Thanks Jax, but when I read across that before, it sounded like to me that he never successfully got to write the values for use on the PicAxe… All that tells me is that the PicAxe has a scratchpad to right to, with variables named using the "put (name), (value) command.

I’m trying to figure out how to either write the value with the write_byte_data() command (and how to call it on the PicAxe, or how to have the PicAxe READ a set value on the RPi, to compare it to variables.

My code I want to use for motor control is along these lines:

If (control variable) = 1 then goto moveforward
If (control variable) = 2 then goto moveback

moveforward:
high 4
low 5
low 6
high 7

moveback:
low 4
high 5
high 6
low 7

So as you can see, if I can simply write one value to the RPi, either by the Pi sending or the PicAxe receiving, I’m good.
However, figuring how how to edit information in the PicAxe’s scratchpad is throwing me for a loop… as that guy in the said link.

I believe you missed a word or two in my first comment. :slight_smile:

I asked if you had managed to control a motor from the keyboard via the PICAXE. I was attempting to break your problem down. I am sure you can write a program to get the PICAXE to control the motor all by itself. Next up is to control the motors by way of keyboard inputs while the PICAXE is connected to the computer. The reason I say that is due to the fact that you are sending serial data to the PICAXE via the cable to make the action happen. Once you have that sorted it will be a matter of figuring out how to talk to the PICAXE via the RPi.

Although not the OP,

Although not the OP, RonHackett seemed to be stuck with the same problem, stated in post #14. However he had claimed victory. Advice from post #19:

"Try speeding up the PICAXE by a setfreq, as 100kHz is right on the the boundary of the i2c spec and quite fast for the default 8MHz operating speed of a 20X2. “

and post #20:

”…speeding up the 20X2 did the trick!

 At 16MHz, everything works as expected - either the Pi or the 20X2 can update the scratchpad, and both of them can correctly read the newly updated info. I’ve been struggling with this one or a while (mostly Pi configuration stuff, which is all new to me), so it’s great to have it working - many thanks!"

This should be applicable across the X1/X2 and M2 lineup of PICAXE chips, not just the 20X2.

This could potentially solve the problems I was having with Arduino communicating via I2C consistently to my PICAXE 08M2 as well. It would successfully send commands only half the time. I could not understand why.

Missing something?

Thanks, but I think I’m still missing something you’re trying to tell me…

If you’re saying about controlling the motors on the Picaxe by connecting a keyboard to the PicAxe,
which I don’t think you are, I don’t have the foggiest clue how to do so.

On the other hand, if you’re asking about if I can control the Motors on the PicAxe via the keyboard on the RPi,
which is what I think you’re trying to say, my problem lies therein.
In order to control the motors FROM the keyboard using a program,
the RPi would have to know WHAT to send to the Pic when I press an input key, correct?

So unless I’m way out in left field, while you’re in right, and I’m missing something you’re trying to say,
the problem breaks down right where you’re saying: No, I can’t control the motor from the Keyboard. 
To do that, I would need to set the up arrow to send something to the PicAxe, unless you have an alt. method?
My problem, in the nutshell, is that I can’t interface with the Pi, other than to receieve the analog values.
Meaning, I’m stuck UNABLE to even write a program to control the PicAxe with arrow keys,
because I can’t figure out what functions to give those arrow keys to create any response in the motors. 

 From what I SEEM to understand from Googling:
The RPi’s 
write_byte_data is supposed to write info to the scratchpad.
However if  I use 
write_byte_data(0x10,2,3) where 0x10 is my PicAxe Board,
and 2 is the scratchpad sector on the board I want to write “3” to,
nothing seems to show up in the scratchpad.

Is there another way to interface them from the pie?
Thanks!

How are you using the PICAXE

How are you using the PICAXE scratchpad? You mentioned put but that is to place values in the scratchpad. Good for if you want to have the Pi read it but you seem to want to have the Pi tell PICAXE what to do, not vice versa. To retrieve data sent from the Pi you need to use get like:

get 2, b1 ;puts scratchpad value at address 2 into variable b1

or access them indirectly with the scratchpad pointer like:

ptr=2 ;sets the scratchpad pointer to address 2

b1=@ptr ;sets b1 to the value of the address that the pointer is pointing to

Either way the value sent from the Pi will be put into general variable b1 that you can then use for comparisons. 

edit-

I also forgot to add you need to clear the I2Cflag that gets set when the PICAXE gets written to. Your code will have something like this in it:

init: hi2csetup i2cslave, address
main:
if hi2cflag = 0 then main ; poll flag, else loop
hi2cflag = 0 ; reset flag
get 2,b1 ; get byte written into scratchpad address 2
comparison code, motor controller code, etc here
goto main

edit (2) - lol

You can also use the hi2clast variable that holds the value of the last scratchpad address written to instead of specifying 2, ie:

get hi2clast,b1 ;gets the byte last received

All should do the same thing, it just depends on how you want to go about it.

For completeness…

I looked at my 08M2 code and apparently I’d tried to crank up the speed to 32MHz but it was commented out, so it must not have worked. Maybe exactly 16MHz is the key? I don’t know. Maybe I tried that too (I tried everything I could think of so it’s possible). The set up was de-breadboarded long ago and most of the bits have been rededicated to other projects so I’m not able to test out the theory anytime in the near future.

The detail of help is much

The detail of help is much appreciate, I’m studying it now to try to wrap my head around it.

But as for my python code, is my write method correct, or is something wrong
(IE: Setting the value to 5 must be sent in hex maybe?)

Again, I’m going to read the code to wrap my head around it,
because I’m actually better at learning code from examples than simple studying.
I have trouble cracking open a book and understanding it,
but I learned PHP by simply reading HOW the code works and tinkering.

I’ll use these methods and let you know how it goes! 

In my experience with

In my experience with Arduino-to-PICAXE the format (hex/dec/binary) didn’t seem to matter. In the PICAXE language itself there isn’t any time where one is preferred over the others, as far as I can recall (except maybe setting up ports and pins). YMMV.

I think the crux is understanding the scratchpad is the memory area where the I2C communications write to but it isn’t readily accessable for calculation/comparisons in the program without get/put commands or the ptr/@ptr variables.

Ah! I found it! This is a nice description of the PICAXE’s memory weirdness, IMO:

https://www.robotshop.com/letsmakerobots/node/2975

Also I found a variable map that helped me figure out the memory layout as well:

https://www.robotshop.com/letsmakerobots/node/22976

Keep us posted.

hi2cflag isn’t being written

I used the code you gave my on my Pic, but the “flag” and “last” i2c variables still printed 0.

My PicAxe Code:

#no_data
#no_table
init: hi2csetup i2cslave, %00100000

b2 = 1

main:
put 2, b2
if hi2cflag = 0 then goto fflag
goto main

fflag: ; false flag, if hi2cflag = 0
b2 = 2
goto main




So, as you can see, I adapted things SIMPLY to try to return a value of 1, 2, or 3.
If the value returns 1 (unlikely), it means b2 being pre-defined isn’t working.
If the value returns 2, it means “hi2cflag = 0”. This is the current case.
If the value returns 3, it means the python is successfully printing over to it.

My Python code:

import smbus

import time

bus = smbus.SMBus(1)

address = 0x10

 

def read(register):

        data = bus.read_byte_data(address, register)

        return data

 

def write(register,value):

        data = bus.write_byte_data(address, register, value)

return data

 

while True:

        a2 = read(2)

write(2,3)

        print "A2 = ",a2

        time.sleep(2.0)

So, thanks again!

I’ll look at the memory stuff you were talking about after I go to sleep.
I’ve been working on trying to figure out this one thing for literally a total of 23 hours in the past 3 days now,
between experimenting and googling, so my brain is going kaput… lol

If you have any feedback about something wrong with my code STOPPING it from writing,
changing the i2c flag, etc, I’d love to hear them, even if they’re speculation, because I’m done stuck bad.

I apologize for not being clear.

https://www.robotshop.com/letsmakerobots/node/16469

http://technologytutor.co.nz/picaxe-circuits/06-how-to-communicate-with-the-picaxe

http://www.maxmcarter.com/picaxe/picaxe_comm.html

The above links are the type of communication/control I was talking about.

Simplify further…

… by removing the RPi reading part. Upload this code to your PICAXE and leave it plugged into your computer with the program editor running. Then try having the RPi try writing to the PICAXE:

#no_data
#no_table
init: hi2csetup i2cslave, %00100000

main:
if hi2cflag = 0 then main ; infinite loop until I2C success
get 2,b2 ; used to see value sent as I don’t recall if you can see the scratchpad in the debug window

debug ; victory screen

 

If the Pi isn’t writing to the PICAXE nothing will happen. If it successfully communicates with the PICAXE the debug window will pop up and you’ll know it’s working.

edit -

Added the get command to the code so you can be sure you can see the value sent from RPi is what you wanted

The “debug” menu will pop up

The “debug” menu will pop up whether it passes the loop or not.

However, since the loop terms are false, the debug window pops up with no values.
If I change the loop to if b1 = 0 goto main, and set b1 = 0, the debug menu still pops up with blank fields.
I also put “put 2, b2” after the loop (b2 = 2 earlier), to see if it returns to the RPi.
With the loop in, 2 stays at 0. With the loop removed it prints 2:

So it’s looking like the debug menu is a poor choice for a victory indicator,
because it seems to shop up so long it’s in your code, at least at the end, regardless of conditions.
This actually makes sense, considering the program firsts translates the instructions before sending. 

Why is it so difficult to simple print to, and return to print the value of, one variable? -_-

Sorry about that

I forgot it does pop up regardless, but it just sits there “waiting” until the code reaches it when it will fill the debug tables with values. I guess that would be the victory condition :</p>

 

 

Last stab

I would try RonHackett’s code for the Pi and PICAXE that he claimed worked, maybe even jack up the speed to 16MHz (add setfreq m16 to the beginning of the code) if the code by itself doesn’t work. If he got it to work then it should work for you too.

Famous last words.

My brain is starting to feel kaput as well. It’s like my arduino I2C project all over again.

Just curious, what PICAXE are you using?

Not Facepalm, faceWALL

I think I’m frying my brain over this and going stupid now…

I’ve been messing with things back and forth, THEN tried to put something simple back in it…

Now all my Raspi is printing up is 0, 7, 15, and I think I’ve seen a 255 pop up… WTH?!
I can give you my info for VNC if you want to take a look or tinker with the RPi… 

 


My current PicAxe code:

#no_data
#no_table
init: hi2csetup i2cslave, %00100000

main:
b2 = 2
get 2,b2


My Python:

import smbus

import time

bus = smbus.SMBus(1)

address = 0x10

 

def read(register):

        data = bus.read_byte_data(address, register)

        return data

 

while True:

        a2 = read(2)

        print "A2 = ",a2

        time.sleep(2.0)