1. Do not share user accounts! Any account that is shared by another person will be blocked and closed. This means: we will close not only the account that is shared, but also the main account of the user who uses another person's account. We have the ability to detect account sharing, so please do not try to cheat the system. This action will take place on 04/18/2023. Read all forum rules.
    Dismiss Notice
  2. For downloading SimTools plugins you need a Download Package. Get it with virtual coins that you receive for forum activity or Buy Download Package - We have a zero Spam tolerance so read our forum rules first.

    Buy Now a Download Plan!
  3. Do not try to cheat our system and do not post an unnecessary amount of useless posts only to earn credits here. We have a zero spam tolerance policy and this will cause a ban of your user account. Otherwise we wish you a pleasant stay here! Read the forum rules
  4. We have a few rules which you need to read and accept before posting anything here! Following these rules will keep the forum clean and your stay pleasant. Do not follow these rules can lead to permanent exclusion from this website: Read the forum rules.
    Are you a company? Read our company rules

arduino

Discussion in 'SimTools compatible interfaces' started by hraanan, Jan 7, 2012.

  1. hraanan

    hraanan New Member

    Joined:
    Aug 10, 2011
    Messages:
    2
    Balance:
    1Coins
    Ratings:
    +0 / 0 / -0
    Hi,
    I have problems with how to define the arduino in x sim. I can't see the com of the arduino in the list!!
    if anyone can help I will be very happy.

    tnx
    hraanan
  2. bsft

    bsft

    Balance:
    Coins
    Ratings:
    +0 / 0 / -0
    Hello, there are people sorting the code so you may have to just wait like everyone else at this stage.
    :cheers:
  3. johnr

    johnr New Member

    Joined:
    Nov 7, 2009
    Messages:
    26
    Balance:
    0Coins
    Ratings:
    +0 / 0 / -0
    Make sure you can use the Arduino outside of X-Sim first. The serial port you use outside X-Sim will be the one you select in Profiler (serial interface screen).
  4. stowaway

    stowaway New Member

    Joined:
    Mar 16, 2009
    Messages:
    213
    Location:
    Gold Coast - Australia
    Balance:
    1Coins
    Ratings:
    +0 / 0 / -0
    I'm currently trying to design an interface with the Arduino Uno.
    I'm not using the Arduino IDE Though, Im just coding directly too the Chip with WinAVR.

    Mine controls 3 motors, and at the moment just communicates through the USO. I'd be happy to colaborate. As soon as my source is sorted ill be uploading it here.
  5. stowaway

    stowaway New Member

    Joined:
    Mar 16, 2009
    Messages:
    213
    Location:
    Gold Coast - Australia
    Balance:
    1Coins
    Ratings:
    +0 / 0 / -0
    This is my code so far for the Arduino UNO. (Or just a ATMEGA328P)

    It uses PID.C/PID.H downloded from Amtel Webpage and a LCD Library.

    At the moment it reads Serial data from USO when used R~a01~~a02~~a03~E
    and saves that data to MotorX.DesiredValue
    every 10ms it calculates the PWMSpeed using pid_controller.
    and it also opens 3 PINS to use Phase Corrected PWM.
    (there is quiet a few lines in there desiged for my testing purposes)

    Ive got my H-Bridge and Winch Motor on order.. So currently it i untested in real world:
    Code:
    /*** TMC - Tippett Motion Control
    **** Timer 0B - PMW Motor 1
    **** Timer 1 - PID Timer Run PID Calculations every PIDDELAY (Currently 2500 for every 10ms)
    **** 
    ****
    **** TO control Motors change OCR2B, OCR0B, OCR0A
    ****
    ****/
    
    #include <avr/io.h> 
    #include <stdio.h>
    #include <stdlib.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    #include pid.h
    #include lcd.h
    #include <string.h>
    
    #define NO_OF_POTS 3
    #define NO_OF_AXIS 3
    #define NO_OF_INPUTS (NO_OF_AXIS * 2)
    #define potSensitivity 10
    
    /* UART SERIAL DEFINES */
    #define F_CPU 16000000UL
    #define BAUD 9600
    #define MYUBRR F_CPU/16/BAUD-1
    #define PIDDELAY 2500
    
    
    
    //Put in header file
    
    void InitPIDTimer(void);
    void ADC_Init(int preScaler, int tenBit);
    
    //To Do. make these values editable via lcd and buttons
    double K_P = 3;
    double K_I = 35;
    double K_D = 10;
    
    
    //TO DO. DELETE THESE VARIABLES
    volatile int desiredPosition;
    volatile int actualPosition;
    volatile uint8_t inputBuffer[NO_OF_INPUTS];
    
    volatile uint8_t position;
    
    
    struct Motors
    {
    	uint16_t CurrentPosition;
    	uint16_t DesiredPosition;
    	struct PID_DATA PidData;
    	uint16_t PWMspeed;
    	
    } Motor1, Motor2, Motor3;
    
    
    /* ADC METHODS */
    
    // Initate ADC. 
    // Input prescaler amount, and 10bit or 8bit results
    void ADC_Init(int preScaler, int tenBit)
    {
    	ADCSRA |= (1 << ADEN);  //Enable ADC
    	
    	//To Do. Set Different prescalers.
    	if (preScaler == 128)
    		ADCSRA |= (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);  //set prescaler to 128
    		
    		
    	if (!tenBit)
    		ADMUX |= (1 << ADLAR);  //Left adjust ADC result to allow easy 8 bit reading	
    		
    	ADMUX |= (1 << REFS0);  //USE AVCC as refernece;
    	ADCSRA |= (1 << ADSC);  //start first conversion
    }
    
    
    /***************/
    
    /* PWM Methods */
    
    void PWM_init(void)
    {
    
    	/* Init Timer 0A PORT D6 or PORT 6 on Arduino */
        DDRD |= (1 << DDD6);
        // PD6 is now an output
    
        OCR0A = 100;
        // set PWM for 50% duty cycle
    
    
        TCCR0A |= (1 << COM0A1);	
        // set none-inverting mode
    
        TCCR0A |= (1 << WGM00);  //PWM Phase Corrected 
    
        TCCR0B |= (1 << CS00);
        // set prescaler to 8 and starts PWM
    	
    	
    		
    	/* Init Timer 0B PORT D5 or PORT 5 on Arduino */
    	DDRD |= (1 << DDD5);
    	OCR0B = 128; // set PWM for 50% duty cycle
    
    	TCCR0A |= (1 << COM0B1);
        // set none-inverting mode
    
    	OCR0B = 128;
    	
    
    	/* INIT Timer 2B Port D3 or 3 oon Arduino*/	
    	DDRD |= (1 << DDD3);
        // PD6 is now an output
    	
        OCR2B = 150;
        // set PWM for 50% duty cycle
    
    
        TCCR2A |= (1 << COM2B1) | (1 << WGM20);
        // set none-inverting mode & set PWM Phase correct Mode
    	        
        	
    	
        TCCR2B |= (1 << CS21);
        // set prescaler to 8 and starts PWM
    
    } 
    
    
    
    
    /***************/
    
    /* SERIAL METHODS */
    
    /* SETUP UART */
    void USART_Init( unsigned int ubrr)
    {
       /*Set baud rate */
       UBRR0H = (unsigned char)(ubrr>>8);
       UBRR0L = (unsigned char)ubrr;
       
      /*Enable receiver and transmitter */
       UCSR0B = (1<<RXEN0)|(1<<TXEN0);
       
       /* Set frame format: 8data, 1stop bit */
       UCSR0C = (3<<UCSZ00);
       
          /*Turn on Receive Complete Interrupt*/
       UCSR0B |= (1 << RXCIE0);
       
       position = -1;
    }
    
    
    
    /******************/
    
    
    
    
    void InitPIDTimer()
    {
    	TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode 
    	TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt 
    	TCCR1B |= ((1 << CS10) | (1 << CS11)); // Start timer at Fcpu/64
    	OCR1A   = PIDDELAY;
    
    }
    
    void Init(void)
    {
    	//Setup PID structs
    	pid_Init(K_P, K_I, K_D, &Motor1.PidData);
    	pid_Init(K_P, K_I, K_D, &Motor2.PidData);
    	pid_Init(K_P, K_I, K_D, &Motor3.PidData);
    	
      
    	/* Init LCD */
    	lcd_init(LCD_DISP_ON);
    	
    	
    	/* Setup  ADC */
    	//ADC_Init(128, 1);
    	
         /*Turn on Receive Complete Interrupt*/
    	UCSR0B |= (1 << RXCIE0);
    
    	/*Turn on ADC Interrupt */
    	ADCSRA |= (1 << ADIE); 
       
       
    	//Turn on PORTB 12 to input
    	DDRB &= ~(1 << PINB4);   //set input direction
    	
    	
    	lcd_clrscr();
    	lcd_puts(Init Okay);
    		   
    }
    
    int main(void)
    {
    
    	PWM_init();
    	
    	Init();
    	
    
    	
    	InitPIDTimer();
    	
    	
    	/* INITALISE SERIAL */
    	USART_Init(MYUBRR);
    	
    	//turn on interrupts	
    	sei();
    
    	int LCDCount = 0;
       
    	while (1)
    	{
    		if (LCDCount > 10000)
    		{
    		
    			
    			LCDCount = 0;	
    			
    			char Motor1String[7];
    			char Motor2String[7];
    		
    			
    			sprintf(Motor1String,%u , Motor1.DesiredPosition);						
    			itoa(Motor1.PWMspeed, Motor2String, 10);
    			
    			
    			
    			lcd_clrscr();     /* clear the screen*/  			
    			lcd_puts(Motor1String); 
    			lcd_gotoxy(0,1);
    			lcd_puts(Motor2String);
    			
    			Motor1.CurrentPosition += Motor1.PWMspeed;
    			Motor3.CurrentPosition += Motor3.PWMspeed;
    			
    		}
    		
    		LCDCount++;
    		
    	}
    	
    	
    	
    }
    
    
    
    /* INTERRUPTS */
    
    //Timer 1A Interrupt
    
    /*Every 10ms Calcualte the PWM value via pid_controller in pid.c*/
    ISR(TIMER1_COMPA_vect)
    {			   		
    			Motor1.PWMspeed = pid_Controller(Motor1.DesiredPosition, Motor1.CurrentPosition, &Motor1.PidData);										
    			Motor2.PWMspeed = pid_Controller(Motor2.DesiredPosition, Motor2.CurrentPosition, &Motor2.PidData);										
    			Motor3.PWMspeed = pid_Controller(Motor3.DesiredPosition, Motor3.CurrentPosition, &Motor3.PidData);						
    } 
    
    
    
    
    //SERIAL INTERRUPT
    ISR (USART_RX_vect)
    {	
    	
    	int input = UDR0;
    	
    	if (input == 'R')
    	{	
    		position = 0;				
    	}
    	else if ((input != 'E') && (position > -1))
    	{
    	
    		if (position < NO_OF_INPUTS)
    		{
    			inputBuffer[position] = input;
    			position++;
    		}
    		else
    		{
    			//error; ignore and restart
    			position = -1;
    		}
    		
    	}
    	else if (input == 'E')
    	{		
    		if (position == 5)
    		{
    			/* Correct Packet Count Recevied. Commit Values */
    			Motor1.DesiredPosition = (inputBuffer[0] << 8) | inputBuffer[1];
    			Motor2.DesiredPosition = (inputBuffer[2] << 8) | inputBuffer[3];
    			Motor3.DesiredPosition = (inputBuffer[4] << 8) | inputBuffer[5];	
    		}
    		
    		position = -1;
    	}
    	
    }
    
    
    
    //ADC INTERRUPT
    ISR(ADC_vect) 
    { 
    	
    
    	switch (ADMUX)
    	{
    		case 0x40:				
    		if ((Motor1.DesiredPosition > ADC + potSensitivity) || (Motor1.DesiredPosition < ADC - potSensitivity))
    		{			
    			Motor1.DesiredPosition = ADC;
    		}					
    		ADMUX = 0x41;
    		break;
    		
    		
    		case 0x41:
    		if ((Motor2.DesiredPosition > ADC + potSensitivity) || (Motor2.DesiredPosition < ADC - potSensitivity))
    		{			
    			Motor2.DesiredPosition = ADC;
    		}
    				
    		ADMUX = 0x42;
    		break;
    		
    		case 0x42:
    		if ((Motor3.DesiredPosition > ADC + potSensitivity) || (Motor3.DesiredPosition < ADC - potSensitivity))
    		{			
    			Motor3.DesiredPosition = ADC;
    		}
    			
    		ADMUX = 0x40;
    		break;		
    	
    	}
    	
    	ADCSRA |= (1 << ADSC);  //next conversion
    	
    } 
    
    
    
    
  6. MSK

    MSK Member

    Joined:
    Oct 9, 2011
    Messages:
    41
    Balance:
    53Coins
    Ratings:
    +1 / 0 / -0
    When I checked my device manager in my control panel, beside the Arduino it was stated COM7. So, In the profiler, I typed in COM7.

    I am using 6 linear actuators (hydraulic). So using 6 axis . Is it possible for me to send data to arduino for each axis in the order I want from X-sim and then program the arduino to receive it in that format ?

    thanks
  7. stowaway

    stowaway New Member

    Joined:
    Mar 16, 2009
    Messages:
    213
    Location:
    Gold Coast - Australia
    Balance:
    1Coins
    Ratings:
    +0 / 0 / -0
    Hi,

    Yes, this is done in the USO. It wont show the comport in the USO but if you read the fine print under there you just need to enter a comport like //.//COM7 (from memory, it may not be exactly that, just read the text to get the format) Arduino comports WONT show up in the drop down box, but you just type in it..

    Then You just decide what format you want to send it in (i think you may need to send it as Decimal if you want to use the Arduino Librarys.. But I send it as Binary) then just set up the format you want to send it ~a01~~a02~~a03~~a04~~a05~~a06~ will just send all axis one after another, no checksum, you need to decide whats best for you, weather you want a check sum or a start character and end character or whatever.

    then you just setup the arduino to listen to the serial. easy pezy.