BikeAngel is an antitheft device aimed to reduce the possibility of a bike being lost and never found again.
I am a member of the team developing BikeAngel. My implications are for the development of the device itself (the hardware) and part of the embedded software.
The project can be found here:
https://www.kickstarter.com/projects/bike-angel/bike-angel
It's difference from the rest of the devices that have similar specifications is the fact that it is placed inside the frame of the bicycle and it is not visible and it is very hard to access.
The device consists of a GSM module, a GPS module. The positioning is determined from the GSM cell and the GPS position and the GPS coordinates are transmitted through GSM or GPRS.
Some say that, being inside the bicycle frame means that it is shielded - it's not. Try putting you phone in the microwave oven(with the oven turned off , don't start it...you can even let it unplugged) and call it(don't turn on the oven).
The phone will ring without a problem.
Put your phone inside a metal case(a STR8 parfume metal casing). It will still work. Shielding depends on materials, thickness, and other stuff, it's not so easy to understand.
And remember, there is an opening on the top.
The device will have an autonomy of 30 days and it will have rechargeable batteries.
I hope I raised your interest for this device. I am opened for suggestions and questions.
Wednesday, 25 March 2015
Wednesday, 12 June 2013
PWM Configuration for ATMEGA16
In previous articles we have talked about digital reading, digital writing, now let's learn how to use the timers to generate PWM.
Atmega16 has three timers called Timer0(8 bit), Timer1(16 bit), Timer2(8 bit).
If a timer is an 8bit timer, it can count up to 2^8-1 = 255. If it is a 16 bit timer, it can count up to 2^16-1 = 65535.
Timers have some registers that can be used.
The first one is the Timer/Counter Configuration Register (TCCR0). This register is used to configure the timer, what we want the timer to do, what function to be executed. We said that the timer counts up or down. The number that is increased or decreased will be found in TCNT0 register(8 bit register), so it can be between 0 and 255.
Now, it counts up or down, but the timer can do something like put a pin on "1" or "0" if the timer reaches a limit. This limit is set in the Output Compare Register(OCR0).
TCNT0 is compared with OCR0. On compare match it can generate an interrupt or it can generate a signal to the outside world.
The timer starts counting up, TCNT0 increases. Until TCNT0 doesn't reach the value in OCR0, the output ping OC0 is set to "1". When TCNT0 is greater than OCR0 , OC0 is set to "0". TCNT0 continues to count up until it reaches the maximum limit of 255, after that it goes back to 0 (cleared) and OC0 is set back to "1".
So that why the frequency between the rising edges of OC0 is (fTimer / 2^8)
Now, we have to set the frequency.
The timer executes when a clock edge appears. The clock is the one that is used for the uC. So , for example is you have a 16MHz clock, this signal will be used as a clock for the timer. However, if you want, you can use this value divided by 8, 64, 256, or 1024 or you can even use an external clock source. The divider is called prescaler. You can select the clock that is used for the timer by setting CS00 CS01 CS02 bits.
The frequency of your PWM signal will be equal to (CLK freq/(N*256)) where N is the clock divider. 256 is 2^8.
CLKfreq/N is fTimer from the explanation of FastPWM.
- What is PWM? For simplicity, let's say it's a square signal with a given frequency and a given duty cycle. For more details refer to this pwm explanation.
- To generate PWM , we will use the timer.
Atmega16 has three timers called Timer0(8 bit), Timer1(16 bit), Timer2(8 bit).
If a timer is an 8bit timer, it can count up to 2^8-1 = 255. If it is a 16 bit timer, it can count up to 2^16-1 = 65535.
- For this tutorial we will study Timer0. Timer1 and 2 are configured in the same way.
Timers have some registers that can be used.
The first one is the Timer/Counter Configuration Register (TCCR0). This register is used to configure the timer, what we want the timer to do, what function to be executed. We said that the timer counts up or down. The number that is increased or decreased will be found in TCNT0 register(8 bit register), so it can be between 0 and 255.
Now, it counts up or down, but the timer can do something like put a pin on "1" or "0" if the timer reaches a limit. This limit is set in the Output Compare Register(OCR0).
TCNT0 is compared with OCR0. On compare match it can generate an interrupt or it can generate a signal to the outside world.
- Let's have a look in the datasheet at page 83, at Waveform Generation Mode Bit Description Table 38. We can see that for FastPWM we have to set WGM01 and WGM00 to "1". Now let's have a look at Table 40 Compare Output Mode, Fast PWM Mode and choose from there the third option(non-inverting mode). So, we have to set COM01 to "1". Until now we have configured what function the timer has to execute(non inverting fast PWM).
- FastPWM non-inverting works something like this(simple explanation).
The timer starts counting up, TCNT0 increases. Until TCNT0 doesn't reach the value in OCR0, the output ping OC0 is set to "1". When TCNT0 is greater than OCR0 , OC0 is set to "0". TCNT0 continues to count up until it reaches the maximum limit of 255, after that it goes back to 0 (cleared) and OC0 is set back to "1".
So that why the frequency between the rising edges of OC0 is (fTimer / 2^8)
Now, we have to set the frequency.
The timer executes when a clock edge appears. The clock is the one that is used for the uC. So , for example is you have a 16MHz clock, this signal will be used as a clock for the timer. However, if you want, you can use this value divided by 8, 64, 256, or 1024 or you can even use an external clock source. The divider is called prescaler. You can select the clock that is used for the timer by setting CS00 CS01 CS02 bits.
The frequency of your PWM signal will be equal to (CLK freq/(N*256)) where N is the clock divider. 256 is 2^8.
CLKfreq/N is fTimer from the explanation of FastPWM.
- Having set the mode of operation and the frequency, all that remains is to set the duty cycle. The duty cycle can be set by writing the OCR0 register. The duty cycle will be OCR0value/255.
- Also, OC0 is set as OUTPUT, so let us set the correct value in the Data Direction Register . OC0 is PB3
#include <avr/io.h>#include <avr/interrupt.h>#define F_CPU 16000000#include <util/delay.h>int main(){ TCCR0 |= (1 << WGM00) | (1 << COM01) | (1 << WGM01) | (1 << CS00); /*Configure the timer for FastPWM at frequency of f =~ 62.5kHz with no prescaling */ DDRB|=( 1 << PB3 );//set OC0 as output. OCR0 = 200;//set the duty cycle(200/255) while(1); return 0;}Usage:- Modifying the speed of a motor- Controlling the luminosity of an LED or other element- Controlling the average voltage- Controlling servo-motors-Other things :) Friday, 15 February 2013
ATMEGA16 Tutorial: Digital Write, Digital Read
Basics for programming an ATMEGA16
1. Digital Write.
When you want to program a uC, you always start from it's datasheet.
http://www.atmel.com/Images/doc2466.pdf
You can see in the datasheet that this uC has 4 8 bit PORTS: PORT A, PORT B, PORT C, PORT D.
Each port can be controlled using 3 registers. PORT, PIN and DDR
You can read in the datasheet at page 51 all the details in the chapter Configuring the Pin.
To summarise:
DDR means Data Direction Register, so using this register we can set if one pin of a port is being used for input or for output.
In the datasheet we can read the following If DDxn is written logic one, Pxn is configured as an output pin. If DDxn is written logic zero, Pxn is configured as an input pin.
Using the PORT register we write to that port, using the PIN register we read from the port.
Case 1:our port is set as output(all 8 pins are output)
We write to one pin from that port the logic value one
Result: On that pin we will have aprox 5V.
We write to one pin from that port the logic value 0
Result: On that pin we will have aprox 0V
Everything seems logic....
Case 2:
our port is set as input
We write to one pin set as input the logic value 1
Result: an internal pull-up resistor is activate.
We write to one pin set as input the logic value 0
Result: the internall pull-up resistor is deactivated
What is a pull-up resistor: http://en.wikipedia.org/wiki/Pull-up_resistor
Basically, it is used to pull the pin to VCC when nothing is wired to it. Nothing does not mean 0 logic or 1 logic, so to avoid hazard(noise signal that influences the pin) we pull it to VCC and we know that when nothing is wired, we will have a logic 1.
Now, let's do a digita write on one pin of PORTA for example.
As we can see in the datasheet, PORTA consists of 0 bits (PA7, PA6, ...,PA0).
Let's say we want to write a logic value of 1 to PA6.
PA7, PA5....PA0 will remain unchanged(input or output)
We have to set PA6 as output and write to it.
First, set PA6 as output. We have to make the 7'th bit of DDRA 1, without modifying the rest of the bits.
We know that x | 0 equals x and x | 1 equals 1.
DDRA = DDRA | (1 << PA6 );
1 << PA6 means 1 shifted to the felft with PA6 positions. PA6 is defined in a library as 6.
1 << 0 means 00000001
1 << 1 means 00000010
and 1 << PA6 means 01000000 (what we want)
We make a logic or on bits between DDRA and (1 << PA6). All the bits beside PA6 remain unchanged, and PA6 will become 1 .
Now, we have to write the logic value of 1 to PA6
Using the same technique:
PORTA = PORTA | (1 << PA6);
If we want to write a logic 0 to PORTA and leave the other bits beside PA6 unchanged, we have to use the function & (and)
x & 1 equals x
x & 0 equals 0. So we have to make a logic and between PORTA and 0 placed at the PA6'th position. Besides that 0, the other bits have to be 1.
1 << PA6 is 01000000
Not changes a logic value: NOT 1 equals 0
NOT 0 equals 1.
~ is a NOT operator that makes NOT on every bit of the register.
~(1 << PA6) equals 10111111 (exactly what we want)
PORTA = PORTA & (~ (1 << PA6 ));
In C programming language if you have an expression like:
OPERATOR1 = OPERATOR1 operand OPERATOR2
you can write it as:
OPERATOR1 operand = OPERATOR2
For example
a = a + b; <=> a + = b;
a = a | b <=> a | = b;
a = a & b <=> a & = b;
PORTA = PORTA | (1 << PA6) is the same as PORTA | = (1 << PA6) ;
Another important thing, when using Atmel libraries you have the macro BIT VALUE :
_BV(PA6) is equal to (1 << PA6 ) , so instead of writing the whole (1 << PA6 ) you can write _BV(PA6) and it's the same thing.
PORTA | = (1 << PA6 ); is the same as PORTA | = _BV(PA6);
So, a complete program to write to a pin of a port will be:
This simple program will make PA6 go to 5V, stay 1 second , then go to 0V and stay 1 sec.
2. Digital READ
For digital read we will read pin PD6. If PD6 is HIGH (logical value 1), we will make PA6 go to 5V.
Else, PA6 will be LOW(0V aka logical value 0)
We have to set PD6 to be input, so we have to make the 7'th bit in DDRD 0.
(as we did in the previous case , we will use AND function)
DDRD & = ~ (1 << PD6 ) ; // The PD6th bit will be 0, so it will be an input.
Let's suppose that on PD6 we have connected a button that pul PD6 to GND. We have to activate, for a correct reading of the pin, the internal pull-up resistor.
PORTD | = (1 << PD6 );// we activate the internal pull-up resistor on PD6.
The value of the pin is determined in the following method:
we know that x & 1 equals x, and x & 0 equals 0. We want to tell if PD6 is 1, we don't care about the rest.
PIND & ( 1 << PD6) gives us exactly the value of PD6 - or it's 1("HIGH") , or 0 ( "LOW"). Put this into an if, and voila:
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
int main()
{
/* PORT D pins are set as output */
DDRD & = ~ (1 << PD6 ) ; // The PD6th bit will be 0, so it will be an input.
while(1)
{
if((PIND & (1 << PD6))) // if PD6 is "HIGH"
{
PORTA |= ( 1 << PA6 ); // PA6 goes HIGH
}
else
PORTA & = ~ (1 << PA6 ); //PA6 goes LOW
}
return 0;
}
If you have questions, please comment below
1. Digital Write.
When you want to program a uC, you always start from it's datasheet.
http://www.atmel.com/Images/doc2466.pdf
You can see in the datasheet that this uC has 4 8 bit PORTS: PORT A, PORT B, PORT C, PORT D.
Each port can be controlled using 3 registers. PORT, PIN and DDR
You can read in the datasheet at page 51 all the details in the chapter Configuring the Pin.
To summarise:
DDR means Data Direction Register, so using this register we can set if one pin of a port is being used for input or for output.
In the datasheet we can read the following If DDxn is written logic one, Pxn is configured as an output pin. If DDxn is written logic zero, Pxn is configured as an input pin.
Using the PORT register we write to that port, using the PIN register we read from the port.
Case 1:our port is set as output(all 8 pins are output)
We write to one pin from that port the logic value one
Result: On that pin we will have aprox 5V.
We write to one pin from that port the logic value 0
Result: On that pin we will have aprox 0V
Everything seems logic....
Case 2:
our port is set as input
We write to one pin set as input the logic value 1
Result: an internal pull-up resistor is activate.
We write to one pin set as input the logic value 0
Result: the internall pull-up resistor is deactivated
What is a pull-up resistor: http://en.wikipedia.org/wiki/Pull-up_resistor
Basically, it is used to pull the pin to VCC when nothing is wired to it. Nothing does not mean 0 logic or 1 logic, so to avoid hazard(noise signal that influences the pin) we pull it to VCC and we know that when nothing is wired, we will have a logic 1.
Now, let's do a digita write on one pin of PORTA for example.
As we can see in the datasheet, PORTA consists of 0 bits (PA7, PA6, ...,PA0).
Let's say we want to write a logic value of 1 to PA6.
PA7, PA5....PA0 will remain unchanged(input or output)
We have to set PA6 as output and write to it.
First, set PA6 as output. We have to make the 7'th bit of DDRA 1, without modifying the rest of the bits.
We know that x | 0 equals x and x | 1 equals 1.
DDRA = DDRA | (1 << PA6 );
1 << PA6 means 1 shifted to the felft with PA6 positions. PA6 is defined in a library as 6.
1 << 0 means 00000001
1 << 1 means 00000010
and 1 << PA6 means 01000000 (what we want)
We make a logic or on bits between DDRA and (1 << PA6). All the bits beside PA6 remain unchanged, and PA6 will become 1 .
Now, we have to write the logic value of 1 to PA6
Using the same technique:
PORTA = PORTA | (1 << PA6);
If we want to write a logic 0 to PORTA and leave the other bits beside PA6 unchanged, we have to use the function & (and)
x & 1 equals x
x & 0 equals 0. So we have to make a logic and between PORTA and 0 placed at the PA6'th position. Besides that 0, the other bits have to be 1.
1 << PA6 is 01000000
Not changes a logic value: NOT 1 equals 0
NOT 0 equals 1.
~ is a NOT operator that makes NOT on every bit of the register.
~(1 << PA6) equals 10111111 (exactly what we want)
PORTA = PORTA & (~ (1 << PA6 ));
In C programming language if you have an expression like:
OPERATOR1 = OPERATOR1 operand OPERATOR2
you can write it as:
OPERATOR1 operand = OPERATOR2
For example
a = a + b; <=> a + = b;
a = a | b <=> a | = b;
a = a & b <=> a & = b;
PORTA = PORTA | (1 << PA6) is the same as PORTA | = (1 << PA6) ;
Another important thing, when using Atmel libraries you have the macro BIT VALUE :
_BV(PA6) is equal to (1 << PA6 ) , so instead of writing the whole (1 << PA6 ) you can write _BV(PA6) and it's the same thing.
PORTA | = (1 << PA6 ); is the same as PORTA | = _BV(PA6);
So, a complete program to write to a pin of a port will be:
#include <avr/io.h>
#define F_CPU 16000000//the cpu is running at 16MHZ)
#include <util/delay.h>
int main() //this is the main function that is being executed when the program starts
{
while(1)//the program runs continous
{
DDRA | = ( 1 << PA6 ); //set PA6 as output
PORTA | = (1 << PA6); //set PA6 on logic value 1
_delay_ms(1000);//we wait for 1 second
PORTA & = ~ (1 << PA6 ); //set PA6 on logic value 0
_delay_ms(1000);
}
return 0;
}
This simple program will make PA6 go to 5V, stay 1 second , then go to 0V and stay 1 sec.
2. Digital READ
For digital read we will read pin PD6. If PD6 is HIGH (logical value 1), we will make PA6 go to 5V.
Else, PA6 will be LOW(0V aka logical value 0)
We have to set PD6 to be input, so we have to make the 7'th bit in DDRD 0.
(as we did in the previous case , we will use AND function)
DDRD & = ~ (1 << PD6 ) ; // The PD6th bit will be 0, so it will be an input.
Let's suppose that on PD6 we have connected a button that pul PD6 to GND. We have to activate, for a correct reading of the pin, the internal pull-up resistor.
PORTD | = (1 << PD6 );// we activate the internal pull-up resistor on PD6.
The value of the pin is determined in the following method:
we know that x & 1 equals x, and x & 0 equals 0. We want to tell if PD6 is 1, we don't care about the rest.
PIND & ( 1 << PD6) gives us exactly the value of PD6 - or it's 1("HIGH") , or 0 ( "LOW"). Put this into an if, and voila:
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
int main()
{
/* PORT D pins are set as output */
DDRD & = ~ (1 << PD6 ) ; // The PD6th bit will be 0, so it will be an input.
PORTD | = (1 << PD6 );// we activate the internal pull-up resistor on PD6.
DDRA | = ( 1 << PA6 ); //set PA6 as output
{
if((PIND & (1 << PD6))) // if PD6 is "HIGH"
{
PORTA |= ( 1 << PA6 ); // PA6 goes HIGH
}
else
PORTA & = ~ (1 << PA6 ); //PA6 goes LOW
}
return 0;
}
If you have questions, please comment below
Varying bulb luminosity using ATMEGA16
GENERAL DESCRIPTION
! THE FOLLOWING APPLICATIONS IS DIRECTLY CONNECTED TO 230V POWER LINE. BE CAREFULL.
! ELECTROCUTION IS POTENTIALY DEADLY.
We know that on the market there are plenty of devices that replace normal wall switches and let you adjust the luminosity of a bulb. But if you want to make an "intelligent" home or a more complicated device to adjust the power of a light bulb what possibilities do you have?1. If you are using DC , than it's simple: just use a switching element ( a BJT or a MOSFET ). You just apply PWM (Pulse Width Modulation) and vary the duty cycle from 0% to 99% and you can adjust the luminosity of a lightbulb or LED or you can set the speed of a motor.
2. If you are using AC .... well you can do the following:
2.a. Use a rectifier to obtain DC from AC, filter it and apply what was written at 1.
2.b.1 Use "something" to turn on and off AC.
If I would use a BJT to implement my application, I would have to consider that in the reverse active region the behavior is different from the forward active region.
Because the application will be used at 50Hz(low frequency) to "drive" a light bulb (small load), and the maximum necessary current that will pass through it will be under 4 - 5 Amps, I have chosen to use a TRIAC. The same application can be easily modified(add some diodes) and can be used to drive high power loads(motors, heating elements, etc) using Thyristors.
In this article, to keep it simple and effective, I will present how to fire a TRIAC using an ATMEGA16.
SCHEMATIC
The following schematics will be used:SCHEMATIC EXPLAINED
We can see that the schematics consists of 6 blocks.1. Separation block(transformer)
2. Rectifier block
3. Voltage source block
4. 0 crossing detector block
5. Triac block
6. Computational block
1. The galvanic separation is used for safety. The transformer takes the 230V AC from the mains and gives on the output a voltage between 8 to 24V(which is safe tot touch).
This block can be replaced with a group of resistors, capacitors, diodes. IT IS DANGEROUS TO HAVE THE MAINS GO DIRECTLY TO THE MICROCONTROLLER.
2. Use the voltage from the secondary winding of the transformer to power up the uC, and also to detect de 0 crossings of the mains. To power up the uC we need DC, so we take the AC from the transformer and after rectifying(which include a bridge rectifier and a capacitor for filtering) block we obtain DC voltage
3. The uC uses 5V. We take the DC obtained at 2, use it as an input for the 7805 integrated circuit. At the output of the 7805 we will obtain 5V stabilized. We will use this voltage to power up the uC.
4. Zero crossing detector - it's just an opto-coupler. Internally, a diode lights up and turns on or off a photo-transistor which pulls the output to GND. When the transistor is turned off , the output is pulled to VCC by the pull-up resistor.
5. When the output of the uC is HIGH, transistor Q0 is in saturation and the diode inside the opto-triac is lighten and the BT136 TRIAC is fired (it conducts current from A1 to A2).
6. The computational block consists of an ATMEGA16 uC used to run a small program. We use the external interrupt pin INT1 (PD3) and an output(PD7).
CODE
#include <avr/io.h>
#define F_CPU 16000000
#include <util/delay.h>
#include<avr/interrupt.h>
ISR ( INT1_vect
)
{
_delay_ms( 1 );
TCCR1B |= ( 1 <<
CS11 );
}
ISR( TIMER1_COMPA_vect
)
{
PORTD |= ( 1 << PD7 ) ;
TCCR1B &= ~
( 1 << CS11 ) ;
TCNT1 = 0 ;
TCCR0 |= ( 1 <<
CS01 );
}
ISR( TIMER0_COMP_vect
)
{
PORTD &= ~ (
1 << PD7 ) ;
TCCR0 &= ~ (
1 << CS01 ) ;
TCNT0 = 0 ;
}
int main()
{
DDRD = ( 1 <<
7 ) ;
PORTD |= ( 1 <<
PD7 ) | ( 1 << PD3 ) ;
MCUCR |= ( 1 << ISC10 ) ;
GICR |= ( 1 <<
INT1 ) ;
TCCR1B = 0x00;
TCCR1A = 0x00;
TCCR1B |= ( 1 <<
WGM12 ) ;
TIMSK |= ( 1 <<
OCIE1A ) ;
OCR1A = 0X09FF;
TCCR0 = 0x00;
TCCR0 |= ( 1<<WGM01
) ;
TIMSK |= ( 1 <<
OCIE0 ) ;
OCR0 = 0XFF;
sei();
while(1);
return 0;
}
CODE EXPLAINED
ISR- means interrupt service request. It is a function that it's called when an interrupt occurs.
TIMER - internal structure of the microcontroller that counts. In our case the timer works in CTC "Clear Timer on Compare" mode. When TCNT(timer register that is incremented with every tick) is equal to OCR an interrupt is generated.
1 << X means 1 shifted to left with X bits
example: 1<<0 means 00000001
and 1<<7 means 10000000
In the main function we make the initialisation for the code to work(initialise the timers, set the interrupts and then wait for something to happen).
When Timer 1 generates an interrupt(it has finished counting), PD3 pin is set to TRUE(5V) and the trigger signal is sent to the opto-triac which fires the triac that powers on the load (light bulb). Timer 1 is turned off and timer 0 starts counting.
When Timer 0 generates an interrupt(it has finished counting), it means the trigger signal must end , PD3 is set to FALSE(0V) and timer 0 stops counting.
The program will be enhanced in the future to receive the data from USART or ADC and to be set dynamically using an algorithm. Right now, everything is static. This is just a Proof Of Concept.
PCB - it's easy to design, I had no design, just used one board with ATMEGA16 and components soldered in air to it.
Results:
Trigger signal after 0 crossing with delay:
Trigger signal and signal on the load:
Bulb at low luminosity and signal with trigger for that:
TO BE MENTIONED:
If you want to drive a motor instead of a light bulb, no problem, but you have to use a snubber circuit to protect the TRIAC from damaging because of the inductive load or from auto-triggering.
Also, it's good practice to make the length of the signal until the sinus reaches 0, but it is a little tricky(it is not included in the code). You have to adjust timer 1 for that.
The same stuff can be done with ARDUINO, which uses Atmel microcontrollers and the code can be written in the same stile or using ARDUINO IDE ( I prefer using the presented style, and defenetly not Arduino IDE).
THIS IS MY INTELLECTUAL PROPERTY, if you want to borrow photos or information please ask first.
Article about thyristor: http://en.wikipedia.org/wiki/Thyristor
Article about the TRIAC: http://en.wikipedia.org/wiki/TRIAC
ATMEGA16 Datasheet: http://www.atmel.com/Images/doc2466.pdf
Hope you like it and it's useful.
If you have something to say (feedback - negative or positive , don't hesitate to post it).
Saturday, 24 November 2012
What things I don't like in Windows - part 1
This is just a little story about what happened to me today, not a technical debate on Linux vs Windows.
Today I had to run a program that needed to read and load a .bin file from a path. In the configuration file, I have specified a simple path C:\x.bin. I have copied the image at the specified path and tried to run the program. The message was that the file x.bin was not there. I have re-installed the program, restarted my computer and still, I had the same problem.
Sick of trying to run this program, I booted up Linux Mint(the OS that I usually use). I was navigating through the files and by mistake I saw that in C: I had a file named x.bin.zip . I rebooted my computer in Windows , unzipped the archive, and tried to run the program that required x.bin . Still, I had an error. Looking up carefully, I saw that x.bin was a folder and inside it was the real x.bin file. When I've tried to copy the file x.bin out of that folder I've got the error that the file that I try to copy had the same name with the folder. I solved that by moving the folder in D: and copy the file back in C:.
I don't like that, by default, Windows hides known file extensions. Usually, when I work in Linux and I need to do something, I work in the console. And there, when I try to see the files in a folder, I use the command ls or ls -lh. All the extensions are obvious, and also, I can see if it's a file or a folder.
In conclusion, I prefer using Linux Mint. When I need to run windows programs, I try to run them in Wine or to run them in a Virtual Machine with Windows instead of running Windows OS.
Today I had to run a program that needed to read and load a .bin file from a path. In the configuration file, I have specified a simple path C:\x.bin. I have copied the image at the specified path and tried to run the program. The message was that the file x.bin was not there. I have re-installed the program, restarted my computer and still, I had the same problem.
Sick of trying to run this program, I booted up Linux Mint(the OS that I usually use). I was navigating through the files and by mistake I saw that in C: I had a file named x.bin.zip . I rebooted my computer in Windows , unzipped the archive, and tried to run the program that required x.bin . Still, I had an error. Looking up carefully, I saw that x.bin was a folder and inside it was the real x.bin file. When I've tried to copy the file x.bin out of that folder I've got the error that the file that I try to copy had the same name with the folder. I solved that by moving the folder in D: and copy the file back in C:.
I don't like that, by default, Windows hides known file extensions. Usually, when I work in Linux and I need to do something, I work in the console. And there, when I try to see the files in a folder, I use the command ls or ls -lh. All the extensions are obvious, and also, I can see if it's a file or a folder.
In conclusion, I prefer using Linux Mint. When I need to run windows programs, I try to run them in Wine or to run them in a Virtual Machine with Windows instead of running Windows OS.
Subscribe to:
Posts (Atom)







