0

Edit, this question has been answered in the comments by chrisl, and also after retesting the code with delay() which showed I forgot to update my lastupdate variable(eerst), I have answered it in the comments and chrisl possibly also will post their findings in a answer TLDR- 28BYJ-48 unipolar 5v not working only whining. run using transistors and code in the bottom of the post. transistors connected to 5V and resistors ranging from 100ohm to 1000ohm tried from Arduino to the transistors Trigger/Gate. - END TLDR

More Detailed I have some 5v and 12v 28BYJ-48 unipolar stepper motors,(I only connect one to the Arduino at a time) the common(tested with resistance meter) is connected to +, and I the other pins are connected to one BC336 transistor per pin so 4 in total. these transistors should handle 0.8A a piece and I measured the maximum amperage used by the coils to be 0.2+-0.02A for the 5v version at 5v, and 0.045 +- 0.001A for the 12v version at 5v. it makes sense if the 12v version doesn't work at 5v, I just wanted to test it to have an ultra-low-power stepper motor. however the 5v version should work, My setup allows a higher voltage drop in the coils in the motor and can handle a higher amperage than a normal driver however this is limited by the motors resistance ofcource. I drive it according to the steps in the datasheet with the standard method. and simplified my code to leave out all extra things and even hardcoding the values but still it only whiles and doesn't run the motor. I use the Arduino 5v to run the stepper motor but according to the datasheet and my measurements, you could drive more than one stepper motor on the 5v pin, even when running from USB power. I also set it really slow so that it should work(based on datasheet). I want to get this working like this because I am working on a custom budget stepper driver for Arduino which allows much simpler control, and which is much cheaper than the current drivers as well as that it by default can run higher voltage stepper motors as well, and one very specific functionality which almost everyone who has ever used one stepper motor or more has hoped that their stepper motor driver had.

I used pin 8 9 10 and 11 Broken Code:

unsigned long eerst=0;
unsigned long nu=0;
int state=0;
byte vals[8]={0b00000001,0b00000011,0b00000010,0b00000110,0b00000100,0b00001100,0b00001000,0b00001001};//made hardcoderd aray to make sure fault wasn't in the cyclic bitshifting

void setup() {
  //0b76543210 portD <-- direction right is low num left is high num, keep confusing this since it differs on some platforms and not having used arduino for a while
  DDRB=DDRB | 0b00001111;//only set 8,9,10, 11 as output do not change resst.
  PORTB=0b00000000;//simplified from only turning of 8,9,10,11 to turning of all of portb 
  delay(1000);
  eerst=millis();
}

void loop() 
{
  nu=millis();
  if(nu-20>=eerst)
  {

//forgot to update here PORTB=vals[state]; state++; if(state>7)//resets state { state=0; } } }

Working Code (might be changed for the long overflow stabilizing), changed variable names to make it clearer for others to read:

unsigned long TimeOfLastStep=0;
unsigned long CurrentTime=0;
int step=0;
byte vals[8]={0b00000001,0b00000011,0b00000010,0b00000110,0b00000100,0b00001100,0b00001000,0b00001001};//made hardcoderd aray to make sure fault wasn't in the cyclic bitshifting

void setup() {
  DDRB=DDRB | 0b00001111;//only set 8,9,10, 11 as output do not change resst.
  PORTB=0b00000000;
  CurrentTime=millis();
}

void loop() 
{
  CurrentTime=millis();
  if(CurrentTime-2>=TimeOfLastStep)//increased speed from 20ms delay to 2 ms
  {
    TimeOfLastStep=CurrentTime;//forgot this
    PORTB=vals[state];
    state++;
    if(state>7)//resets state
      {
        state=0;
      }
  }
}
4
  • 1
    I guess eerst should be the timestamp variable. You need to set this inside the if statement. Currently you are running as fast as the Arduino can, probably too fast for the motor. Also you should handle the if statement line in the BlinkWithoutDelay example if(nu - eerst >= 20). Then inside the if statement do eerst += 20;. Please test this. I will write an answer if that solves it
    – chrisl
    Dec 17, 2021 at 14:10
  • yes you are right, not long after posting it I saw the problem as well, and my timings were of since I assumed 100 steps per rotation, so a movement would be very slow if it did something. So I know now what I failed, it was one of those typical cases where you think something and think of typing it but then forget you didn't actually type it yet. Dec 17, 2021 at 14:33
  • @chrisl You mean to edit it directly in the if statement just like you do in a for loop? or do you mean that thing about the order of how to put the variables for non blocking code to prevent the code from hanging or misbehaving/skipping when the unsigned long flips(passed it's maximum value). if so, then that would be very helpful and why/what value order to use it for infinite amounts without needing a restart to prevent possible problems. Dec 17, 2021 at 14:34
  • @chrisl the thing you mean in the second thing is if(nu-eerst>=2), instead of if(nu-2>=eerst). right? I checked it with some mathematics and my precious code indeed was not rollover proof(weird behavior when you go beyond the max value of a unsigned variable and get back to the lowest one. Dec 17, 2021 at 15:09

1 Answer 1

2

I found the problem(s) in my design, everything was right but I forgot to add eerst=nu;(first=now;, used a different language because now is used by the arduino ide). Also I didn't read the datasheet properly and so assume 100step/revolution causing me to use delays which where to large, and so even if it worked the movement would be super slow and possibly missed.

New working code:

unsigned long eerst=0;
unsigned long nu=0;
int state=0;
byte vals[8]={0b00000001,0b00000011,0b00000010,0b00000110,0b00000100,0b00001100,0b00001000,0b00001001};//made hardcoderd aray to make sure fault wasn't in the cyclic bitshifting.
//in PortB you have the pins 8,9,10,11,12,13. you start at the back of the byte, so if 0b00000001 then only pin 8 is on. if 0b00000010, then only pin 9 is on, if 0b00000011 then pin 8 and 9 are on. PortB has 8 bits, but only 6 settable pins, so do not change the first 2 bits. you can do it more secure this should be done when using port D since that one is connected to serial. however for simplicity I did not add that code here, you can ask for it and I will probably respond with it.

void setup() { since it differs on some platforms and not having used arduino for a while
  DDRB=DDRB | 0b00001111;//only set 8,9,10, 11 as output do not change resst.
  PORTB=0b00000000; // disabling all port B outputs
  eerst=millis();//eerstm means first, set first to milis to have delay without pausing the code.
}

void loop() 
{
  nu=millis();//nu is now, store this lets the code know for how long the arduino ran in milliseconds, needed for non blocking delay, only one now/nu is needed.
  if(nu-2>=eerst)// if 2 milliseconds have passed(have been waited), execute the following code.
  {
    eerst=nu;//reset the non blocking delay timer
    PORTB=vals[state];//Hardcoded values in the array above, this turns on and off pins and is much faster than digital write, selects item at number [state] of aray.
    state++;//go to next state/step
    if(state>7)//resets state
      {
        state=0;//resets state/back to state 0(1 of 8)
      }
  }
}

edit: solution was also referenced to in the comments below the post. it was really a problem about having it in mind but forgetting to type something down. anyway I will probably soon start to test with that custom driver don't know how to publish it, but will probably link it back here if I remember it. will be open source probably if I find the proper methods.

2
  • I have my new driver working, currently my current design costs around 15 cents to make yourself as a hobbyist, and it allows much more than a traditional driver as well as that it can control 2 stepper motors separately and doesn't require as much pins. however I still have to do some tests and improve things a bit to increase the efficiency and such, especially when you replace parts with custom parts. currently it is around as powerful per motor as the normal driver, but in tests I found that I could reach a much greater efficiency than the original one. Dec 18, 2021 at 13:07
  • with my current setup I could make a working lithography mashine for €1,65(excluding the arduino) In this design I do use scrap parts for things like the frame and lens, the precision of the uv beam can only be changed manually in this design, I calculated it using the prices I paid for the parts, this excludes shipping and I got parts in bigger quantities, however I also included parts in this price which you probably already have laying around like resistors, transistors, a capacitor to stabilize the power,etc. I asumed one to have cables. I will probably publish how to make this thing. Dec 18, 2021 at 13:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.