I have this simple code on Raspberry B+.
#include <wiringPi.h>
#include <stdio.h>
int main (int argc, char** argv)
{
int pin;
if (argc <2)
pin = 7;
else
pin = atoi(argv[1]);
printf("Raspberry Pi wiringPi blink test\n");
if (wiringPiSetup() == -1)
return 1;
pinMode(pin, OUTPUT);
for (;;){
printf("LED On\n");
digitalWrite(pin, 1);
delay(250);
printf("LED Off\n");
digitalWrite(pin, 0);
delay(250);
}
return 0;
}
I want to blink a LED connected to a certain pin.
But for some reason the led is blinking only when connected to pin 7. (I have not tried all other pins though, just 8,31,32,33);
when I try the command gpio -g 6 write 1 (which is for pin 31) the LED glows...
What is wrong with the code?
I figured out!
The wiringPi pin numbering is different from R-Pi!
Here is a chart for which pin is which.
It was just a coincidence that pin 7 on R-Pi is pin 7 on wiringPi as well.
Related
I have been unable to solve a simple USART transmit/receive program. The problem is that I used this in the past and worked effortlessly but now it returns in my Linux machine question marks and in windows some boxes and Chinese characters. I don´t understand what changed. I have tried a lot of different things like changing the code and the parts but nothing seems to solve it.
I´m using a AVR atmega 328p, and a pololu usb programmer. I flashed it from the atmel studio in windows and from avrdude in linux.
Here is the code:
#define F_CPU 1000000
#define BAUD 9600
#include <avr/io.h>
#include <util/delay.h>
#include <util/setbaud.h>
void init_USART(void);
void transmit_Byte(char data);
char receive_Byte(void);
int main(void)
{
char TEST;
init_USART(); /* Initialize USART */
while (1)
{
TEST = receive_Byte();
transmit_Byte(TEST);
}
}
void init_USART(void)
{
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
#if USE_2x
UCSR0A |= (1 << U2X0);
#else
UCSR0A &= ~(1 << U2X0);
#endif
UCSR0B = (1 << TXEN0) | (1 << RXEN0); /* Enable USART
transmitt/receive */
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); /* 8 data bits, 1 stop
bit */
}
void transmit_Byte(char data)
{
loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait for empty
transmit buffer */
UDR0 = data;
}
char receive_Byte(void)
{
loop_until_bit_is_set(UCSR0A, RXC0);
return(UDR0);
}
This is my first question so I apologize in advanced if I did something wrong.
Thanks a lot for your time!
edit: I have tried a ftdi232 and a mcp2221
edit 2: After addin UL still not as expected but got less unknown characters.
SOLVED: But I don't understand why. I changed the fuse CKDIV8 to 1 and it started working. The datasheet says it comes factory with 8 MHz clock and the CKDIV8=0 so it is set to 1 MHz. So why is it inversed? I also tried previously clock_prescale_set(clock_div_8); as the datasheet suggest for prescaling and it didn't work neither.
What is the difference between setting the CLDIV8 and the avr/power.h function?
Sorry for my ignorance but I am very new in FTDI chip Linux software development.
I have module based on FT245RL chip, programmed to be 4 port output (relays) and 4 port opto isolated input unit.
I found out in Internet program in C to turn on/off relays connected to outputs D0 to D3. After compiling it works properly. Below draft of this working program:
/* switch4.c
* # gcc -o switch4 switch4.c -L. -lftd2xx -Wl,-rpath,/usr/local/lib
* Usage
* # switch4 [0-15], for example # switch4 1
* */
#include <stdio.h>
#include <stdlib.h>
#include "./ftd2xx.h"
int main(int argc, char *argv[])
{
FT_STATUS ftStatus;
FT_HANDLE ftHandle0;
int parametr;
LPVOID pkod;
DWORD nBufferSize = 0x0001;
DWORD dwBytesWritten;
if(argc > 1) {
sscanf(argv[1], "%d", ¶metr);
}
else {
parametr = 0;
}
FT_SetVIDPID(0x5555,0x0001); // id from lsusb
FT_Open(0,&ftHandle0);
FT_SetBitMode(ftHandle0,15,1);
pkod=¶metr;
ftStatus = FT_Write(ftHandle0,pkod,nBufferSize,&dwBytesWritten);
ftStatus = FT_Close(ftHandle0);
}
My question is. How can I read in the same program, status of D4 to D7 pins, programmed as inputs? I mean about "printf" to stdout the number representing status (zero or one) of input pins (or all input/output pins).
Can anybody help newbie ?
UPDATE-1
This is my program with FT_GetBitMode
// # gcc -o read5 read5.c -L. -lftd2xx -Wl,-rpath,/usr/local/lib
#include <stdio.h>
#include <stdlib.h>
#include "./ftd2xx.h"
int main(int argc, char *argv[])
{
FT_STATUS ftStatus;
FT_HANDLE ftHandle0;
UCHAR BitMode;
FT_SetVIDPID(0x5555,0x0001); // id from lsusb
ftStatus = FT_Open(0,&ftHandle0);
if(ftStatus != FT_OK) {
printf("FT_Open failed");
return;
}
FT_SetBitMode(ftHandle0,15,1);
ftStatus = FT_GetBitMode(ftHandle0, &BitMode);
if (ftStatus == FT_OK) {
printf("BitMode contains - %d",BitMode);
}
else {
printf("FT_GetBitMode FAILED!");
}
ftStatus = FT_Close(ftHandle0);
}
But it returns "FT_GetBitMode FAILED!" instead value of BitMode
FT_GetBitMode returns the instantaneous value of the pins. A single byte will be
returned containing the current values of the pins, both those which are inputs and
those which are outputs.
Source.
Finally I found out whats going wrong. I used incorrect version of ftdi library. The correct version dedicated for x86_64 platform is located here:
Link to FTDI library
Can someone help me here to understand about arduino library variable name like what is tempTC, tempCJC, faultOpen, faultShortGND, faultShortVCC,
I am so confused. please help here ! thanks
/*
read_MAX31855.ino
TODO:
Clean up code and comment!!
Also make use of all library functions and make more robust.
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
http://creativecommons.org/licenses/by-sa/3.0/
*/
#include <MAX31855.h>
// Adruino 1.0 pre-defines these variables
#if ARDUINO < 100
int SCK = 13;
int MISO = 12;
int SS = 10;
#endif
int LED = 9;
// Setup the variables we are going to use.
double tempTC, tempCJC;
bool faultOpen, faultShortGND, faultShortVCC, x;
bool temp_unit = 1; // 0 = Celsius, 1 = Fahrenheit
// Init the MAX31855 library for the chip.
MAX31855 temp(SCK, SS, MISO);
void setup() {
Serial.begin(9600);
pinMode(LED, OUTPUT);
}
void loop() {
x = temp.readMAX31855(&tempTC, &tempCJC, &faultOpen, &faultShortGND, &faultShortVCC, temp_unit);
Serial.print(tempTC);
Serial.print("\t");
Serial.print(tempCJC);
Serial.print("\t");
Serial.print(faultOpen);
Serial.print(faultShortGND);
Serial.println(faultShortVCC);
digitalWrite(LED, HIGH);
delay(500);
digitalWrite(LED, LOW);
delay(500);
}
tempTC: The thermocouple value read from the IC.
tempCJC: The Cold Junction-Compensated temperature value.
faultOpen faultShortGND faultShortVCC: Flags that indicate wether any of these faults occurred while reading the temperature.
All these are done directly in the MAX31855 IC, read via SPI with the library you posted.
Trying to get an ATmega162 USART up and running. This code does exactly what I expect it to:
#define F_CPU 14745600UL
#define UBRR_1 F_CPU / 16 / 9600 - 1
#define UBRR_2 F_CPU / 16 / 31250 - 1
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
int main(){
uint16_t ubrr1 = UBRR_1;
UBRR0H = (uint8_t)(ubrr1 >> 8);
UBRR0L = (uint8_t)ubrr1;
UCSR0B = _BV(TXEN0);
UCSR0C = _BV(URSEL0) | _BV(UCSZ00) | _BV(UCSZ01);
uint16_t ubrr2 = UBRR_2;
UBRR1H = (uint8_t)(ubrr2 >> 8);
UBRR1L = (uint8_t)ubrr2;
UCSR1B = _BV(RXEN1);
UCSR1C = _BV(URSEL1) | _BV(UCSZ10) | _BV(UCSZ11);
DDRB = _BV(PB0) | _BV(PB1);
PORTB |= _BV(PB0);
while (1){
PORTB ^= _BV(PB0);
_delay_ms(50);
// byte received on usart 1
if ((UCSR1A & _BV(RXC1)) != 0){
// usart 0 ready to write
if ((UCSR0A & _BV(UDRE0)) != 0){
uint8_t b = UDR1;
UDR0 = b;
}
}
}
return 0;
}
That is, initializes the two USARTs at different baud rates, reads from USART1 and writes to USART0. Works great. Yes, I know that _delay_ms() is messing with the timing, but it works fine for this example. Now, as soon as I enable the RX interrupt on USART1 and add the appropriate vector, the main loop stops running (the LED isn't blinking, at least):
#define F_CPU 14745600UL
#define UBRR_1 F_CPU / 16 / 9600 - 1
#define UBRR_2 F_CPU / 16 / 31250 - 1
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/delay.h>
int main(){
uint16_t ubrr1 = UBRR_1;
UBRR0H = (uint8_t)(ubrr1 >> 8);
UBRR0L = (uint8_t)ubrr1;
UCSR0B = _BV(TXEN0);
UCSR0C = _BV(URSEL0) | _BV(UCSZ00) | _BV(UCSZ01);
uint16_t ubrr2 = UBRR_2;
UBRR1H = (uint8_t)(ubrr2 >> 8);
UBRR1L = (uint8_t)ubrr2;
UCSR1B = _BV(RXEN1);
UCSR1C = _BV(URSEL1) | _BV(UCSZ10) | _BV(UCSZ11);
DDRB = _BV(PB0) | _BV(PB1);
// enable usart1 rx interrupt
UCSR1B |= _BV(RXCIE1);
PORTB |= _BV(PB0);
// enable interrupts
sei();
while (1){
PORTB ^= _BV(PB0);
_delay_ms(50);
}
return 0;
}
ISR(USART1_RXC_vect){
uint8_t byte = UDR1;
if ((UCSR0A & _BV(UDRE0)) != 0){
UDR0 = byte;
}
}
The weirdest part is that it's not the sei(); and UCSR1B |= _BV(RXCIE1); lines that make the program stop working -- it's the existence of the ISR. As soon as I comment out that function, the main loop executes normally. Did I miss a flag somewhere?
It's possible this has been caused by the M161C fuse bit (in the extended fuse byte) becoming programmed. This puts the ATmega162 into ATmega161 compatibility mode which causes the device to have a different layout of the interrupt vector table (which the compiler won't know about.) See enter link description here Page 57 for the details. You could test this by compiling with -mmcu=atmega161 and seeing if it fixes the problem.
The other thing which would cause similar behaviour is if this code is run on an (almost identical-looking) ATmega16 instead of an ATmega162 as the UDR1 register is in a different place in the IO register map, meaning that the RXC interrupt flag would never get cleared and the handler would re-enter forever. You can check the register values the compiler is using by disassembling with avr-objdump.
I have to interface my GSM module with the AM1808 based on ARM9.
I have assigned all the GPIO pins to the Da850.c as well as mux.h files. I successfully created a uImage and inserted that image in my flash.
I need to handle some of that GPIO from User application.
I know that we can handle the GPIO from the Kerel space but i need to handle from the user space.
As for example I have assigned a GPIO for power key to GSM module. I need to change the pin means (HIGH or LOW) through application.
Ok i have written a following code to access it from the User Space,
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include "GSMpwr.h"
#define BS_GSM_PWR_REGISTER 0x01E26014
#define BS_DCDS_MASK 0x00000004
int fd; // Memory device descriptor
unsigned long *pPWR;
unsigned short GetGSMpwr(void)
{
#if defined __HOST_ARM
unsigned long dcd_value = *pPWR;
return (pwr_value >> 7) & 0x01;
#endif
}
void InitializeGSMpwr(void)
{
#if defined __HOST_ARM
int page_size = getpagesize();
unsigned int MAP_addr;
unsigned int reg_addr;
unsigned char *pTemp; // Pointer to GSMpwr register
/*
* Open memory and get pointer to GSMpwr register in the FPGA
*/
if((fd = open("/dev/mem", O_RDWR | O_SYNC)) < 0)
{
printf("failed to open /dev/mem");
return;
}
else
{
MAP_addr = (BS_GSM_PWR_REGISTER & ~(page_size - 1));
pTemp = (unsigned char *)mmap(NULL, page_size,(PROT_READ | PROT_WRITE),MAP_SHARED,fd,MAP_addr);
if((pTemp == MAP_FAILED) || (pTemp == NULL))
{
printf("failed to map /dev/mem");
return;
}
else
{
printf(“Memory Mapped at Address %p. \n”,pTemp);
}
virt_addr = map_base + (control & MAP_MASK);
reg_addr = (BS_GSM_PWR_REGISTER & (page_size - 1));
pPWR = (unsigned long*)(pTemp + reg_addr);
printf("GSM PWR PIN mapped in Application\n");
}
I can only read that pin through this code, Now i want to use that pin as an output and want to go high and low with the time interval of 3sec.
The easiest way is to utilize GPIO support in sysfs, where you could control all the exported GPIO's. Please have a look at the Linux kernel GPIO documentation, in particular, Sysfs Interface for Userspace part.
After you have enabled GPIO support in sysfs (GPIO_SYSFS), the GPIO control would be as easy as:
Example
GPIO=22
cd /sys/class/gpio
ls
echo $GPIO > /sys/class/gpio/export
ls
Notice on the first ls that gpio22 doesn't exist, but does after you export GPIO 22 to user space.
cd /sys/class/gpio/gpio$GPIO
ls
There are files to set the direction and retrieve the current value.
echo "in" > direction
cat value
You can configure the GPIO for output and set the value as well.
echo "out" > direction
echo 1 > value
Example is taken from here.
I got it please find following code for that,I got the Specific pin address and i have accessed that pin like,
unsigned short GetGSMpwr(void)
{
unsigned long pwr_value = *pPWR;
printf("GSM_PWR:check Start : %ld",pwr_value);
return (pwr_value >> 1) & 0x01;
}
unsigned short SetGSMpwr(void)
{
unsigned long pwr_value = *pPWR;
printf("GSM_PWR:check Start : %ld",pwr_value);
*pPWR = ~((pwr_value >> 1) & 0x01);
}
unsigned short ClrGSMpwr(void)
{
unsigned long pwr_value = *pPWR;
printf("GSM_PWR:check Start : %ld",pwr_value);
*pPWR = 256;
}`